diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/API_Gateway.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/API_Gateway.md similarity index 92% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/API_Gateway.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/API_Gateway.md index 7f27030..136f176 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/API_Gateway.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/API_Gateway.md @@ -10,7 +10,7 @@ client. In response to a client request you can then call a [lambda function](Lambda_handler_function.md) that executes a backend process. -![](/static/gateway-services.png) +![](static/gateway-services.png) See [using API Gateway as Lambda trigger](Practical_walkthrough_Lambda_creation_within_AWS.md) diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/AWS_CLI.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/AWS_CLI.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/AWS_CLI.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/AWS_CLI.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/AWS_SAM_and_Docker.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/AWS_SAM_and_Docker.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/AWS_SAM_and_Docker.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/AWS_SAM_and_Docker.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/AWS_architecture_hierarchy.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/AWS_architecture_hierarchy.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/AWS_architecture_hierarchy.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/AWS_architecture_hierarchy.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Accessing_metadata_about_SQL_database.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Accessing_metadata_about_SQL_database.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Accessing_metadata_about_SQL_database.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Accessing_metadata_about_SQL_database.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Accessing_secrets_from_a_Lambda.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Accessing_secrets_from_a_Lambda.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Accessing_secrets_from_a_Lambda.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Accessing_secrets_from_a_Lambda.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Add_Subtract_Fractions.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Add_Subtract_Fractions.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Add_Subtract_Fractions.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Add_Subtract_Fractions.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Adding_documents_to_a_Mongo_collection.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Adding_documents_to_a_Mongo_collection.md similarity index 96% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Adding_documents_to_a_Mongo_collection.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Adding_documents_to_a_Mongo_collection.md index e7cc250..72fadc4 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Adding_documents_to_a_Mongo_collection.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Adding_documents_to_a_Mongo_collection.md @@ -49,4 +49,4 @@ have the Mongo document outputted to the console: This will also be reflected in Compass: -![](/static/mongo-doc-added.png) +![](static/mongo-doc-added.png) diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Additive_identity.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Additive_identity.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Additive_identity.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Additive_identity.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Additive_inverse_property.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Additive_inverse_property.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Additive_inverse_property.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Additive_inverse_property.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Aggregate_functions_in_SQL.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Aggregate_functions_in_SQL.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Aggregate_functions_in_SQL.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Aggregate_functions_in_SQL.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Algebra_key_terms.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Algebra_key_terms.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Algebra_key_terms.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Algebra_key_terms.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Algorithmic_complexity.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Algorithmic_complexity.md similarity index 98% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Algorithmic_complexity.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Algorithmic_complexity.md index cffbf47..c9254cc 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Algorithmic_complexity.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Algorithmic_complexity.md @@ -4,7 +4,7 @@ tags: [algorithms] # Algorithmic complexity -![Screenshot_2021-05-11_at_18.55.23.png](/static/Screenshot_2021-05-11_at_18.55.23.png) +![Screenshot_2021-05-11_at_18.55.23.png](static/Screenshot_2021-05-11_at_18.55.23.png) _Summary of the main classes of algorithmic complexity_ ## Distinguish algorithms from programs @@ -119,7 +119,7 @@ following data set: | 5 | 5 | If we plotted this as a graph it is clear that this is equivalent to a linear -distribution:![lin.svg](/static/lin.svg) +distribution:![lin.svg](static/lin.svg) Algorithms which display this distribution are therefore called **linear algorithms**. @@ -242,7 +242,7 @@ factor of it. Therefore the runtime is not growing proportional to the size of the input, it is growing proportional to the size of the input squared. Graphically this is represented with a curving lines as follows: -![square.svg](/static/square.svg) +![square.svg](static/square.svg) We can clearly see that as n grows, the runtime gets steeper and more pronounced, @@ -291,7 +291,7 @@ Back to algorithms: $O(\log n)$ is a really good complexity to have. It is close to O(1) and in between O(1) and O(n). Represented graphically, it starts of with a slight increase in runtime but then quickly levels off: -![Screenshot_2021-05-11_at_18.51.02.png](/static/Screenshot_2021-05-11_at_18.51.02.png) +![Screenshot_2021-05-11_at_18.51.02.png](static/Screenshot_2021-05-11_at_18.51.02.png) Many sorting algorithms run in log n time, as does recursion. @@ -356,7 +356,7 @@ we should keep in mind the following shorthands: With this in mind we can break down the `findSum` function like so: -![breakdown.svg](/static/breakdown.svg) +![breakdown.svg](static/breakdown.svg) This gives us: diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Analogue_and_digital.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Analogue_and_digital.md similarity index 99% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Analogue_and_digital.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Analogue_and_digital.md index 528b576..1871c71 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Analogue_and_digital.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Analogue_and_digital.md @@ -7,7 +7,7 @@ tags: [analogue] Analogue and digital are paradigms for recording information, specifically information about an object or state that obtains in the world. -![](/static/analog-digital.svg) +![](static/analog-digital.svg) ## Analogue diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Any.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Any.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Any.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Any.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Apollo_Client.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Apollo_Client.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Apollo_Client.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Apollo_Client.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Apollo_Server.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Apollo_Server.md similarity index 99% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Apollo_Server.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Apollo_Server.md index f929cdf..a6cc44f 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Apollo_Server.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Apollo_Server.md @@ -73,7 +73,7 @@ When we access the local URL we are able to access the Apollo server using the Explorer GUI. This automatically loads our schema and is basically a more fancy version of GraphiQL: -![](/static/apollo-explorer.png) +![](static/apollo-explorer.png) It makes it easy to read descriptions of the dataypes and to construct queries by clicking to insert fields. diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Application_Layer_of_Internet_Protocol.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Application_Layer_of_Internet_Protocol.md similarity index 90% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Application_Layer_of_Internet_Protocol.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Application_Layer_of_Internet_Protocol.md index 2db64cc..5a971db 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Application_Layer_of_Internet_Protocol.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Application_Layer_of_Internet_Protocol.md @@ -7,7 +7,7 @@ created: Friday, September 06, 2024 The final, topmost layer of the Internet Protocol suite. -![Data at the Application Layer](/static/application-layer-data.png) +![Data at the Application Layer](static/application-layer-data.png) The Application Layer is where we get to the protocols that describe the behaviour of applications. All the preceding lower levels are effectively diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Application_state_management_with_React_hooks.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Application_state_management_with_React_hooks.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Application_state_management_with_React_hooks.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Application_state_management_with_React_hooks.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Application_structure.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Application_structure.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Application_structure.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Application_structure.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Arithmetic_Logic_Unit.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Arithmetic_Logic_Unit.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Arithmetic_Logic_Unit.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Arithmetic_Logic_Unit.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Arrays.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Arrays.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Arrays.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Arrays.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Assembly.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Assembly.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Assembly.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Assembly.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Associativity.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Associativity.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Associativity.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Associativity.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Atomic_and_molecular_propositions.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Atomic_and_molecular_propositions.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Atomic_and_molecular_propositions.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Atomic_and_molecular_propositions.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Awk.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Awk.md similarity index 99% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Awk.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Awk.md index 5b5c79d..43e6939 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Awk.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Awk.md @@ -89,7 +89,7 @@ awk '/Joe/ {print}' list.txt ### Lines, records, fields -![](/static/awk-outline.png) +![](static/awk-outline.png) When `awk` receives a file it divides the lines into **records**. diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Axioms_of_set_theory.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Axioms_of_set_theory.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Axioms_of_set_theory.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Axioms_of_set_theory.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Basic_model_of_the_operating_system.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Basic_model_of_the_operating_system.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Basic_model_of_the_operating_system.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Basic_model_of_the_operating_system.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Basic_prop_passing_in_React.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Basic_prop_passing_in_React.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Basic_prop_passing_in_React.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Basic_prop_passing_in_React.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Basic_properties_of_sets.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Basic_properties_of_sets.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Basic_properties_of_sets.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Basic_properties_of_sets.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Basics_of_web_components.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Basics_of_web_components.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Basics_of_web_components.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Basics_of_web_components.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Biconditional_Elimination.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Biconditional_Elimination.md similarity index 87% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Biconditional_Elimination.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Biconditional_Elimination.md index 0730b4f..3f002cc 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Biconditional_Elimination.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Biconditional_Elimination.md @@ -9,4 +9,4 @@ Give that the biconditional means that if $P$ is the case, $Q$ must be the case and if $Q$ is the case, $P$ must be the case, if we have $P \leftrightarrow Q$ and $P$, we can derive $Q$ and vice versa. -![](/static/biconditional-elim.png) +![](static/biconditional-elim.png) diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Biconditional_Introduction.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Biconditional_Introduction.md similarity index 92% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Biconditional_Introduction.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Biconditional_Introduction.md index 018886d..8d78495 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Biconditional_Introduction.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Biconditional_Introduction.md @@ -10,4 +10,4 @@ the case, $P$ must be the case. Thus to introduce this operator we must demonstrate both that $Q$ follows from $P$ and that $P$ follows from $Q$. We do this via two sub-proofs. -![](/static/bi-intro.png) +![](static/bi-intro.png) diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Binary_addition.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Binary_addition.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Binary_addition.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Binary_addition.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Binary_arithmetic.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Binary_arithmetic.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Binary_arithmetic.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Binary_arithmetic.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Binary_colour_encoding.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Binary_colour_encoding.md similarity index 94% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Binary_colour_encoding.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Binary_colour_encoding.md index ff32bff..5b43d87 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Binary_colour_encoding.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Binary_colour_encoding.md @@ -24,7 +24,7 @@ In decimal, 0 is equal to black (zero light intensity) and 255 is equal to white (full light intensity). Some examples of this (including binary and hex representations are below): -![](/static/greyscale-encoding.svg) +![](static/greyscale-encoding.svg) ### Colour encoding @@ -41,13 +41,13 @@ Some examples below Red is represented in RGB with all 8 red bits to set to 1 and the remaining 16 bits for the other two colours set to 0. -![](/static/red-encoding.svg) +![](static/red-encoding.svg) #### Yellow Yellow is represented in RGB with both red and blue set to 1 and the remaining 8 green bits set to ): -![](/static/yellow-encoding.svg) +![](static/yellow-encoding.svg) ## Binary encoding of images diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Binary_encoding.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Binary_encoding.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Binary_encoding.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Binary_encoding.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Binary_encoding_of_text.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Binary_encoding_of_text.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Binary_encoding_of_text.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Binary_encoding_of_text.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Binary_number_system.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Binary_number_system.md similarity index 94% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Binary_number_system.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Binary_number_system.md index 16dca1d..f8a4995 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Binary_number_system.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Binary_number_system.md @@ -97,11 +97,11 @@ equal to: **1 in the two column and 1 in the 4 column → 110** More clearly: -![](/static/Pasted_image_20220319135558.png) +![](static/Pasted_image_20220319135558.png) And for comparison: -![](/static/Pasted_image_20220319135805.png) +![](static/Pasted_image_20220319135805.png) Or we can express the binary as: @@ -115,4 +115,4 @@ $$ 2^1 + 2^2 $$ Let's convert 23 into binary: -![](/static/Pasted_image_20220319135823.png) +![](static/Pasted_image_20220319135823.png) diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Binary_units_of_measurement.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Binary_units_of_measurement.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Binary_units_of_measurement.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Binary_units_of_measurement.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Bitwise_operators.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Bitwise_operators.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Bitwise_operators.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Bitwise_operators.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Bluetooth.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Bluetooth.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Bluetooth.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Bluetooth.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Boolean_algebra.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Boolean_algebra.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Boolean_algebra.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Boolean_algebra.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Boolean_function_synthesis.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Boolean_function_synthesis.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Boolean_function_synthesis.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Boolean_function_synthesis.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Boolean_functions.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Boolean_functions.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Boolean_functions.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Boolean_functions.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Boot_process.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Boot_process.md similarity index 99% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Boot_process.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Boot_process.md index 815f51e..3b79528 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Boot_process.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Boot_process.md @@ -61,7 +61,7 @@ create your boot process so the two are clearly distinguishable. The de facto standard boot loader for Linux is GRUB: Grand Unified Boot Loader. -![](/static/grub.jpg) +![](static/grub.jpg) You see the GRUB default menu when you first start a Linux machine. It will offer you various options for loading your installed OS or other OSs. GRUB is a diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Breadboards.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Breadboards.md similarity index 95% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Breadboards.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Breadboards.md index 45dfe8b..6d64fa4 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Breadboards.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Breadboards.md @@ -6,7 +6,7 @@ created: Sunday, June 23, 2024 # Breadboards -![](/static/breadboard-diagram.jpg) +![](static/breadboard-diagram.jpg) ## Contact holes diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Built_in_React_hooks.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Built_in_React_hooks.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Built_in_React_hooks.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Built_in_React_hooks.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Bus.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Bus.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Bus.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Bus.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/CPU_architecture.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/CPU_architecture.md similarity index 98% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/CPU_architecture.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/CPU_architecture.md index 37fa398..1882d82 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/CPU_architecture.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/CPU_architecture.md @@ -19,7 +19,7 @@ The CPU comprises three core components: - the Arithmetic Logic Unit (ALU) - the Control Unit (CU) -![](/static/von_neumann_architecture.jpeg) +![](static/von_neumann_architecture.jpeg) > This method of putting together a computer is known as the **Von Neumann > Architecture**. It was devised by John von Neumann in about 1945, well before @@ -106,7 +106,7 @@ Hertz was the scientist who detected We use Hertz as a measure of the frequency of electromatic wave cycles in a signal. -![](/static/hertz_wave_freq.gif) +![](static/hertz_wave_freq.gif) As the diagram above shows, a cycle is equal to one ascending and one descending crest. The more cycles per time unit, the greater the Hertz. We see the Hz diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Call_stack.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Call_stack.md similarity index 95% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Call_stack.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Call_stack.md index 47de8ef..a61e95f 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Call_stack.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Call_stack.md @@ -34,4 +34,4 @@ console.log("Bye"); ## Related notes -![Stack memory](/static/Stack_memory.md) +![Stack memory](static/Stack_memory.md) diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Capturing_user_input_in_Bash.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Capturing_user_input_in_Bash.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Capturing_user_input_in_Bash.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Capturing_user_input_in_Bash.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Case_statements_in_Bash.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Case_statements_in_Bash.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Case_statements_in_Bash.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Case_statements_in_Bash.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Cells_and_batteries.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Cells_and_batteries.md similarity index 93% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Cells_and_batteries.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Cells_and_batteries.md index e99f91d..e249636 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Cells_and_batteries.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Cells_and_batteries.md @@ -32,7 +32,7 @@ connection types: The table below summarises the relative differences: -![](/static/cell-comparison.svg) +![](static/cell-comparison.svg) ### Series connections @@ -56,12 +56,12 @@ Thus series connections increase voltage but keep current constant. _Series battery connection:_ -![](/static/series-battery-diagram.svg) +![](static/series-battery-diagram.svg) _Can be represented in a circuit diagram in one of the following two ways: as a series of cells or as a single battery:_ -![](/static/series-battcircuit.svg) +![](static/series-battcircuit.svg) In the case of **series opposing**, negative terminals are connected to each other and positive terminals are connected to each other in a series. This @@ -86,11 +86,11 @@ $$ _Parallel battery connection:_ -![](/static/parallel-battery-diagram.svg) +![](static/parallel-battery-diagram.svg) _Parallel battery circuit diagram:_ -![](/static/circ-batt-final.svg) +![](static/circ-batt-final.svg) ### Series-parrallel diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Cherry_picking.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Cherry_picking.md similarity index 98% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Cherry_picking.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Cherry_picking.md index b04c427..06d926c 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Cherry_picking.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Cherry_picking.md @@ -40,7 +40,7 @@ This will apply the changes from the commit with hash `xyz` from thee `main` branch to the `feature` branch. This will create a new SHA on `feature` (pqr) but the changes will be identical. -![](/static/cherry-pick.svg) +![](static/cherry-pick.svg) The benefit is that you only take the select changes you want, you are not merging the whole `main` branch into feature. diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Child_to_parent_data_flow_in_React.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Child_to_parent_data_flow_in_React.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Child_to_parent_data_flow_in_React.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Child_to_parent_data_flow_in_React.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Chipset_and_controllers.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Chipset_and_controllers.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Chipset_and_controllers.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Chipset_and_controllers.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Class_inheritance_in_Python.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Class_inheritance_in_Python.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Class_inheritance_in_Python.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Class_inheritance_in_Python.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Classes.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Classes.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Classes.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Classes.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Classes_in_Python.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Classes_in_Python.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Classes_in_Python.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Classes_in_Python.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Clock_signals.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Clock_signals.md similarity index 98% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Clock_signals.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Clock_signals.md index b5f3ef2..277a5a9 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Clock_signals.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Clock_signals.md @@ -30,7 +30,7 @@ the reverse (the electrons moving from the voltage source to ground). The diagram below shows a pulse cycle of 2Hz. -![](/static/clock_pulses.png) +![](static/clock_pulses.png) ## Linking components to the clock diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/CloudWatch.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/CloudWatch.md similarity index 96% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/CloudWatch.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/CloudWatch.md index 51a4f67..06d7350 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/CloudWatch.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/CloudWatch.md @@ -39,9 +39,9 @@ their infrastructure and applications. CloudWatch can usually be accessed directly from within the dashboard for the given AWS service under the "Monitor" tab. For example with AWS Lambda: -![](/static/lambda-cloudwatch.png) +![](static/lambda-cloudwatch.png) In addition to graphical metrics, we can also view specific logs for each event and execution of the given service. In the case of a Lambda function: -![](/static/cloudwatch-logs.png) +![](static/cloudwatch-logs.png) diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Command_pattern.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Command_pattern.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Command_pattern.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Command_pattern.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Commutativity.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Commutativity.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Commutativity.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Commutativity.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Comparing_React_classes_to_hooks.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Comparing_React_classes_to_hooks.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Comparing_React_classes_to_hooks.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Comparing_React_classes_to_hooks.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Compile_Python_app_to_single_executable.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Compile_Python_app_to_single_executable.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Compile_Python_app_to_single_executable.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Compile_Python_app_to_single_executable.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Compile_from_source.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Compile_from_source.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Compile_from_source.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Compile_from_source.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Complete_Mongo_example.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Complete_Mongo_example.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Complete_Mongo_example.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Complete_Mongo_example.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Components_props_classes.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Components_props_classes.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Components_props_classes.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Components_props_classes.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Components_props_hooks_in_React.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Components_props_hooks_in_React.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Components_props_hooks_in_React.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Components_props_hooks_in_React.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Concise_subfield_mapping_JS.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Concise_subfield_mapping_JS.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Concise_subfield_mapping_JS.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Concise_subfield_mapping_JS.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Conditional_Elimination.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Conditional_Elimination.md similarity index 90% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Conditional_Elimination.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Conditional_Elimination.md index ae65b48..5ed800a 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Conditional_Elimination.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Conditional_Elimination.md @@ -10,4 +10,4 @@ If we have a conditional and we have independently derived its antecedent, we may invoke its consequent. This is often referred to as _Modus ponens_ (affirming the antecedent). -![](/static/cond-elim.png) +![](static/cond-elim.png) diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Conditional_Introduction.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Conditional_Introduction.md similarity index 89% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Conditional_Introduction.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Conditional_Introduction.md index 16977f7..ba55b5d 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Conditional_Introduction.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Conditional_Introduction.md @@ -9,4 +9,4 @@ tags: If we can show that $Q$ follows from $P$ (typically via a sub-proof) than we can assert that P implies Q. This is also sometimes known as _Conditional Proof_ -![](/static/cond-intro.png) +![](static/cond-intro.png) diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Conditional_statements_in_Python.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Conditional_statements_in_Python.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Conditional_statements_in_Python.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Conditional_statements_in_Python.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Conditionals_in_Bash.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Conditionals_in_Bash.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Conditionals_in_Bash.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Conditionals_in_Bash.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Conjunction_Elimination.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Conjunction_Elimination.md similarity index 88% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Conjunction_Elimination.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Conjunction_Elimination.md index b6a9b04..105d6c8 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Conjunction_Elimination.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Conjunction_Elimination.md @@ -9,4 +9,4 @@ tags: If a conjunction exists, it means that both conjuncts are the case; therefore we can legitimately extract either one of them. Also known as _Simplification_. -![](/static/conjunc-elim.png) +![](static/conjunc-elim.png) diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Conjunction_Introduction.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Conjunction_Introduction.md similarity index 86% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Conjunction_Introduction.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Conjunction_Introduction.md index ab1d618..828e60b 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Conjunction_Introduction.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Conjunction_Introduction.md @@ -9,4 +9,4 @@ tags: If two conjuncts have each been independently derived then they can be conjoined. Also known more simply as _Conjunction_ -![](/static/conjunc-intro.png) +![](static/conjunc-intro.png) diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Connect_to_Mongo_database.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Connect_to_Mongo_database.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Connect_to_Mongo_database.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Connect_to_Mongo_database.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Connecting_a_frontend_to_a_Docker_backend.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Connecting_a_frontend_to_a_Docker_backend.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Connecting_a_frontend_to_a_Docker_backend.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Connecting_a_frontend_to_a_Docker_backend.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Containerization.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Containerization.md similarity index 97% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Containerization.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Containerization.md index 3dc24f2..e505d64 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Containerization.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Containerization.md @@ -67,11 +67,11 @@ expenditure and security challenges. _Standard userspace_ -![](/static/standard-userspace.png) +![](static/standard-userspace.png) _Userspace with containerization_ -![](/static/containers-in-userspace.png) +![](static/containers-in-userspace.png) ## Differences with virtual machines @@ -100,7 +100,7 @@ rest as it would any other process on the OS. | Less portable | More portable | | Slower and more difficult to run | Scale rapidly due to lightweight nature | -![](/static/container-versus-vm.png) +![](static/container-versus-vm.png) ## Why use containers? diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Controlled_components_in_React.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Controlled_components_in_React.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Controlled_components_in_React.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Controlled_components_in_React.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Corresponding_material_and_biconditional.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Corresponding_material_and_biconditional.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Corresponding_material_and_biconditional.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Corresponding_material_and_biconditional.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Coulombs_Laws.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Coulombs_Laws.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Coulombs_Laws.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Coulombs_Laws.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Create_Mongo_database.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Create_Mongo_database.md similarity index 95% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Create_Mongo_database.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Create_Mongo_database.md index ca2340a..7a91a28 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Create_Mongo_database.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Create_Mongo_database.md @@ -31,4 +31,4 @@ _Compass_ is a graphical interface for viewing and interacting with the data in your Mongo database. It will automatically load to the default Mongo port: `27017`. -![](/static/mongo-compass.png) +![](static/mongo-compass.png) diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Create_an_SQL_table.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Create_an_SQL_table.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Create_an_SQL_table.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Create_an_SQL_table.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Create_timed_systemd_job.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Create_timed_systemd_job.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Create_timed_systemd_job.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Create_timed_systemd_job.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Creating_a_Docker_image.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Creating_a_Docker_image.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Creating_a_Docker_image.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Creating_a_Docker_image.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Creating_a_Linux_partition_table.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Creating_a_Linux_partition_table.md similarity index 98% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Creating_a_Linux_partition_table.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Creating_a_Linux_partition_table.md index 333ec27..d40e2ab 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Creating_a_Linux_partition_table.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Creating_a_Linux_partition_table.md @@ -149,4 +149,4 @@ sudo e2label /dev/sda1 my_human_name ## Related notes -![Linux disk partitions](/static/Linux_disk_partitions.md) +![Linux disk partitions](static/Linux_disk_partitions.md) diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Creating_a_Mongo_schema_and_model.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Creating_a_Mongo_schema_and_model.md similarity index 96% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Creating_a_Mongo_schema_and_model.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Creating_a_Mongo_schema_and_model.md index 234518b..d9df534 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Creating_a_Mongo_schema_and_model.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Creating_a_Mongo_schema_and_model.md @@ -71,11 +71,11 @@ const course = new Course({ }); ``` -![](/static/mongoose-hierarchy.svg) +![](static/mongoose-hierarchy.svg) ## Outcome Having created a database, connected to it with Mongoose, and created a model we will see our collection reflected in Compass: -![](/static/mongo-collection.png) +![](static/mongo-collection.png) diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/1_GET.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Creating_a_RESTful_API_GET.md similarity index 98% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/1_GET.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Creating_a_RESTful_API_GET.md index 4d8d9ba..5b18c9e 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/1_GET.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Creating_a_RESTful_API_GET.md @@ -22,7 +22,7 @@ router.get("/", (req, res) => { Our server is now set up: -![](/static/server-listening.png) +![](static/server-listening.png) > When creating our API this structure of creating handlers for specific routes > will be iterated. Every endpoint will be specified with diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/5__Integrating_the_Mongo_database.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Creating_a_RESTful_API_Integrating_the_Database.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/5__Integrating_the_Mongo_database.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Creating_a_RESTful_API_Integrating_the_Database.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/0_Introduction.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Creating_a_RESTful_API_Introduction.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/0_Introduction.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Creating_a_RESTful_API_Introduction.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/2_POST.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Creating_a_RESTful_API_POST.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/2_POST.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Creating_a_RESTful_API_POST.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/3_PUT.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Creating_a_RESTful_API_PUT.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/3_PUT.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Creating_a_RESTful_API_PUT.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Creating_memory_with_NAND.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Creating_memory_with_NAND.md similarity index 94% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Creating_memory_with_NAND.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Creating_memory_with_NAND.md index 976cea5..3c25e6b 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Creating_memory_with_NAND.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Creating_memory_with_NAND.md @@ -10,7 +10,7 @@ below demonstrates how memory can be created using [NAND](Logic_gates.md#nand-gate) gates. A single bit is stored in memory. -![](/static/nand_latch_logic_circuit.png) Interactive version of circuit: +![](static/nand_latch_logic_circuit.png) Interactive version of circuit: @@ -37,7 +37,7 @@ gates. A single bit is stored in memory. > Upshot: With **S** `ON`, output is the same as input -![](/static/nand-mem-first.gif) +![](static/nand-mem-first.gif) ### Second state: both S and I `ON` @@ -54,7 +54,7 @@ gates. A single bit is stored in memory. > Upshot: With **S** on, the output is again the same as the input -![](/static/nand-mem-second.gif) +![](static/nand-mem-second.gif) > So far we have seen that when **S** is `ON` you can change **I** on and off > and **O** will change with it. @@ -73,4 +73,4 @@ and at Gate 2: `OFF (Gate 1) + OFF (S) = OFF` This is illustrated in the diagram below. The space occupied by **A** and **B** remains on (note it is illuminated) regardless of the state of **I**. -![](/static/nand-mem-demonstrated.gif) +![](static/nand-mem-demonstrated.gif) diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Cron.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Cron.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Cron.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Cron.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Current.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Current.md similarity index 98% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Current.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Current.md index 6dd09c6..57cfcc4 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Current.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Current.md @@ -29,7 +29,7 @@ force the **voltage source**. _The diagram below illustrates the flow of current where the circles are electrons knocking into each other and passing current:_ -![](/static/charge-cylinder.svg) +![](static/charge-cylinder.svg) > Electrons travel very slowly through a conductor. This is in contrast to their > intrinsic motion which of course equal to the speed of light (186, 000 miles diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Custom_React_hook_examples.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Custom_React_hook_examples.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Custom_React_hook_examples.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Custom_React_hook_examples.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Custom_types_in_TypeScript.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Custom_types_in_TypeScript.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Custom_types_in_TypeScript.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Custom_types_in_TypeScript.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/DRAM_and_SRAM_memory.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/DRAM_and_SRAM_memory.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/DRAM_and_SRAM_memory.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/DRAM_and_SRAM_memory.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Daemons.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Daemons.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Daemons.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Daemons.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Data_types_in_Bash.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Data_types_in_Bash.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Data_types_in_Bash.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Data_types_in_Bash.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Data_types_in_MySQL.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Data_types_in_MySQL.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Data_types_in_MySQL.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Data_types_in_MySQL.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Database_indices.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Database_indices.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Database_indices.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Database_indices.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Database_options_on_AWS.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Database_options_on_AWS.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Database_options_on_AWS.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Database_options_on_AWS.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Dates_in_Python.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Dates_in_Python.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Dates_in_Python.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Dates_in_Python.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/DeMorgan's_Laws.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/DeMorgan's_Laws.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/DeMorgan's_Laws.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/DeMorgan's_Laws.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Defining_a_computer.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Defining_a_computer.md similarity index 94% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Defining_a_computer.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Defining_a_computer.md index 4ae808e..bd2af80 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Defining_a_computer.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Defining_a_computer.md @@ -15,7 +15,7 @@ single set of tasks according to prewritten instructions. We’ll take the term _computer_ to mean general purpose computer. Simplified model of what a computer is: -![1.4-Input-Process-Output.png](/static/1.4-Input-Process-Output.png) +![1.4-Input-Process-Output.png](static/1.4-Input-Process-Output.png) Although the input, output and storage parts of a computer are very important, they will not be the focus of this course. Instead we are going to learn all @@ -55,9 +55,9 @@ instructions to make calculations. wind, drift, slope and elevation. These were used well into WW2 but they were limited to the particular type of cannon or shell -![Screenshot_2020-08-09_at_21.32.54 1.png](/static/Screenshot_2020-08-09_at_21.32.54%201.png) +![Screenshot_2020-08-09_at_21.32.54 1.png](static/Screenshot_2020-08-09_at_21.32.54%201.png) -![Screenshot_2020-08-09_at_21.34.48.png](/static/Screenshot_2020-08-09_at_21.34.48.png) +![Screenshot_2020-08-09_at_21.34.48.png](static/Screenshot_2020-08-09_at_21.34.48.png) > Before the invention of actual computers, 'computer' was a job-title denoting > people who were employed to conduct complex calculations, sometimes with the diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Delay_line_memory.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Delay_line_memory.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Delay_line_memory.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Delay_line_memory.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Delete_a_branch.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Delete_a_branch.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Delete_a_branch.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Delete_a_branch.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Delete_records_in_an_SQL_table.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Delete_records_in_an_SQL_table.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Delete_records_in_an_SQL_table.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Delete_records_in_an_SQL_table.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Deleting_Mongo_documents.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Deleting_Mongo_documents.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Deleting_Mongo_documents.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Deleting_Mongo_documents.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Dependency_injection.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Dependency_injection.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Dependency_injection.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Dependency_injection.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Devices.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Devices.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Devices.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Devices.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Dictionaries_in_Python.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Dictionaries_in_Python.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Dictionaries_in_Python.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Dictionaries_in_Python.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Difference_between_remote_origin_and_head.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Difference_between_remote_origin_and_head.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Difference_between_remote_origin_and_head.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Difference_between_remote_origin_and_head.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Disjunction_Elimination.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Disjunction_Elimination.md similarity index 87% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Disjunction_Elimination.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Disjunction_Elimination.md index 5caaf2f..31afccd 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Disjunction_Elimination.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Disjunction_Elimination.md @@ -15,14 +15,14 @@ disjuncts comprising the disjunction you start out with. If you can derive your target proposition as the conclusion of each subproof then you may invoke the conclusion in the main proof and take it to be derived. -![](/static/disjunc-elim.png) +![](static/disjunc-elim.png) _Here is an example where Disjunction Elimination is used to derive a new disjunction._ -![](/static/proofs-drawio-Page-6.drawio.png) +![](static/proofs-drawio-Page-6.drawio.png) _Here are two further examples that use Disjunction Elimination to derive singular propositions_ -![](/static/ORelim1.png) ![](/static/ORelim2.png) +![](static/ORelim1.png) ![](static/ORelim2.png) diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Disjunction_Introduction.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Disjunction_Introduction.md similarity index 95% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Disjunction_Introduction.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Disjunction_Introduction.md index a8205ef..cad4d2f 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Disjunction_Introduction.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Disjunction_Introduction.md @@ -15,4 +15,4 @@ to be true. This is represented in the context of can pass up via either branch of a disjunction pattern. This rule is sometimes also referred to (confusingly) as _Addition_. -![](/static/disjunc-intro.png) +![](static/disjunc-intro.png) diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Disk_info.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Disk_info.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Disk_info.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Disk_info.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Distributivity.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Distributivity.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Distributivity.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Distributivity.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Dividing_fractions.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Dividing_fractions.md similarity index 92% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Dividing_fractions.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Dividing_fractions.md index 869810f..fb95bce 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Dividing_fractions.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Dividing_fractions.md @@ -8,16 +8,16 @@ tags: Suppose you have the following shape: -![draw.io-Page-9.drawio 1.png](/static/draw.io-Page-9.drawio.png) +![draw.io-Page-9.drawio 1.png](static/draw.io-Page-9.drawio.png) One part is shaded. This represents one-eighth of the original shape. -![one-eighth-a.png](/static/one-eighth-a.png) +![one-eighth-a.png](static/one-eighth-a.png) Now imagine there are four instances of the shape and one-eighth remains shaded. How man one-eighths are there in four? -![draw.io-Page-9.drawio 2.png](/static/draw.io-Page-9.drawio.png) +![draw.io-Page-9.drawio 2.png](static/draw.io-Page-9.drawio.png) The shaded proportion represents $\frac{1}{8}$ of the shape. Imagine four of these shapes, how many eighths are there? diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Docker_CLI.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Docker_CLI.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Docker_CLI.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Docker_CLI.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Docker_Compose.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Docker_Compose.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Docker_Compose.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Docker_Compose.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Docker_architecture.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Docker_architecture.md similarity index 98% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Docker_architecture.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Docker_architecture.md index 0b13b37..ef4adab 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Docker_architecture.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Docker_architecture.md @@ -6,7 +6,7 @@ tags: [docker, containerization] ## Overview -![](/static/dock-architecture.png) +![](static/dock-architecture.png) - The Docker Client is a thin API for making [REST API](RESTful_APIs.md) to the Docker Server. Any CLI diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Docker_compose_and_Dockerfile_difference.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Docker_compose_and_Dockerfile_difference.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Docker_compose_and_Dockerfile_difference.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Docker_compose_and_Dockerfile_difference.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Docker_containers.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Docker_containers.md similarity index 99% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Docker_containers.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Docker_containers.md index c8e268c..7bd87d5 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Docker_containers.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Docker_containers.md @@ -142,7 +142,7 @@ docker attach my_container ## Container lifecycle -![](/static/container-lifecycle.png) +![](static/container-lifecycle.png) All containers have a lifecycle represented by five distinct states. Each state has an associated command: diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Docker_general_overview.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Docker_general_overview.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Docker_general_overview.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Docker_general_overview.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Docker_images.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Docker_images.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Docker_images.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Docker_images.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Docker_storage.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Docker_storage.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Docker_storage.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Docker_storage.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/DynamoDB_CLI_commands.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/DynamoDB_CLI_commands.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/DynamoDB_CLI_commands.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/DynamoDB_CLI_commands.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/DynamoDB_SDK_commands.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/DynamoDB_SDK_commands.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/DynamoDB_SDK_commands.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/DynamoDB_SDK_commands.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/DynamoDB_data_structure.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/DynamoDB_data_structure.md similarity index 99% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/DynamoDB_data_structure.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/DynamoDB_data_structure.md index e81b0ef..f135966 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/DynamoDB_data_structure.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/DynamoDB_data_structure.md @@ -17,7 +17,7 @@ DynamoDB is "NoSQL" because it does not support #SQL queries and is non-relational meaning there cannot be JOIN operations via [foreign_keys](Foreign_keys_in_SQL.md) -![](/static/dynamodb.png) +![](static/dynamodb.png) ### Primary key diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Effective_logging_in_Git.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Effective_logging_in_Git.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Effective_logging_in_Git.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Effective_logging_in_Git.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Elastic_Compute_Cloud.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Elastic_Compute_Cloud.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Elastic_Compute_Cloud.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Elastic_Compute_Cloud.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Electromagnetism.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Electromagnetism.md similarity index 99% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Electromagnetism.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Electromagnetism.md index 48cd7d8..1e73fea 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Electromagnetism.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Electromagnetism.md @@ -55,7 +55,7 @@ call this propensity of electrons the **intrinsic magnetic moment** of the electron. It is aggregates of these miniature magnetic behaviours that produce the overall magnetic property of the material. -![](/static/dipole-again.svg) +![](static/dipole-again.svg) In most materials, equal numbers of electrons spin in opposite directions. As a result, their magentic effects are cancelled out. However **in strongly magnetic @@ -179,7 +179,7 @@ waves form a spectrum based on their frequency and wavelength. For example, 'radio waves' are low-frequency / long wavelength electromagnetic waves and gamma rays are high-frequency / short wavelength waves: -![](/static/em-spectrum.jpg) +![](static/em-spectrum.jpg) The image below shows the propagation of an electromagnetic wave through space. We can identify the core components as follows @@ -189,7 +189,7 @@ We can identify the core components as follows which propagates upward along the $y$ axis - The directionality of both waves is forward along the $x$ axis -![](/static/em-wave.gif) +![](static/em-wave.gif) ## Using magnetism to generate electricity diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Electrons.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Electrons.md similarity index 99% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Electrons.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Electrons.md index 6f48ade..fc5cb6d 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Electrons.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Electrons.md @@ -16,7 +16,7 @@ to the nucleus. _The diagram below demonstrates shell naming conventions and the maximum number of electrons per shell._ -![](/static/valence-shell.svg) +![](static/valence-shell.svg) ## Valence diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Enums.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Enums.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Enums.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Enums.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Environmental_and_shell_variables.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Environmental_and_shell_variables.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Environmental_and_shell_variables.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Environmental_and_shell_variables.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Equivalent_equations.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Equivalent_equations.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Equivalent_equations.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Equivalent_equations.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Equivalent_fractions.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Equivalent_fractions.md similarity index 95% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Equivalent_fractions.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Equivalent_fractions.md index 84d0d44..85732b5 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Equivalent_fractions.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Equivalent_fractions.md @@ -9,7 +9,7 @@ tags: Two fractions are equivalent if they represent the same value. To begin with we can represent this visually: -![equiv-fractions.png](/static/equiv-fractions.png) +![equiv-fractions.png](static/equiv-fractions.png) _Each shaded area is taking up the same proportion of the whole._ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Error_handling_in_Python.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Error_handling_in_Python.md similarity index 98% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Error_handling_in_Python.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Error_handling_in_Python.md index 5b51974..cf9ce67 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Error_handling_in_Python.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Error_handling_in_Python.md @@ -38,7 +38,7 @@ exception class. The root class is `BaseException` which all errors and exeptions extend as subclasses as demonstrated by this diagram: -![](/static/python-exception-hierarchy.png) +![](static/python-exception-hierarchy.png) ## Exception syntax diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Event_loop.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Event_loop.md similarity index 98% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Event_loop.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Event_loop.md index 3e405cd..1c10f9b 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Event_loop.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Event_loop.md @@ -25,7 +25,7 @@ If there was only one thread, this would be inefficient and unworkable. Therefore the framework will be multi-threaded: multiple request-response cycles can be executed at once by different threads. -![sync-thread.svg](/static/sync-thread.svg) +![sync-thread.svg](static/sync-thread.svg) To accomodate the ability to increase the scale of synchronous applications you need to be able to spawn more threads commensurate to increased demand. This @@ -43,7 +43,7 @@ dispatching them asynchronously. When a request is made it sends it off and continues with its execution and handling new requests. Once these resolve, the data is returned to the main thread. -![async.svg](/static/async.svg) +![async.svg](static/async.svg) ## The Event Loop @@ -74,7 +74,7 @@ process exits when there is no more pending work in the Event Loop, or when are tasks queued in the Event Loop, or present on the [call stack](Call_stack.md). -![](/static/node-event-loop.svg) +![](static/node-event-loop.svg) The phases are as follows: diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Example_scenario_internet_data_transfer.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Example_scenario_internet_data_transfer.md similarity index 94% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Example_scenario_internet_data_transfer.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Example_scenario_internet_data_transfer.md index 1e97a46..1c0a742 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Example_scenario_internet_data_transfer.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Example_scenario_internet_data_transfer.md @@ -5,9 +5,9 @@ created: Friday, September 06, 2024 # Example scenario of data transfer accross the internet -![Path of a network request accross the internet](/static/network-request-layers.png) +![Path of a network request accross the internet](static/network-request-layers.png) -![All layers of the IP](/static/all-layers-of-IP.png) +![All layers of the IP](static/all-layers-of-IP.png) - A client device is connected to a wireless WiFi network. - This network is connected to the internet via a router. diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Expansions_and_substitutions.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Expansions_and_substitutions.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Expansions_and_substitutions.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Expansions_and_substitutions.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Exponents.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Exponents.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Exponents.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Exponents.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Expressing_whole_numbers_as_fractions.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Expressing_whole_numbers_as_fractions.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Expressing_whole_numbers_as_fractions.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Expressing_whole_numbers_as_fractions.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Factors_and_divisors.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Factors_and_divisors.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Factors_and_divisors.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Factors_and_divisors.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Factory_pattern.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Factory_pattern.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Factory_pattern.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Factory_pattern.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Fetch_decode_execute.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Fetch_decode_execute.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Fetch_decode_execute.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Fetch_decode_execute.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Fetch_from_Secrets_Manager.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Fetch_from_Secrets_Manager.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Fetch_from_Secrets_Manager.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Fetch_from_Secrets_Manager.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/File_descriptors.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/File_descriptors.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/File_descriptors.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/File_descriptors.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/File_permissions_and_execution_in_Bash.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/File_permissions_and_execution_in_Bash.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/File_permissions_and_execution_in_Bash.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/File_permissions_and_execution_in_Bash.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Filesystems.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Filesystems.md similarity index 99% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Filesystems.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Filesystems.md index efa724d..8ac6a30 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Filesystems.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Filesystems.md @@ -65,7 +65,7 @@ Our `sda1` partition is now mounted at `mountpoint`. We can go ahead and create files. If we now look within the graphical file manager when we click on the `sda1` volume, we will see the new file we have created in `mountpoint`. -![](/static/mount-directory.png) +![](static/mount-directory.png) ## fstab diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Find_Bash_command.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Find_Bash_command.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Find_Bash_command.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Find_Bash_command.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Flip_flops.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Flip_flops.md similarity index 97% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Flip_flops.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Flip_flops.md index f1bc27c..ed841ce 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Flip_flops.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Flip_flops.md @@ -42,7 +42,7 @@ The possible state changes for the JK Flip-Flop are detailed below: A JK Flip-Flop can execute on either the positive or negative pulse. Below are the diagrams for a rising and falling pulse respectively: -![](/static/jk-flip-flops.png) +![](static/jk-flip-flops.png) ## T Flip-Flops @@ -59,4 +59,4 @@ Thus the state table for the T Flip-Flop is: | 0 | Pulse | Maintain previous value | Hold | | 0 | Pulse | Inverse of previous value | Toggle | -![](/static/t-flip-flops.png) +![](static/t-flip-flops.png) diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Foreign_keys_in_SQL.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Foreign_keys_in_SQL.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Foreign_keys_in_SQL.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Foreign_keys_in_SQL.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Formal_conventions.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Formal_conventions.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Formal_conventions.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Formal_conventions.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Formal_proofs_in_propositional_logic.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Formal_proofs_in_propositional_logic.md similarity index 97% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Formal_proofs_in_propositional_logic.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Formal_proofs_in_propositional_logic.md index d0a80db..a8de834 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Formal_proofs_in_propositional_logic.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Formal_proofs_in_propositional_logic.md @@ -54,11 +54,11 @@ Sub-proofs follow this structure recursively. This is known as _Fitch notation_ _Schematically_: -![](/static/proofs-drawio-Page-5.drawio.png) +![](static/proofs-drawio-Page-5.drawio.png) _Applied example_: -![](/static/proofs-drawio-Page-6.drawio.png) +![](static/proofs-drawio-Page-6.drawio.png) ## Sub-proofs diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Format_specifiers_in_C.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Format_specifiers_in_C.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Format_specifiers_in_C.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Format_specifiers_in_C.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Formatting_output_text_in_Bash.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Formatting_output_text_in_Bash.md similarity index 96% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Formatting_output_text_in_Bash.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Formatting_output_text_in_Bash.md index ee6a00b..5846064 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Formatting_output_text_in_Bash.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Formatting_output_text_in_Bash.md @@ -30,7 +30,7 @@ three lines ## Colour outputs -![](/static/terminal_colours.png) +![](static/terminal_colours.png) ```bash echo -e "\033[31;40mColoured Text\033[0m" diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Forms_in_React.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Forms_in_React.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Forms_in_React.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Forms_in_React.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Four_bit_adder.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Four_bit_adder.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Four_bit_adder.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Four_bit_adder.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Frequency_counters.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Frequency_counters.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Frequency_counters.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Frequency_counters.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Full_Node_API_example.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Full_Node_API_example.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Full_Node_API_example.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Full_Node_API_example.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Function_overloads.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Function_overloads.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Function_overloads.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Function_overloads.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Functions.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Functions.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Functions.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Functions.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Functions_in_Bash.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Functions_in_Bash.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Functions_in_Bash.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Functions_in_Bash.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Functions_in_Python.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Functions_in_Python.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Functions_in_Python.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Functions_in_Python.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Fundamental_Theorem_of_Arithmetic.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Fundamental_Theorem_of_Arithmetic.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Fundamental_Theorem_of_Arithmetic.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Fundamental_Theorem_of_Arithmetic.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Further_examples_of_TS_generics.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Further_examples_of_TS_generics.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Further_examples_of_TS_generics.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Further_examples_of_TS_generics.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/GPU_versus_CPU.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/GPU_versus_CPU.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/GPU_versus_CPU.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/GPU_versus_CPU.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Generics_in_TypeScript.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Generics_in_TypeScript.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Generics_in_TypeScript.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Generics_in_TypeScript.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Git_bisect.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Git_bisect.md similarity index 96% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Git_bisect.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Git_bisect.md index fb98bb8..13d812e 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Git_bisect.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Git_bisect.md @@ -15,7 +15,7 @@ We mark the last good revision and the first bad revision. Bisect will the reset the code to the midpoint between the good and bad versions and let you test it. You mark that as a good or bad version and then bisect repeats the process. -![](/static/git-bisect.svg) +![](static/git-bisect.svg) ## Procedure diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Git_rebasing.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Git_rebasing.md similarity index 97% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Git_rebasing.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Git_rebasing.md index 6049122..7ef99af 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Git_rebasing.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Git_rebasing.md @@ -17,7 +17,7 @@ is evident from the following automatic commit message that is generated: Merge branch B of github.com:thomasabishop/remote-repository into A ``` -![](/static/normal-merge-again.svg) +![](static/normal-merge-again.svg) In this scenario the merge commit has two or more parent commits each representing the history of the merged branches. The resulting history of A will @@ -26,7 +26,7 @@ include the commits of B. Basically the two histories are combined. This would give us a history that looks like the following, with different colours for the separate SHAs of each merged branch: -![](/static/combined-merge-hist.svg) +![](static/combined-merge-hist.svg) If we were to create a rebase branch of A from B, there would be a new singular history without distinguishing multiple parents that combines the commits of A @@ -39,12 +39,12 @@ of commits in a single branch. When a rebase is applied, it will put the diverging B commits at the tip of A like so: -![](/static/rebase-tip-chage.svg) +![](static/rebase-tip-chage.svg) And then rebrand the previous A commits to be continuous with B presenting a flat and linear Git history like the following: -![](/static/single-git-history-rebase.svg) +![](static/single-git-history-rebase.svg) ## Benefits, use-cases @@ -160,7 +160,7 @@ recent. This will open an interactive rebase window, listing the commits. You can then use the keywords to decide what you want to do with them. In our case this will be `s` for squash. -![](/static/git-interactive-rebase.png) +![](static/git-interactive-rebase.png) ### Example diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Global_object_in_NodeJS.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Global_object_in_NodeJS.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Global_object_in_NodeJS.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Global_object_in_NodeJS.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Grep.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Grep.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Grep.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Grep.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Ground.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Ground.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Ground.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Ground.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Guide_to_YAML.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Guide_to_YAML.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Guide_to_YAML.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Guide_to_YAML.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/HTTP_request_types.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/HTTP_request_types.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/HTTP_request_types.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/HTTP_request_types.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Half_adder_and_full_adder.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Half_adder_and_full_adder.md similarity index 98% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Half_adder_and_full_adder.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Half_adder_and_full_adder.md index 34505a8..cdbe2a2 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Half_adder_and_full_adder.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Half_adder_and_full_adder.md @@ -65,7 +65,7 @@ The diagram below shows the circuit representation of a half-adder and an example calculation. This calculation matches the ones column of the earlier binary addition example: $0011 + 0010$. -![](/static/half-adder-new.png) +![](static/half-adder-new.png) ### Implementation with logic gates @@ -109,7 +109,7 @@ And the carry-out bit replicates the truth conditions of It is therefore possible to implement a half-adder with just these two logic gates: -![](/static/half-adder-gates-three.png) +![](static/half-adder-gates-three.png) The digital circuit above has the same inputs and outputs as the half adder diagram above. @@ -134,7 +134,7 @@ and B) and like the half adder, generates a sum bit and a carry-out bit. | ---------------------------- | ----------------------------- | ------------------------ | ---------------------- | ---------------------------- | | The first number to be added | The second number to be added | The incoming carried bit | The sum bit (A+B+C_in) | The carry-out bit (A+B+C_in) | -![](/static/full-adder-new.png) +![](static/full-adder-new.png) The diagram above is equivalent to the calculation taking place in the fours column. It has received a carry from the twos column ($1 + 1$ results in $1$ as diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Handle_multiple_endpoints_single_lambda.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Handle_multiple_endpoints_single_lambda.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Handle_multiple_endpoints_single_lambda.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Handle_multiple_endpoints_single_lambda.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Handling_negative_fractions.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Handling_negative_fractions.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Handling_negative_fractions.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Handling_negative_fractions.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Hardware_Description_Language.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Hardware_Description_Language.md similarity index 99% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Hardware_Description_Language.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Hardware_Description_Language.md index 63dfad3..5335359 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Hardware_Description_Language.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Hardware_Description_Language.md @@ -34,7 +34,7 @@ we can learn the main facets of chip design. Its syntax is very similar to VHDL. We will create an HDL program for an XOR gate that is implemented through the following arrangement of NOT, AND, and OR gates: -![](/static/xor-hdl.png) +![](static/xor-hdl.png) ### HDL file (`Xor.hdl`): diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Hardware_abstraction_and_modularity.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Hardware_abstraction_and_modularity.md similarity index 95% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Hardware_abstraction_and_modularity.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Hardware_abstraction_and_modularity.md index 651cf23..579e55b 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Hardware_abstraction_and_modularity.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Hardware_abstraction_and_modularity.md @@ -29,4 +29,4 @@ Edition)] The design of the diagram below emphasises the role of abstraction and modularity in the movement from transistors to chips: -![](/static/hardware-abstraction-hierarchy.png) +![](static/hardware-abstraction-hierarchy.png) diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Hardware_simulation.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Hardware_simulation.md similarity index 97% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Hardware_simulation.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Hardware_simulation.md index 6d6d39d..cc884ac 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Hardware_simulation.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Hardware_simulation.md @@ -9,7 +9,7 @@ In order to test our them into the hardware simulator program. We will demonstrate this with the following XOR implementation: -![](/static/xor-addition-four.png) +![](static/xor-addition-four.png) There are several simulation options: @@ -43,7 +43,7 @@ When this is run it automatically generates an output file in the source directory at `Xor.out`. This can be viewed within the simulator via the 'View' drop down. -![](/static/hd-sim-test.png) +![](static/hd-sim-test.png) ## Comparison-based diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Headless_Raspi_network_setup.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Headless_Raspi_network_setup.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Headless_Raspi_network_setup.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Headless_Raspi_network_setup.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Heap_memory.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Heap_memory.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Heap_memory.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Heap_memory.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Hexadecimal_number_system.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Hexadecimal_number_system.md similarity index 99% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Hexadecimal_number_system.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Hexadecimal_number_system.md index f914858..b4696cf 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Hexadecimal_number_system.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Hexadecimal_number_system.md @@ -114,7 +114,7 @@ $$ = 15 $$ -![](/static/hexadecimal-to-bytes.svg) +![](static/hexadecimal-to-bytes.svg) > Every four bits (or half byte) in binary corresponds to one symbol in > hexadecimal. Therefore **a byte can be easily represented with two hexadecimal diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/IO_in_Python.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/IO_in_Python.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/IO_in_Python.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/IO_in_Python.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/IP_addresses.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/IP_addresses.md similarity index 98% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/IP_addresses.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/IP_addresses.md index 0af20d9..2722e6b 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/IP_addresses.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/IP_addresses.md @@ -31,7 +31,7 @@ The 32 bits comprise two major groupings - the **network prefix** - the **host** -![Different sections of IP address](/static/ip-address-anatomy.png) +![Different sections of IP address](static/ip-address-anatomy.png) Devices connected to the same network share the same network prefix. They are said to be on the same **subnet**. However each device will have a unique value diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Identify_merged_branches.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Identify_merged_branches.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Identify_merged_branches.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Identify_merged_branches.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Importing_MongoDB_data.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Importing_MongoDB_data.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Importing_MongoDB_data.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Importing_MongoDB_data.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Increasing_fractions_to_their_highest_terms.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Increasing_fractions_to_their_highest_terms.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Increasing_fractions_to_their_highest_terms.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Increasing_fractions_to_their_highest_terms.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Insert_data_into_SQL_table.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Insert_data_into_SQL_table.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Insert_data_into_SQL_table.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Insert_data_into_SQL_table.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Instruction_set_architectures.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Instruction_set_architectures.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Instruction_set_architectures.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Instruction_set_architectures.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Integers.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Integers.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Integers.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Integers.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Integrated_circuits.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Integrated_circuits.md similarity index 93% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Integrated_circuits.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Integrated_circuits.md index 351a5b0..d02dfe3 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Integrated_circuits.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Integrated_circuits.md @@ -23,6 +23,6 @@ to a breadboard. _An integrated circuit and its use on a breadboard:_ -![](/static/integrated-circuit.jpeg) +![](static/integrated-circuit.jpeg) -![](/static/breadboard-DIP.jpg) +![](static/breadboard-DIP.jpg) diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Interactive_staging.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Interactive_staging.md similarity index 94% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Interactive_staging.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Interactive_staging.md index df7e779..14f06bf 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Interactive_staging.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Interactive_staging.md @@ -17,7 +17,7 @@ git add -i This opens an interface: -![](/static/git-interactive-mode-2.png) +![](static/git-interactive-mode-2.png) We select 2 and it lets us stage by number. If I enter 1, it will stage the first change. @@ -38,7 +38,7 @@ But it is useful for staging sub-portions of a file, which are called **hunks**. We access these via **patch mode**: -![](/static/git-patch-mode.png) +![](static/git-patch-mode.png) ### Splitting hunks @@ -57,7 +57,7 @@ mode. We enter this with `e`. This will oped up Vim for the manual work to be done: -![](/static/git-manual-hunk.png) +![](static/git-manual-hunk.png) We use the diff symbols `+`, `-` and space to do this. diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Internet_Layer_of_Internet_Protocol.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Internet_Layer_of_Internet_Protocol.md similarity index 95% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Internet_Layer_of_Internet_Protocol.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Internet_Layer_of_Internet_Protocol.md index d37d18b..1481bcc 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Internet_Layer_of_Internet_Protocol.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Internet_Layer_of_Internet_Protocol.md @@ -27,7 +27,7 @@ when sent and received within the [Link Layer](Link_Layer_of_Internet_Protocol.md) on the local network, are enclosed within a Link Layer frame (in its payload section): -![Internet Layer packet](/static/internet-layer-packet-revised.png) +![Internet Layer packet](static/internet-layer-packet-revised.png) Like a frame, an IP packet has a header and a payload. The payload comprises the data between sent between hosts. The header contains a source IP address and a diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Internet_fundamentals.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Internet_fundamentals.md similarity index 97% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Internet_fundamentals.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Internet_fundamentals.md index 7cbce87..28ad694 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Internet_fundamentals.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Internet_fundamentals.md @@ -24,7 +24,7 @@ Hence the Internet Protocol Suite is also known as "TCP/IP". The TCP/IP is a network stack comprising four layers, each with its own protocols. From the top: -![TCP/IP stack diagram](/static/TCP_IP.png) +![TCP/IP stack diagram](static/TCP_IP.png) - The [Link Layer](Link_Layer_of_Internet_Protocol.md) concerns communication between devices on the same local network. The transfer of information once it diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Intersection_types_in_TypeScript.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Intersection_types_in_TypeScript.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Intersection_types_in_TypeScript.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Intersection_types_in_TypeScript.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Intro_to_the_Unix_shell.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Intro_to_the_Unix_shell.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Intro_to_the_Unix_shell.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Intro_to_the_Unix_shell.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Inversion_of_operators.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Inversion_of_operators.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Inversion_of_operators.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Inversion_of_operators.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Invoking_the_shell_in_Python.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Invoking_the_shell_in_Python.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Invoking_the_shell_in_Python.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Invoking_the_shell_in_Python.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Iterating_in_React.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Iterating_in_React.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Iterating_in_React.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Iterating_in_React.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Iterating_through_complex_data_structures_in_Python.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Iterating_through_complex_data_structures_in_Python.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Iterating_through_complex_data_structures_in_Python.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Iterating_through_complex_data_structures_in_Python.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Joins_in_SQL.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Joins_in_SQL.md similarity index 98% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Joins_in_SQL.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Joins_in_SQL.md index fd5db8d..24c2359 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Joins_in_SQL.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Joins_in_SQL.md @@ -92,7 +92,7 @@ ON model.model_id = sales.model_id; -- Specify the match criteria We can represent the logical relationship that obtains between the `sales` and `model` tables as follows: -![](/static/sql-inner-join.png) +![](static/sql-inner-join.png) ## Outer joins @@ -141,7 +141,7 @@ this would give us the following table in return: The logical relationship sustained between `sales` and `model` by a left inner join is represented in the following diagram: -![](/static/sql-left-outer-join.png) +![](static/sql-left-outer-join.png) #### Implementation @@ -184,7 +184,7 @@ performed a right outer join this would give us the following table in return: The logical relationship sustained between `sales` and `model` by a right inner join is represented in the following diagram: -![](/static/sql-right-outer-join.png) +![](static/sql-right-outer-join.png) #### Implementation @@ -226,7 +226,7 @@ generated: Represented by the following diagram: -![](/static/sql-full-outer-join.png) +![](static/sql-full-outer-join.png) #### Implementation diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Journey_of_GraphQL_query.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Journey_of_GraphQL_query.md similarity index 61% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Journey_of_GraphQL_query.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Journey_of_GraphQL_query.md index b3251eb..8724156 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Journey_of_GraphQL_query.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Journey_of_GraphQL_query.md @@ -4,4 +4,4 @@ tags: [graphql] # The journey of a GraphQL query -![](/static/graphql-journey-two.svg) +![](static/graphql-journey-two.svg) diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Key_characteristics_of_GraphQL.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Key_characteristics_of_GraphQL.md similarity index 97% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Key_characteristics_of_GraphQL.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Key_characteristics_of_GraphQL.md index b06914d..cbcb52a 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Key_characteristics_of_GraphQL.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Key_characteristics_of_GraphQL.md @@ -54,7 +54,7 @@ client application. Client requests are sent over HTTPS and the data is typically returned in the form of JSON: -![](/static/graphql-architecture.png) +![](static/graphql-architecture.png) ## Implementation overview @@ -132,15 +132,15 @@ each individual resource: The REST scenario: -![](/static/REST_request-load.png) +![](static/REST_request-load.png) The GraphQL scenario: -![](/static/graphQL_request_load.png) +![](static/graphQL_request_load.png) ### Abstraction of multiple services -![](/static/graphql_multiple_resources.png) +![](static/graphql_multiple_resources.png) ### Stops overfetching diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Killing_processes.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Killing_processes.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Killing_processes.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Killing_processes.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/LEDs.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/LEDs.md similarity index 93% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/LEDs.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/LEDs.md index 782b1b7..fbfab37 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/LEDs.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/LEDs.md @@ -8,7 +8,7 @@ tags: LED' stands for **Light Emitting Diode**, a [circuit]() component that emits light. The symbol for an LED is displayed below: -![](/static/diode-led.png) +![](static/diode-led.png) A **diode** is a special kind of component that only permits current to flow through it in one direction. To achieve this it has very low resistance in one @@ -16,7 +16,7 @@ direction to allow current flow and high resistance in the other direction to impede current flow. This feature of diodes is clearly represented in the generic diode circuit symbol: -![](/static/diode.png) +![](static/diode.png) An LED diode lights up when the right amount of current flows through it. A standard LED has a maximum current of 20mA. An appropriate diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Lambda_directory_structure.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Lambda_directory_structure.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Lambda_directory_structure.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Lambda_directory_structure.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Lambda_handler_function.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Lambda_handler_function.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Lambda_handler_function.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Lambda_handler_function.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Lambda_programming_model.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Lambda_programming_model.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Lambda_programming_model.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Lambda_programming_model.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Lambda_triggers.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Lambda_triggers.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Lambda_triggers.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Lambda_triggers.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Lambdas_in_Python.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Lambdas_in_Python.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Lambdas_in_Python.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Lambdas_in_Python.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Latches.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Latches.md similarity index 98% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Latches.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Latches.md index c118bc3..73340cf 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Latches.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Latches.md @@ -43,7 +43,7 @@ The most succinct account of a latch: _The representation of an SR Latch in a digital circuit diagram_: -![](/static/sr_latch_diagram.png) +![](static/sr_latch_diagram.png) ## Creating a latch circuit @@ -58,7 +58,7 @@ also an input of the other at a single stage in the sequence. The circuit is created as follows: -![](/static/sr_latch_logic_circuit.png) +![](static/sr_latch_logic_circuit.png) Interactive version: diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Law_of_Non_Contradiction.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Law_of_Non_Contradiction.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Law_of_Non_Contradiction.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Law_of_Non_Contradiction.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Law_of_the_Excluded_Middle.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Law_of_the_Excluded_Middle.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Law_of_the_Excluded_Middle.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Law_of_the_Excluded_Middle.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Lifecycle_methods.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Lifecycle_methods.md similarity index 98% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Lifecycle_methods.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Lifecycle_methods.md index 6e63710..ab5b0cb 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Lifecycle_methods.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Lifecycle_methods.md @@ -43,7 +43,7 @@ The final phase is unmounting: when the component is removed from the DOM: 6. `componentWillUnmount()` -![React component lifecycle](/static/react-lifecycle.png) +![React component lifecycle](static/react-lifecycle.png) ## Side-effects: why lifecycle phases matter diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Link_Layer_of_Internet_Protocol.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Link_Layer_of_Internet_Protocol.md similarity index 93% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Link_Layer_of_Internet_Protocol.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Link_Layer_of_Internet_Protocol.md index 15eb3cb..ee076fb 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Link_Layer_of_Internet_Protocol.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Link_Layer_of_Internet_Protocol.md @@ -24,7 +24,7 @@ same is not true for other layers. For example a device like a laptop participates in all four layers up to the Application Layer but a network router does not: -![Link Layer diagram](/static/link-layer-frame-revised.png) +![Link Layer diagram](static/link-layer-frame-revised.png) ## MAC addresses @@ -42,7 +42,7 @@ a specific MAC address. This is off-limits from the outside. Link Layer data is divided into small units called "frames". The anatomy of a frame is as follows: -![Link Layer frame](/static/link-layer-frame-revised.png) +![Link Layer frame](static/link-layer-frame-revised.png) The header contains the source and destination MAC address plus a descriptor of the type of data it contains. The data is the payload. The footer is used to diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Linux_disk_partitions.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Linux_disk_partitions.md similarity index 98% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Linux_disk_partitions.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Linux_disk_partitions.md index 00036c2..45af26f 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Linux_disk_partitions.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Linux_disk_partitions.md @@ -174,4 +174,4 @@ In our example above: ## Related notes -![Creating a Linux partition table](/static/Creating_a_Linux_partition_table.md) +![Creating a Linux partition table](static/Creating_a_Linux_partition_table.md) diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/List_comprehension_in_Python.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/List_comprehension_in_Python.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/List_comprehension_in_Python.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/List_comprehension_in_Python.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Listing_and_navigating_directories_in_the_Shell.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Listing_and_navigating_directories_in_the_Shell.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Listing_and_navigating_directories_in_the_Shell.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Listing_and_navigating_directories_in_the_Shell.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Lists_and_arrays_in_Bash.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Lists_and_arrays_in_Bash.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Lists_and_arrays_in_Bash.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Lists_and_arrays_in_Bash.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Lists_in_Python.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Lists_in_Python.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Lists_in_Python.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Lists_in_Python.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Local_AWS_development_with_SAM.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Local_AWS_development_with_SAM.md similarity index 98% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Local_AWS_development_with_SAM.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Local_AWS_development_with_SAM.md index f62f0f3..4f41cfa 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Local_AWS_development_with_SAM.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Local_AWS_development_with_SAM.md @@ -32,7 +32,7 @@ You will be able to call it after executing the above. This will be indicated by: -![](/static/local-sam-docker.png) +![](static/local-sam-docker.png) If we want to invoke the function directly we use: diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Logarithms.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Logarithms.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Logarithms.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Logarithms.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Logic_gates.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Logic_gates.md similarity index 98% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Logic_gates.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Logic_gates.md index 195393f..35c2944 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Logic_gates.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Logic_gates.md @@ -92,7 +92,7 @@ tion) truth functional connective ### Symbol -![](/static/and-gate-new-2.png) +![](static/and-gate-new-2.png) ### Truth conditions @@ -110,7 +110,7 @@ tion) truth functional connective ### Symbol -![](/static/nand-gate-new.png) +![](static/nand-gate-new.png) ### Truth conditions @@ -139,7 +139,7 @@ NANDs alone. ### Symbol -![](/static/or-gate-new.png) +![](static/or-gate-new.png) ### Truth condition @@ -168,7 +168,7 @@ t ### Symbol -![](/static/xor-gate-new.png) +![](static/xor-gate-new.png) ### Truth conditions @@ -189,7 +189,7 @@ t ### Symbol -![](/static/nor-gate-new.png) +![](static/nor-gate-new.png) ### Truth conditions diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Logical_consistency.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Logical_consistency.md similarity index 98% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Logical_consistency.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Logical_consistency.md index d1362f5..f7fba74 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Logical_consistency.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Logical_consistency.md @@ -72,7 +72,7 @@ A has very important consequences for reasoning because if a set of propositions is inconsistent, any other proposition is derivable from it. -![](/static/derivation_from_contradiction.png) +![](static/derivation_from_contradiction.png) _A demonstration of the the consequences of deriving a contradiction in a sequence of reasoning._ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Logical_equivalence.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Logical_equivalence.md similarity index 96% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Logical_equivalence.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Logical_equivalence.md index 24fce46..637992e 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Logical_equivalence.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Logical_equivalence.md @@ -41,4 +41,4 @@ Note that the property of equivalence stated in terms of derivablity above is identical to the derivation rule for the [material biconditional](Biconditional_Introduction.md): -![bi-intro.png](/static/bi-intro.png) +![bi-intro.png](static/bi-intro.png) diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Logical_indeterminacy.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Logical_indeterminacy.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Logical_indeterminacy.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Logical_indeterminacy.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Logical_possibility_and_necessity.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Logical_possibility_and_necessity.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Logical_possibility_and_necessity.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Logical_possibility_and_necessity.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Logical_truth_and_falsity.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Logical_truth_and_falsity.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Logical_truth_and_falsity.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Logical_truth_and_falsity.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Loops_in_Python.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Loops_in_Python.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Loops_in_Python.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Loops_in_Python.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Loops_in_bash.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Loops_in_bash.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Loops_in_bash.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Loops_in_bash.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/MAC_addresses.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/MAC_addresses.md similarity index 91% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/MAC_addresses.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/MAC_addresses.md index 20f68fe..6cf6363 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/MAC_addresses.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/MAC_addresses.md @@ -11,7 +11,7 @@ an IP address which is logical. Each device on a [local network](./Link_Layer_of_Internet_Protocol.md) has a MAC as a unique identifier. It is a hardware-based, physical attribute of the device, typically permanently encoded onto a non-volatile memory chip attached -to the ![network_card](/static/Network_card.md). +to the ![network_card](static/Network_card.md). MAC addresses consist of 6 bytes (48-bits) represented as 12 [hexadecimal_digits](Hexadecimal_number_system.md). diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Machine_code.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Machine_code.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Machine_code.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Machine_code.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Magnetic_core_memory.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Magnetic_core_memory.md similarity index 89% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Magnetic_core_memory.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Magnetic_core_memory.md index c3bbcfc..7da9de2 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Magnetic_core_memory.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Magnetic_core_memory.md @@ -5,7 +5,7 @@ created: Friday, September 27, 2024 # Magnetic core memory -![](/static/magnetic-core-memory.jpg) +![](static/magnetic-core-memory.jpg) Like [Magnetic_drum_memory](Magnetic_drum_memory.md), magnetic core memory was faster and more reliable than [delay_line_memory](Delay_line_memory.md) and @@ -17,4 +17,4 @@ were arranged in a crisscross grid. A bead would be placed at the overlap of two copper threads. This constitutes a "core".A pulse of electric current would magnetise/de-magnetise the cores. -![](/static/magnetic-core-closeup.jpg) +![](static/magnetic-core-closeup.jpg) diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Magnetic_drum_memory.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Magnetic_drum_memory.md similarity index 95% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Magnetic_drum_memory.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Magnetic_drum_memory.md index 73e28d7..48e6ed0 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Magnetic_drum_memory.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Magnetic_drum_memory.md @@ -8,7 +8,7 @@ created: Tuesday, September 24, 2024 Along with the [Williams_Tube](Williams_Tube_memory.md), another early approach to RAM used in 1950s-1960s era of computing. -![Magnetic drum](/static/magnetic-drum-memory.jpg) +![Magnetic drum](static/magnetic-drum-memory.jpg) A magnetic drum was a metal cylinder coated with a magnetic material. Data was stored by magnetising small regions on the drum's surface. The drum would rotate diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Magnetic_tape.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Magnetic_tape.md similarity index 90% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Magnetic_tape.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Magnetic_tape.md index b14d1ca..4ccd4c1 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Magnetic_tape.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Magnetic_tape.md @@ -11,7 +11,7 @@ Used for data storage in early digital computers (broadly from the While the UNIVAC was not the first to use magnetic tape, it popularised the method due to its success and high profile. -![Magnetic tape reader in IBM computer](/static/magnetic-tape-ibm.jpeg) +![Magnetic tape reader in IBM computer](static/magnetic-tape-ibm.jpeg) It worked as follows. The tape was a long, narrow strip of plastic coated with a magnetic material. Data is recorded on the the tape by magnetising tiny @@ -30,7 +30,7 @@ accommodated batch processing well. However its sequential nature meant it was slow at retreiving specific pieces of data as it would have to cycle through all the values stored on the tape. -![Magnetic tape stored as casette](/static/magnetic-tape-disk.jpeg) +![Magnetic tape stored as casette](static/magnetic-tape-disk.jpeg) It developed from open-reel tapes to cartridges and cassettes. It was superseded by hard disk drives and solid state drives. diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Mainframe_computers.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Mainframe_computers.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Mainframe_computers.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Mainframe_computers.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Managing_environments_in_NodeJS.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Managing_environments_in_NodeJS.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Managing_environments_in_NodeJS.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Managing_environments_in_NodeJS.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Map_and_filter_in_Python.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Map_and_filter_in_Python.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Map_and_filter_in_Python.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Map_and_filter_in_Python.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Map_and_filter_to_reduce_in_JS.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Map_and_filter_to_reduce_in_JS.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Map_and_filter_to_reduce_in_JS.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Map_and_filter_to_reduce_in_JS.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Mapped_types_in_TS.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Mapped_types_in_TS.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Mapped_types_in_TS.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Mapped_types_in_TS.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Maps_and_sets_in_JS.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Maps_and_sets_in_JS.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Maps_and_sets_in_JS.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Maps_and_sets_in_JS.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Match_statements_in_Python.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Match_statements_in_Python.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Match_statements_in_Python.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Match_statements_in_Python.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Matter_and_atoms.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Matter_and_atoms.md similarity index 98% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Matter_and_atoms.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Matter_and_atoms.md index f9856b7..2411727 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Matter_and_atoms.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Matter_and_atoms.md @@ -28,7 +28,7 @@ tags: [physics] can join to form sodium chloride. We call this **chemical bonding**. ## Atomic particles -![](/static/atom-diagram.svg) +![](static/atom-diagram.svg) diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Memoization_in_React.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Memoization_in_React.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Memoization_in_React.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Memoization_in_React.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Memory_Management_Unit.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Memory_Management_Unit.md similarity index 96% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Memory_Management_Unit.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Memory_Management_Unit.md index 5b40d79..41065d4 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Memory_Management_Unit.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Memory_Management_Unit.md @@ -10,7 +10,7 @@ virtual memory space. It is a chip that sits between the CPU and the RAM and determines the physical location of the memory requested by the kernel as virtual memory. -![Virtual memory diagram](/static/virtual-memory-diagram.jpg) +![Virtual memory diagram](static/virtual-memory-diagram.jpg) ## Pages diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Memory_addresses.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Memory_addresses.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Memory_addresses.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Memory_addresses.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Memory_leaks.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Memory_leaks.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Memory_leaks.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Memory_leaks.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Memory_versus_processor.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Memory_versus_processor.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Memory_versus_processor.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Memory_versus_processor.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Messaging_services.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Messaging_services.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Messaging_services.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Messaging_services.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Middleware_in_NodeJS.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Middleware_in_NodeJS.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Middleware_in_NodeJS.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Middleware_in_NodeJS.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Mixed_and_improper_fractions.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Mixed_and_improper_fractions.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Mixed_and_improper_fractions.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Mixed_and_improper_fractions.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Modelling_relationships_in_MongoDB.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Modelling_relationships_in_MongoDB.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Modelling_relationships_in_MongoDB.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Modelling_relationships_in_MongoDB.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Module_pattern.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Module_pattern.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Module_pattern.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Module_pattern.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Module_wrapping_at_runtime.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Module_wrapping_at_runtime.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Module_wrapping_at_runtime.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Module_wrapping_at_runtime.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Modules_in_NodeJS.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Modules_in_NodeJS.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Modules_in_NodeJS.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Modules_in_NodeJS.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/MongoDB_Introduction.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/MongoDB_Introduction.md similarity index 96% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/MongoDB_Introduction.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/MongoDB_Introduction.md index be1f73c..1cf828a 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/MongoDB_Introduction.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/MongoDB_Introduction.md @@ -27,4 +27,4 @@ in RDB table: units that comprise the collection. A document is a container comprising key-value pairs in the manner of an object. -![](/static/mongo-db-structure.svg) +![](static/mongo-db-structure.svg) diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Monitoring_processes_and_resources.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Monitoring_processes_and_resources.md similarity index 99% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Monitoring_processes_and_resources.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Monitoring_processes_and_resources.md index 523da53..007d965 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Monitoring_processes_and_resources.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Monitoring_processes_and_resources.md @@ -22,7 +22,7 @@ time that they are utilising. You can also order by memory usage. _Here I have pressed `u` to show only the processes associated with my user:_ -![](/static/htop.png) +![](static/htop.png) ### Main commands @@ -131,7 +131,7 @@ using them. Without modifiers it outputs a huge amount of data. The best way to use it is to execute it against a specific PID. For example the below output gives me some useful info about which files VS Code is using: -![](/static/lsof.png) +![](static/lsof.png) ## System calls: `strace` diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Morgan.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Morgan.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Morgan.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Morgan.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Motherboard.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Motherboard.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Motherboard.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Motherboard.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Multiple_pointers.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Multiple_pointers.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Multiple_pointers.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Multiple_pointers.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Multiplexers_and_demultiplexers.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Multiplexers_and_demultiplexers.md similarity index 96% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Multiplexers_and_demultiplexers.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Multiplexers_and_demultiplexers.md index 72f357b..92e3f1f 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Multiplexers_and_demultiplexers.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Multiplexers_and_demultiplexers.md @@ -16,7 +16,7 @@ input to a single output line. We have two inputs (A,B) plus a third input SEL (for "select"). Applying a value to SEL toggles the output between A and B. -![](/static/MUX.png) +![](static/MUX.png) Multiplexers can be used to build larger circuits by connecting the output of one multiplexer to the input of another. They are often used to implement data @@ -35,7 +35,7 @@ As the name suggests, a demultiplexer reverses the functionality of a multiplexer. It receives a single input and based on the selection of the SEL input it channels it to either an A or a B output. -![](/static/DMUX.png) +![](static/DMUX.png) We can think of it as a distributor of a value into one of several possible channels. diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Multiplicative_identity.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Multiplicative_identity.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Multiplicative_identity.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Multiplicative_identity.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Multiplicative_property_of_negative_one.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Multiplicative_property_of_negative_one.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Multiplicative_property_of_negative_one.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Multiplicative_property_of_negative_one.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Multiplying_fractions.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Multiplying_fractions.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Multiplying_fractions.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Multiplying_fractions.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Mutations_with_Apollo_Client.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Mutations_with_Apollo_Client.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Mutations_with_Apollo_Client.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Mutations_with_Apollo_Client.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Naming_conventions.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Naming_conventions.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Naming_conventions.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Naming_conventions.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Natural_numbers.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Natural_numbers.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Natural_numbers.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Natural_numbers.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Negation_Elimination.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Negation_Elimination.md similarity index 94% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Negation_Elimination.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Negation_Elimination.md index c1089dc..4f2dc0b 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Negation_Elimination.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Negation_Elimination.md @@ -13,4 +13,4 @@ with a true proposition from which you derive a contradiction, you start with the negation of a proposition, derive a contradiction and then assert the positive of the negated proposition you started out with. -![](/static/negate-elim.png) +![](static/negate-elim.png) diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Negation_Introduction.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Negation_Introduction.md similarity index 93% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Negation_Introduction.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Negation_Introduction.md index 098aa3a..216d07e 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Negation_Introduction.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Negation_Introduction.md @@ -12,4 +12,4 @@ declared in a sub-proof. If you can derive a contradiction from this assumption you are permitted to derive the negation of the auxiliary assumption in the main proof. -![](/static/negate-intro.png) +![](static/negate-intro.png) diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Negative_exponents.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Negative_exponents.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Negative_exponents.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Negative_exponents.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Network_card.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Network_card.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Network_card.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Network_card.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Network_debugging.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Network_debugging.md similarity index 71% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Network_debugging.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Network_debugging.md index 88424b4..47fb237 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Network_debugging.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Network_debugging.md @@ -8,4 +8,4 @@ created: Monday, June 17, 2024 ## Related notes -![Network scanning](/static/Network_scanning.md) +![Network scanning](static/Network_scanning.md) diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Network_fundamentals.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Network_fundamentals.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Network_fundamentals.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Network_fundamentals.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Network_hosts.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Network_hosts.md similarity index 91% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Network_hosts.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Network_hosts.md index 7bbf296..ace007f 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Network_hosts.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Network_hosts.md @@ -6,7 +6,7 @@ created: Saturday, August 03, 2024 # Network hosts A network **host** or **node** is a single computing device attached to a -![network](/static/Network_fundamentals.md) +![network](static/Network_fundamentals.md) Hosts can act as servers or clients, or both. diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Network_protocols.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Network_protocols.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Network_protocols.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Network_protocols.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Network_requests_in_Python.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Network_requests_in_Python.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Network_requests_in_Python.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Network_requests_in_Python.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Network_scanning.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Network_scanning.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Network_scanning.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Network_scanning.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/NodeJS_scripts.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/NodeJS_scripts.md similarity index 95% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/NodeJS_scripts.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/NodeJS_scripts.md index 96148a9..b3e880e 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/NodeJS_scripts.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/NodeJS_scripts.md @@ -26,7 +26,7 @@ if (require.main === module) { Basically we have a function that contains the main actions of the script. This is then invoked within `main` in the manner of a Bash or -![Python script](/static/Single_file_Python_scripts.md) +![Python script](static/Single_file_Python_scripts.md) This obviously requires the Node binary to be in your path and the script must be run with executable privileges. diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Node_and_MySQL_db.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Node_and_MySQL_db.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Node_and_MySQL_db.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Node_and_MySQL_db.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Nodemon.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Nodemon.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Nodemon.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Nodemon.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Non_null_assertion_in_TypeScript.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Non_null_assertion_in_TypeScript.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Non_null_assertion_in_TypeScript.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Non_null_assertion_in_TypeScript.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/None_in_Python.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/None_in_Python.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/None_in_Python.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/None_in_Python.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Numbers_in_Python.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Numbers_in_Python.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Numbers_in_Python.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Numbers_in_Python.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Object_language_and_meta_language.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Object_language_and_meta_language.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Object_language_and_meta_language.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Object_language_and_meta_language.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Observer_pattern.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Observer_pattern.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Observer_pattern.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Observer_pattern.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Ohms_Law.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Ohms_Law.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Ohms_Law.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Ohms_Law.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/OpenSearch.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/OpenSearch.md similarity index 99% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/OpenSearch.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/OpenSearch.md index 1a00a6c..b4e088b 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/OpenSearch.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/OpenSearch.md @@ -50,7 +50,7 @@ A cluster is the highest level of organisation within an OpensSearch domain that contains your indexed data. It processes all the search queries and handles tasks like indexing, searching, and managing documents. -![](/static/opensearch-architecture.drawio.svg) +![](static/opensearch-architecture.drawio.svg) A cluster comprises **nodes**. Nodes are individual servers that hold part of the cluster's data. Each node participates in the indexing and searching of the diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Operating_system_API.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Operating_system_API.md similarity index 98% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Operating_system_API.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Operating_system_API.md index b8f4aa5..b53d83f 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Operating_system_API.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Operating_system_API.md @@ -20,7 +20,7 @@ Whether using the GUI or a terminal emulator, the shell translates the user's commands into API calls. The API the invokes internal operating system code to perform the action. -![OS API diagram](/static/OS-api.svg) +![OS API diagram](static/OS-api.svg) ## Example: opening a file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Order_of_operations.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Order_of_operations.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Order_of_operations.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Order_of_operations.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Package_management_in_NodeJS.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Package_management_in_NodeJS.md similarity index 95% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Package_management_in_NodeJS.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Package_management_in_NodeJS.md index 96862be..f1858d1 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Package_management_in_NodeJS.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Package_management_in_NodeJS.md @@ -29,7 +29,7 @@ We can pinpoint specific dependencies in the `package.json`, e.g. See whether your dependency version is out of date use `npm outdated`. This gives us a table, for example: -![Pasted image 20220411082627.png](/static/Pasted_image_20220411082627.png) +![Pasted image 20220411082627.png](static/Pasted_image_20220411082627.png) - _Latest_ tells us the latest release available from the developers - _Wanted_ tells us the version that our `package.json` rules target. To take diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Packet_switching_British_precursors.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Packet_switching_British_precursors.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Packet_switching_British_precursors.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Packet_switching_British_precursors.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Pacman.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Pacman.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Pacman.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Pacman.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Passing_arguments_and_options_to_Bash_scripts.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Passing_arguments_and_options_to_Bash_scripts.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Passing_arguments_and_options_to_Bash_scripts.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Passing_arguments_and_options_to_Bash_scripts.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Passing_arguments_to_Python_scripts.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Passing_arguments_to_Python_scripts.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Passing_arguments_to_Python_scripts.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Passing_arguments_to_Python_scripts.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Peer_to_peer_network.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Peer_to_peer_network.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Peer_to_peer_network.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Peer_to_peer_network.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Ports_in_NodeJS.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Ports_in_NodeJS.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Ports_in_NodeJS.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Ports_in_NodeJS.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Practical_walkthrough_Lambda_creation_within_AWS.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Practical_walkthrough_Lambda_creation_within_AWS.md similarity index 87% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Practical_walkthrough_Lambda_creation_within_AWS.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Practical_walkthrough_Lambda_creation_within_AWS.md index cf2c91e..c3920fa 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Practical_walkthrough_Lambda_creation_within_AWS.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Practical_walkthrough_Lambda_creation_within_AWS.md @@ -8,17 +8,17 @@ tags: [AWS, aws-lambda, node-js] First we name the function and accept the defaults: -![](/static/lambda_func_one.png) +![](static/lambda_func_one.png) This presents us with the function dashboard - a graphical representation of the Lambda showing [triggers]() as an input and destination as an output: -![](/static/lambda-func-two.png) +![](static/lambda-func-two.png) Beneath this we have a code editor with the handler function with a basic boilerplate: -![](/static/lambda-func-three.png) +![](static/lambda-func-three.png) ## Adding a trigger @@ -28,15 +28,15 @@ execute the handler. We will do this using [AWS API Gateway](AWS_API_Gateway.md). We select "Add trigger" from the dashboard view and input basic settings: -![](/static/api-gateway-trigger.png) +![](static/api-gateway-trigger.png) Now we see this step displayed in the dashboard: -![](/static/lambda-overview.png) +![](static/lambda-overview.png) With the endpoint and other settings displayed: -![](/static/trigger-info.png) +![](static/trigger-info.png) If we go to the endpoint URL (`https://4kjqwbvd7g.execute-api.us-east-1.amazonaws.com/default/myFirstFunction`), @@ -74,4 +74,4 @@ We get `Hello Thomas` as output. For a more advanced API with multiple endpoints and parameters, it's easiest to use Postman: -![](/static/postman-lambda.png) +![](static/postman-lambda.png) diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Prefixes_for_units_of_electrical_measurement.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Prefixes_for_units_of_electrical_measurement.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Prefixes_for_units_of_electrical_measurement.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Prefixes_for_units_of_electrical_measurement.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Prime_factorization.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Prime_factorization.md similarity index 71% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Prime_factorization.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Prime_factorization.md index 7444986..10ac3bc 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Prime_factorization.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Prime_factorization.md @@ -17,11 +17,11 @@ main approaches to this: > $n$. We then repeat this process with the resulting factors working > recursively until the numbers we are left with are primes. -![Untitled Diagram-Page-1.drawio.png](/static/Untitled%20Diagram-Page-1.drawio.png) _The +![Untitled Diagram-Page-1.drawio.png](static/Untitled%20Diagram-Page-1.drawio.png) _The prime factors of 27 are 2, 3, 3_ it doesn't matter which products we choose as the interim factors, we should always reach the same outcome: -![Untitled Diagram-Page-3.drawio 1.png](/static/Untitled%20Diagram-Page-3.drawio%201.png) +![Untitled Diagram-Page-3.drawio 1.png](static/Untitled%20Diagram-Page-3.drawio%201.png) -![Untitled Diagram-Page-2.drawio.png](/static/Untitled%20Diagram-Page-2.drawio.png) +![Untitled Diagram-Page-2.drawio.png](static/Untitled%20Diagram-Page-2.drawio.png) diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Primes_and_composites.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Primes_and_composites.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Primes_and_composites.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Primes_and_composites.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Primitive_types.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Primitive_types.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Primitive_types.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Primitive_types.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Printing_values_in_C.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Printing_values_in_C.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Printing_values_in_C.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Printing_values_in_C.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Process_module_in_NodeJS.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Process_module_in_NodeJS.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Process_module_in_NodeJS.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Process_module_in_NodeJS.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Processes.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Processes.md similarity index 85% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Processes.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Processes.md index c91cc85..cb1a2df 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Processes.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Processes.md @@ -19,7 +19,7 @@ a container in which a program runs. This container includes: - other information about the state of the process Other than the `init` process started by the kernel (PID1) (see -![systemd](/static/systemd.md)), every process has a parent process that started it. +![systemd](static/systemd.md)), every process has a parent process that started it. This parent-child relationship creates a tree of processes. It is possible that a parent process will terminate before one of its child @@ -29,7 +29,7 @@ processes. In this instance the child becomes an orphan. When this occurs in Below, I have used the `pstree` utility to list all the running processes on my machine hierarchically. -![diagram of `pstree` output](/static/ps-tree.png) +![diagram of `pstree` output](static/ps-tree.png) Children are represented vertically and horizontally. @@ -49,8 +49,8 @@ _processID_ or just _PID_. ## Related notes -![systemd](/static/systemd.md) +![systemd](static/systemd.md) -![ps](/static/ps.md) +![ps](static/ps.md) -![Monitoring processes and resources](/static/Monitoring_processes_and_resources.md) +![Monitoring processes and resources](static/Monitoring_processes_and_resources.md) diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Prop_types_in_React.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Prop_types_in_React.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Prop_types_in_React.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Prop_types_in_React.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Proper_shebang_syntax.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Proper_shebang_syntax.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Proper_shebang_syntax.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Proper_shebang_syntax.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Props_in_React.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Props_in_React.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Props_in_React.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Props_in_React.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Prototypical_inheritance.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Prototypical_inheritance.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Prototypical_inheritance.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Prototypical_inheritance.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Push_buttons.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Push_buttons.md similarity index 87% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Push_buttons.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Push_buttons.md index 175e0be..31a6e6c 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Push_buttons.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Push_buttons.md @@ -16,11 +16,11 @@ pairs. To create a breakable circuit we would connect a signal-in cable to the top left at row 23 and a signal-out cable to the bottom-right at row 25. -![Push button legs diagram](/static/push-button-legs.png) +![Push button legs diagram](static/push-button-legs.png) _The correct use of a push button where the button breaks the circuit_ -![](/static/correct_push_button.jpg) +![](static/correct_push_button.jpg) To override the switch functionality and just have the button work as a connector we would connect the signal-in to the row 23 input and the row 23 @@ -29,7 +29,7 @@ output. _The push button being used as simple connector which does not break the circuit:_ -![](/static/incorrect_push_button.jpg) +![](static/incorrect_push_button.jpg) ## Related notes diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Python_application_structure.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Python_application_structure.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Python_application_structure.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Python_application_structure.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Python_data_types.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Python_data_types.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Python_data_types.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Python_data_types.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Python_execution.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Python_execution.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Python_execution.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Python_execution.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Python_interpreter.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Python_interpreter.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Python_interpreter.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Python_interpreter.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Python_modules_and_imports.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Python_modules_and_imports.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Python_modules_and_imports.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Python_modules_and_imports.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Python_package_management.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Python_package_management.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Python_package_management.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Python_package_management.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Querying_a_Mongo_collection.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Querying_a_Mongo_collection.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Querying_a_Mongo_collection.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Querying_a_Mongo_collection.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Queue.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Queue.md similarity index 98% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Queue.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Queue.md index 1774102..8a7c276 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Queue.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Queue.md @@ -7,7 +7,7 @@ tags: _Visualization of the queue data structure_ -![queue.svg](/static/queue.svg) +![queue.svg](static/queue.svg) ## A queue is a sequential data structure and most similar to a stack diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Quote_marks_in_Bash.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Quote_marks_in_Bash.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Quote_marks_in_Bash.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Quote_marks_in_Bash.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/RESTful_APIs.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/RESTful_APIs.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/RESTful_APIs.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/RESTful_APIs.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/ROM_versus_disk_loading.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/ROM_versus_disk_loading.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/ROM_versus_disk_loading.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/ROM_versus_disk_loading.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/React_Components.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/React_Components.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/React_Components.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/React_Components.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/React_errors.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/React_errors.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/React_errors.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/React_errors.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/React_useContext.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/React_useContext.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/React_useContext.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/React_useContext.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/React_useEffect.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/React_useEffect.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/React_useEffect.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/React_useEffect.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/React_useReducer.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/React_useReducer.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/React_useReducer.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/React_useReducer.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/React_useState.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/React_useState.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/React_useState.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/React_useState.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Read_command__in_Bash.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Read_command__in_Bash.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Read_command__in_Bash.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Read_command__in_Bash.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Reciprocals.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Reciprocals.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Reciprocals.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Reciprocals.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Recursion.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Recursion.md similarity index 96% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Recursion.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Recursion.md index 9d6538f..b6acd91 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Recursion.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Recursion.md @@ -15,7 +15,7 @@ another example. Also fractals display recursive properties. ## Schema The general structure of a recursive function is as follows: -![javascript-recursion.png](/static/javascript-recursion.png) +![javascript-recursion.png](static/javascript-recursion.png) ## Why use recursive functions? @@ -129,4 +129,4 @@ if (num > 0) { } ``` -![javascript-factorial 1.png](/static/javascript-factorial%201.png) +![javascript-factorial 1.png](static/javascript-factorial%201.png) diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Redirect_to_dev_null.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Redirect_to_dev_null.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Redirect_to_dev_null.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Redirect_to_dev_null.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Redirection_in_Bash.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Redirection_in_Bash.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Redirection_in_Bash.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Redirection_in_Bash.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Reducing_fractions.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Reducing_fractions.md similarity index 96% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Reducing_fractions.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Reducing_fractions.md index 14114f2..4f6c380 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Reducing_fractions.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Reducing_fractions.md @@ -91,7 +91,7 @@ A better method is to utilise [prime factorization](Prime%20factorization.md) combined with the canceling technique. First we find the prime factors of both the numerator and denominator: -![drawio-Page-7.drawio.png](/static/drawio-Page-7.drawio.png) +![drawio-Page-7.drawio.png](static/drawio-Page-7.drawio.png) This gives us: @@ -161,7 +161,7 @@ _Reduce the following fraction to its lowest terms: $$\frac{14y^5}{-35y^3}$$_ - Apply [Prime factorization](Prime%20factorization.md): - ![draw.io-Page-8.drawio.png](/static/draw.io-Page-8.drawio.png) + ![draw.io-Page-8.drawio.png](static/draw.io-Page-8.drawio.png) - Cancel the coefficients and variable parts @@ -177,7 +177,7 @@ $$\frac{- 12xy^2}{ - 18xy^2}$$_ - Apply [Prime factorization](Prime%20factorization.md): -![draw.io-Page-8.drawio 1.png](/static/draw.io-Page-8.drawio%201.png) +![draw.io-Page-8.drawio 1.png](static/draw.io-Page-8.drawio%201.png) - Cancel the coefficients and variable parts diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Register_and_cache_memory.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Register_and_cache_memory.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Register_and_cache_memory.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Register_and_cache_memory.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Regular_expressions_in_SQL.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Regular_expressions_in_SQL.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Regular_expressions_in_SQL.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Regular_expressions_in_SQL.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Reiteration.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Reiteration.md similarity index 92% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Reiteration.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Reiteration.md index 6563d7b..d6839d2 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Reiteration.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Reiteration.md @@ -11,4 +11,4 @@ within the main proof or a more deeply nested sub-proof. Reiteration allows us to reuse any assumptions, or propositions derived from assumptions, without having to introduce a new dependency with another assumption. -![](/static/reiteration.png) +![](static/reiteration.png) diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Relation_between_kernel_and_CPU.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Relation_between_kernel_and_CPU.md similarity index 98% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Relation_between_kernel_and_CPU.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Relation_between_kernel_and_CPU.md index 006a58e..f270e36 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Relation_between_kernel_and_CPU.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Relation_between_kernel_and_CPU.md @@ -25,7 +25,7 @@ is the first instruction that the CPU fetches and this is what allows the kernel to play its mediatory role. However most of the fetch, decode, execute cycles of the CPU take place independently of the kernel. -![](/static/kernel-cpu-interaction.svg) +![](static/kernel-cpu-interaction.svg) > Fetch decode and execute refer to processor pipeline stages. They occur > automatically as part of normal processor operation, the kernel doesn’t diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Relational_database_architecture.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Relational_database_architecture.md similarity index 94% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Relational_database_architecture.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Relational_database_architecture.md index 4bad1d1..bd14a36 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Relational_database_architecture.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Relational_database_architecture.md @@ -7,7 +7,7 @@ tags: Tables, fields and records are the basic building blocks of databases -![](/static/FL-Databases-1.5_terminology.gif) +![](static/FL-Databases-1.5_terminology.gif) ## Table diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Relays.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Relays.md similarity index 96% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Relays.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Relays.md index 5472a23..7348dd2 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Relays.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Relays.md @@ -23,7 +23,7 @@ circuit can be used the trigger the operation of another circuit. ## Operation -![Operation of a relay](/static/relay.gif) +![Operation of a relay](static/relay.gif) Current flows through the electromagnet which creates a magnetic field. This field attracts the armature which then moves to open or close the contacts. When diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Remote_tracking_branches.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Remote_tracking_branches.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Remote_tracking_branches.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Remote_tracking_branches.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Rename_a_branch.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Rename_a_branch.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Rename_a_branch.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Rename_a_branch.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Reset_to_remote_version.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Reset_to_remote_version.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Reset_to_remote_version.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Reset_to_remote_version.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Resistance.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Resistance.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Resistance.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Resistance.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Restructure_URLs_lambda.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Restructure_URLs_lambda.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Restructure_URLs_lambda.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Restructure_URLs_lambda.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Retrieve_data_from_SQL_table.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Retrieve_data_from_SQL_table.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Retrieve_data_from_SQL_table.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Retrieve_data_from_SQL_table.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Role_of_memory_in_computation.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Role_of_memory_in_computation.md similarity index 96% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Role_of_memory_in_computation.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Role_of_memory_in_computation.md index 695bf52..4b198c9 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Role_of_memory_in_computation.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Role_of_memory_in_computation.md @@ -24,7 +24,7 @@ has completed and the OS kernel is itself loaded into memory. > sends to the CPU not just the first instruction in the requested file but also > a number of instructions that immediately follow it. -![Memory flow diagram](/static/memory-flow.svg) +![Memory flow diagram](static/memory-flow.svg) Every part of the above process - the journey accross the bus, the lookup in the controller, the operations on the DRAM, the journey back accross the bus - takes diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Role_of_unique_key_in_relational_databases.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Role_of_unique_key_in_relational_databases.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Role_of_unique_key_in_relational_databases.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Role_of_unique_key_in_relational_databases.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Routing_on_link_click_in_React.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Routing_on_link_click_in_React.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Routing_on_link_click_in_React.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Routing_on_link_click_in_React.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Rules_for_operations_on_like_and_unlike_terms.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Rules_for_operations_on_like_and_unlike_terms.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Rules_for_operations_on_like_and_unlike_terms.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Rules_for_operations_on_like_and_unlike_terms.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/S3.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/S3.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/S3.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/S3.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/SAM.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/SAM.md similarity index 96% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/SAM.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/SAM.md index 2bd6652..cfdd845 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/SAM.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/SAM.md @@ -57,7 +57,7 @@ Default output format [None]: This information can be found in the Security Credentials section of the given [IAM](zk/AWS_User_management_and_roles.md#iam) user: -![](/static/access-key-aws.png) +![](static/access-key-aws.png) ### Switching between credentials @@ -147,7 +147,7 @@ the Lambda. The full template is below: -![](/static/sam-template-yaml.png) +![](static/sam-template-yaml.png) ## Adding our own code @@ -206,7 +206,7 @@ exports.clock = async (event) => { The directory structure is as follows: -![](/static/sam-directory.png) +![](static/sam-directory.png) When we call the API Gateway path `/clock` with `GET`, our function will be triggered. @@ -227,7 +227,7 @@ We need to install the runtime dependencies for the function. We do this by running `sam build`. This ignores test files and development dependencies and installs the project dependencies and source files to a temporary subdirectory. -![](/static/sam-build.png) +![](static/sam-build.png) The build directory is `.aws-sam/build/`. There will be a subdirectory for each of our files. @@ -242,7 +242,7 @@ The packaging proces will first archive all of the project artefacts into a zip file and then upload that to [S3](zk/AWS_S3.md). A reference to this S3 entity is then provided to CloudFormation. -![](/static/s3-package-again.svg) +![](static/s3-package-again.svg) The command is as follows: @@ -271,15 +271,15 @@ CloudFormation. In CloudFormation each individual project is called a **stack**. If we then go to Cloud Formation we will see the deployed application. -![](/static/cloud-formation-stack.png) +![](static/cloud-formation-stack.png) ## Call the endpoint If we now go to the Lambda console, we will see our function listed, and the API Gateway endpoint under `triggers`: -![](/static/gateway-trigger.png) +![](static/gateway-trigger.png) We can then call this from Postman to check everything is working as it should: -![](/static/postman-aws-output.png) +![](static/postman-aws-output.png) diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Save_readonly_Vim_file.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Save_readonly_Vim_file.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Save_readonly_Vim_file.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Save_readonly_Vim_file.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Schema_Definition_Language_in_GraphQL.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Schema_Definition_Language_in_GraphQL.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Schema_Definition_Language_in_GraphQL.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Schema_Definition_Language_in_GraphQL.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Secrets_or_env_vars_in_AWS.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Secrets_or_env_vars_in_AWS.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Secrets_or_env_vars_in_AWS.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Secrets_or_env_vars_in_AWS.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Semantic_versioning.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Semantic_versioning.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Semantic_versioning.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Semantic_versioning.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Set_DNS_settings.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Set_DNS_settings.md similarity index 92% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Set_DNS_settings.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Set_DNS_settings.md index 44e94ba..e7869e4 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Set_DNS_settings.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Set_DNS_settings.md @@ -65,5 +65,5 @@ nameserver fded:2060:8671:0:681:9bff:fe9b:37f0 ## Related notes -![Network scanning](/static/Network_scanning.md) -![Network debugging](/static/Network_debugging.md) +![Network scanning](static/Network_scanning.md) +![Network debugging](static/Network_debugging.md) diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Sets_in_Python.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Sets_in_Python.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Sets_in_Python.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Sets_in_Python.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Setting_up_and_configuring_TypeScript.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Setting_up_and_configuring_TypeScript.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Setting_up_and_configuring_TypeScript.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Setting_up_and_configuring_TypeScript.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Shell_sessions.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Shell_sessions.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Shell_sessions.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Shell_sessions.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Signed_and_unsigned_numbers.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Signed_and_unsigned_numbers.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Signed_and_unsigned_numbers.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Signed_and_unsigned_numbers.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Signed_magnitude_representation.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Signed_magnitude_representation.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Signed_magnitude_representation.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Signed_magnitude_representation.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Single_file_Python_scripts.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Single_file_Python_scripts.md similarity index 92% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Single_file_Python_scripts.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Single_file_Python_scripts.md index 11a0a64..061c1f2 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Single_file_Python_scripts.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Single_file_Python_scripts.md @@ -41,4 +41,4 @@ if __name__ == "__main__": ## Related notes -![Python modules and imports](/static/Python_modules_and_imports.md) +![Python modules and imports](static/Python_modules_and_imports.md) diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Singleton_pattern.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Singleton_pattern.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Singleton_pattern.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Singleton_pattern.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Sliding_window.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Sliding_window.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Sliding_window.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Sliding_window.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Solving_equations.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Solving_equations.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Solving_equations.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Solving_equations.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Sorting_lists_in_Python.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Sorting_lists_in_Python.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Sorting_lists_in_Python.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Sorting_lists_in_Python.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Soundness.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Soundness.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Soundness.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Soundness.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Split_into_array_in_Bash.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Split_into_array_in_Bash.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Split_into_array_in_Bash.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Split_into_array_in_Bash.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Stack_memory.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Stack_memory.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Stack_memory.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Stack_memory.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Stacks.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Stacks.md similarity index 96% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Stacks.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Stacks.md index 243b6d3..9d2b337 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Stacks.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Stacks.md @@ -3,9 +3,9 @@ tags: - data-structures --- -_A stack visualised vertically_ ![stack2.svg](/static/stack2.svg) +_A stack visualised vertically_ ![stack2.svg](static/stack2.svg) -_A stack visualised horizontally_ ![stack1.svg](/static/stack1.svg) +_A stack visualised horizontally_ ![stack1.svg](static/stack1.svg) ## A stack is a linear data structure that observes LIFO diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Stale_branches_and_pruning.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Stale_branches_and_pruning.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Stale_branches_and_pruning.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Stale_branches_and_pruning.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Step_functions_and_state_machines.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Step_functions_and_state_machines.md similarity index 95% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Step_functions_and_state_machines.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Step_functions_and_state_machines.md index 0067337..99351a8 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Step_functions_and_state_machines.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Step_functions_and_state_machines.md @@ -38,11 +38,11 @@ The diagram below shows the definition of a given state machine. On the left is the JSON specification. On the right is a diagramatic representation that shows the control flow and all possible steps that comprise a given pathway / state: -![](/static/state-machine-definition.png) +![](static/state-machine-definition.png) For each execution of the state machine (each time it is triggered) you can review the runtime. The flow diagram will highlight green to show the given pathway, and you can also see the inputs and outputs for each step and any errors: -![](/static/state-machine-execution.png) +![](static/state-machine-execution.png) diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Strategies_for_constructing_proofs.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Strategies_for_constructing_proofs.md similarity index 97% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Strategies_for_constructing_proofs.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Strategies_for_constructing_proofs.md index 118f2e1..8dc9f6c 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Strategies_for_constructing_proofs.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Strategies_for_constructing_proofs.md @@ -58,7 +58,7 @@ in the first conjunct. We can get this simply but applying So far we have: -![](/static/step1.png) +![](static/step1.png) Now we just need to get $D$ from the proposition at line 3. This is easy since we already have access to the consequent of the biconditional at line 1. @@ -66,7 +66,7 @@ Therefore we can apply [Biconditional Elimination](Biconditional_Elimination.md)) at line 3 to get $D$. We are now halfway there: -![](/static/step2.png) +![](static/step2.png) Next we need to turn our attention to deriving $L \lor A$. How can we obtain $L$ ? Well it is contained within the first conjunct of the assumption on line 2. @@ -77,7 +77,7 @@ $\lnot N$ as an assumption on the first line, so we can use [Conditional Elimination](Conditional_Elimination.md) to derive $L$. These two steps give us: -![](/static/step3.png) +![](static/step3.png) Now we need to get from $L$ to $L \lor A$. This is really straightforward because by using @@ -87,7 +87,7 @@ constituent parts of the conjunction that is the conclusion, we can combine them with [Conjunction Introduction](Conjunction_Introduction.md) as we had planned at the outset. -![](/static/step4.png) +![](static/step4.png) ### A further example @@ -109,7 +109,7 @@ approach is therefore to seek to derive the antecedent ($\lnot L$) and then use [Biconditional Elimination](Biconditional_Elimination.md) to extract the target sentence which is the consequent. -![proof.png](/static/proof.png) +![proof.png](static/proof.png) ## Proving theorems @@ -127,13 +127,13 @@ Our strategy here is to identify the main connective in the proposition we want to derive (the material conditional). We then assume the antecedent and attempt to derive the consequent from it. -![](/static/theoremproof.png) +![](static/theoremproof.png) ## A complex theorem proof _Prove_ $\vdash (\lnot A \lor \lnot B) \leftrightarrow \lnot(A \land B)$ -![](/static/dsfdsfsdfwe.png) +![](static/dsfdsfsdfwe.png) ### Walkthrough diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Streams_in_NodeJS.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Streams_in_NodeJS.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Streams_in_NodeJS.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Streams_in_NodeJS.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Strings_in_Bash.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Strings_in_Bash.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Strings_in_Bash.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Strings_in_Bash.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Strings_in_Python.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Strings_in_Python.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Strings_in_Python.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Strings_in_Python.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Structuring_Express_applications.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Structuring_Express_applications.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Structuring_Express_applications.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Structuring_Express_applications.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Substrings_in_Bash.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Substrings_in_Bash.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Substrings_in_Bash.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Substrings_in_Bash.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Swap_space.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Swap_space.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Swap_space.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Swap_space.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Switch_between_Python_vers.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Switch_between_Python_vers.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Switch_between_Python_vers.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Switch_between_Python_vers.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Syllogism.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Syllogism.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Syllogism.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Syllogism.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Symlinks.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Symlinks.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Symlinks.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Symlinks.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Syntax_of_propositional_logic.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Syntax_of_propositional_logic.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Syntax_of_propositional_logic.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Syntax_of_propositional_logic.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Tags_in_Git.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Tags_in_Git.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Tags_in_Git.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Tags_in_Git.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Test_values_in_Bash.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Test_values_in_Bash.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Test_values_in_Bash.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Test_values_in_Bash.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Testing_Python_code.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Testing_Python_code.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Testing_Python_code.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Testing_Python_code.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Testing_with_Jest.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Testing_with_Jest.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Testing_with_Jest.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Testing_with_Jest.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Text_manipulation_in_Bash.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Text_manipulation_in_Bash.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Text_manipulation_in_Bash.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Text_manipulation_in_Bash.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/The_History_of_Computing_Swade.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/The_History_of_Computing_Swade.md similarity index 94% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/The_History_of_Computing_Swade.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/The_History_of_Computing_Swade.md index 7f94e68..bd5ee5e 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/The_History_of_Computing_Swade.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/The_History_of_Computing_Swade.md @@ -52,9 +52,9 @@ First three phases of digital electronic computers: Focus was chiefly on creating a desktop calculator capable of four-function arithmetic. -![Photograph of Pascaline](/static/pascaline.jpg) +![Photograph of Pascaline](static/pascaline.jpg) -![Photograph of replica of Leibniz stepped drum machine](/static/leibniz-stepped-drum.jpg) +![Photograph of replica of Leibniz stepped drum machine](static/leibniz-stepped-drum.jpg) The main contenders were the Pascaline of #Pascal (which only did cumulative addition) and the wheel or "stepped drum" calculator of #Leibniz that could do @@ -63,9 +63,9 @@ all operations (in theory). Subsequent designs were based on these artefacts. In practice, neither worked consistently well with the carriage of tens remaining a sticking point. -![Photograph of Arithmometer](/static/arithmometer.jpg) +![Photograph of Arithmometer](static/arithmometer.jpg) -![Photograph of Comptometer](/static/comptometer.png) +![Photograph of Comptometer](static/comptometer.png) The arithmometer (crank driven) and comptometer (key-driven) were descendents of the Leibniz design that became commercially viable by the 19th century along @@ -148,7 +148,7 @@ This used fluid to model the workings of the British economy. It consisted of a series of transparent plastic tanks and pipes which were fastened to a wooden board. -![Philips Hydraulic Computer](/static/hydraulic_computer.jpg) +![Philips Hydraulic Computer](static/hydraulic_computer.jpg) Each tank represented some aspect of the UK national economy and the flow of money around the economy was illustrated by coloured water. At the top of the @@ -165,7 +165,7 @@ the Philips Computer it was general enough to be used to solve problems from different contexts. Examples of these contexts: heat flow, ballistics, mechanics, population growth, chemical interactions, astronomy. -![Differential Analyser](/static/differential_analyser_bush.jpg) +![Differential Analyser](static/differential_analyser_bush.jpg) It was about the size of a room and used shafts, motors, discs and wheels to work. @@ -211,7 +211,7 @@ _Automatic Sequence Controlled Calculator_ (ASCC). A general-purpose electro-mechanical computer it was most famously used at Los Alamos by #vonNeumann to calculate the blast yield of the atomic bomb. -![Harvard Mark One](/static/Harvard_Mark_1.jpg) +![Harvard Mark One](static/Harvard_Mark_1.jpg) It was more than 15m in length and weighed 5 tonnes comprising over 750,000 parts. It used paper tape and punched cards for input/output. @@ -223,9 +223,9 @@ specific set of operations on numbers and nothing else. It used relays like the others. Its distinguishing feature was that it used a teletype for input rather than cards or paper tape. -![Calculating panel of the CMC](/static/complex-number-calculator-bell-labs.jpg) +![Calculating panel of the CMC](static/complex-number-calculator-bell-labs.jpg) -![Teletype input of CMC](/static/stibitz-teletype.jpg) +![Teletype input of CMC](static/stibitz-teletype.jpg) It comprised a panel (the calculating unit) and teletype (the input). One could remotely access the computer from the teletype in another location, providing it @@ -233,7 +233,7 @@ was connected to Bell Lab's telephone network. #### Z3 (1941) - Konrad Zuse -![Z3](/static/Zuse-Z3.jpeg) +![Z3](static/Zuse-Z3.jpeg) First designed in 1938 and completed in 1941. Considered the first fully automatic, programmable digital computer although relay-based. Programs were @@ -251,7 +251,7 @@ famously, the ENIAC. ### The Antanasoff-Berry Computer (1939 - 1942) -![ABC Computer](/static/abc-computer.jpg) +![ABC Computer](static/abc-computer.jpg) Fully automatic, digital electronic computer but not programmable or really general-purpose, being created to do linear equations. It took decimal input and @@ -294,7 +294,7 @@ myriad factors: gun elevation, shell shape and weight, explosive charge, distance, wind, temperature etc. Previously this had been done by human computers under the aegis of the Ballistic Research Laboratory. -![The main control panel of the ENIAC](/static/eniac.jpg) +![The main control panel of the ENIAC](static/eniac.jpg) It was not completed until after VE day but was used at Los Alamos after the War and retired in 1955. @@ -378,7 +378,7 @@ variety of different electronic methods for memory: #### Manchester Baby (1948) -![The Manchester Baby Computer](/static/manchester_baby.png) +![The Manchester Baby Computer](static/manchester_baby.png) - An experimental computer intended to create the [von Neumann architecture](CPU_architecture.md) using @@ -391,7 +391,7 @@ variety of different electronic methods for memory: #### EDSAC (1949) J.Wilkes et al. -![EDSAC](/static/EDSAC.jpg) +![EDSAC](static/EDSAC.jpg) - _Electronic Delay Storge Automatic Computer_ @@ -413,7 +413,7 @@ variety of different electronic methods for memory: operations) - diagnostics: techniques for verifying program code and its correctness -![Programming Digital Electronic Computer book](/static/programming_a_digital_electronic_computter.jpg) +![Programming Digital Electronic Computer book](static/programming_a_digital_electronic_computter.jpg) - The key players wrote the first textbook on programming in 1951: _The Preparation of Programs for an Electronic Digital Computer_ (Wilkes, Wheeler, @@ -437,7 +437,7 @@ variety of different electronic methods for memory: - Turing proposed a stored program architecture with high-speed memory. It would be more perfomant than the EDVAC as a result. -![The Pilot ACE computer](/static/pilot-ace.jpg) +![The Pilot ACE computer](static/pilot-ace.jpg) - Turing's actual design was not implemented as it was thought too ambitious given how powerful it would need to be. Instead a smaller prototype was made, @@ -456,7 +456,7 @@ variety of different electronic methods for memory: ### IAS machines -![The MANIAC computer](/static/MANIAC_computer.jpg) +![The MANIAC computer](static/MANIAC_computer.jpg) Several machines were built at the Institute for Advanced Study utilising the "von Neumann" architecture and associated advancements such as vacuum-tubes and @@ -468,7 +468,7 @@ widely studied making them influential outside of academia. ### UNIVAC (1951) -![UNIVAC_computer](/static/univac-1.jpg) +![UNIVAC_computer](static/univac-1.jpg) Mauchley and Eckert, who had designed the ENIAC left the Moore School and went into business: Eckert-Mauchley Computer Corporation. This was bought by @@ -483,7 +483,7 @@ multiple means of input/output including: directly via an operator console (basically a typewriter keyboard), magnetic tape for input and output, along with punched cards. -![UNIVAC operator console](/static/univac-operator-console.jpeg) +![UNIVAC operator console](static/univac-operator-console.jpeg) It was the first computer specifically designed to include business and administrative use. This was underscored by its first client: the US Census @@ -526,7 +526,7 @@ computer industry with the UNIVAC. ### IBM 701 ("Defense Calculator") (1952) -![Control unit of the IBM 701](/static/ibm-701-control-unit.jpeg) +![Control unit of the IBM 701](static/ibm-701-control-unit.jpeg) IBM's first electronic computer. It directly competed with the UNIVAC for government contracts. It followed the prevailing approach of vaccuum tubes for @@ -538,14 +538,14 @@ manage payroll in business contexts. ### IBM 702 ("Tape Processing Machine") (1953) -![Advertisement for the IBM 702](/static/ibm-add.jpeg) +![Advertisement for the IBM 702](static/ibm-add.jpeg) Focused primarily on business applications and targetted at businesses rather than government contracts. Less powerful than the 701. ### IBM 650 (1953) -![IBM 650](/static/ibm-650.jpg) +![IBM 650](static/ibm-650.jpg) Low-cost general purpose machine using magnetic drum memory. Marketed as slower but more affordable than the 700 range. It was mass-produced unlike the others @@ -553,7 +553,7 @@ which were built for specific customers. It was in fact the first mass-produced computer in the world. It proved the breakout star in IBMs initial line up and sometimes called "IBM's Model T". -![IBM_650 console panel](/static/ibm-650-console-panel.jpg) +![IBM_650 console panel](static/ibm-650-console-panel.jpg) IBM offerred 650s to univesities at a 60% discount on the condition that the universities would establish courses in computing. This was shrewd as it meant @@ -568,7 +568,7 @@ vacuum-tubes. ### IBM 1401 (1959) -![IBM 1401](/static/ibm-1401.jpg) +![IBM 1401](static/ibm-1401.jpg) Another IBM mainframe. Transistors replaced vacuum-tubes. Magnetic core storage replaced magnetic drum storage. It was housed in rectangular light-blue cabinets @@ -576,7 +576,7 @@ and the ubiquity of the 1401 in industry earned IBM the moniker 'Big Blue'. ### IBM System/360 (1964) -![IBM 360](/static/ibm-360.jpg) +![IBM 360](static/ibm-360.jpg) Named to suggest all-round compatibility - a family of mainframes designed to cover commercial and scientific applications. Considered one of history's most @@ -586,7 +586,7 @@ Up until this point all IBM computers had a programming language unique to the specific processor. At that point there were about seven IBM computer models in active use and they were all incompatible with each other. -![IBM 360 promo poster](/static/ibm-360-in-use.jpeg) +![IBM 360 promo poster](static/ibm-360-in-use.jpeg) In contrast the 360 computers all used the same programming language. This meant they were interoperable with each others. Because the there were variants in the @@ -599,7 +599,7 @@ Two devices that leveraged the new technology of [magnetic_core_memory](Magnetic_core_memory.md) where the Whirlwind and SAGE computers. The ENIAC was also updated to use magnetic cores. -![Whirlwind magnetic core memory](/static/whirlwind-magnetic-cores.JPG) +![Whirlwind magnetic core memory](static/whirlwind-magnetic-cores.JPG) The Whirlwind computer (1953) was a flight simulator and the first to use magnetic cores. Crucially was able to operate in realtime for output. @@ -618,7 +618,7 @@ The resulting computer was SAGE (made by IBM) which was modelled on Whirlwind, using magnetic cores. SAGE computers were spread accross the continental US in sectors and managed by NORAD. -![SAGE command post](/static/SAGE_command_post.jpg) +![SAGE command post](static/SAGE_command_post.jpg) The SAGE system was operation between 1958-1984, receiving continual improvements and updates. In addition to magnetic cores it introduced many @@ -676,7 +676,7 @@ mid-1960s. The introduced the PDP-8 in 1965 (Programmed Data Processor). The PDP-8 used transisotrs and magnetic core memory. It was affordable to smaller businesses if not yet, consumers. -![The PDP-8](/static/540px-PDP-8_(1).jpg>) +![The PDP-8](static/540px-PDP-8_(1).jpg>) The internals were made public and DEC encouraged making the machine extensible by users being permitted to create their own programs and specialised @@ -702,7 +702,7 @@ the Intel 4004 - was the microprocessor combined with three other ICs (comprising 2.3k transistors) that comprised the fundamental building blocks of the #vonNeumann architecture. -![Intel 4004 chip](/static/intel-4004.jpg) +![Intel 4004 chip](static/intel-4004.jpg) However it took until the Apple II in 1977 for the phrase "personal computer" to enter the lexicon and become an identifiable class. @@ -719,7 +719,7 @@ required manual assembly. It was released by Micro Instrumentation Telemetry Systems (MITS) in 1975. It couldn't do much but had expansion capability (memory, teletype interface, casette player for data storage). -![Altair 8800](/static/altair-8800.jpg) +![Altair 8800](static/altair-8800.jpg) Bill Gates and Paul Allen made a proposal to MITS: they would write software that would allow users to program the Altair in BASIC. They agreed and were @@ -730,7 +730,7 @@ Around the same time, Steve Wozniak (member of the Homebrew club) built the Apple I as a single-board hobbyist project. He made this available to buy via mail order and formed Apple with Steve Jobs in 1976 to manage the enterprise. -![Apple I](/static/apple1.jpg) +![Apple I](static/apple1.jpg) By 1977 they had investment capital and brought out the Apple II. This was sold preassembled with casing and required no soldering. It had expansion slots for @@ -742,7 +742,7 @@ allowed it to run the CP/M OS (created by the company Digital Research) giving ready-made access to software such as a word-processor, spreadsheets and databases. -![Apple 2](/static/apple2.jpg) +![Apple 2](static/apple2.jpg) Other competitors in the PC market at this time were Radioshack's TRS-80 and the Commodore PET. @@ -754,7 +754,7 @@ real interest. When PCSs started being used by businesses and their capacity grew to include typical business applications (databases, spreadsheets) it sensed an incursion into its market. -![IBM PC](/static/ibm-pc.jpg) +![IBM PC](static/ibm-pc.jpg) Thus, in 1981, IBM launched the "IBM Personal Computer" which rapidly became the industry standard. This had the effect of legitimising the concept of a PC. diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/The_Little_Man_computer.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/The_Little_Man_computer.md similarity index 97% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/The_Little_Man_computer.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/The_Little_Man_computer.md index 06e1f15..3283442 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/The_Little_Man_computer.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/The_Little_Man_computer.md @@ -9,7 +9,7 @@ principles. It has all the CPU components we have detailed above. It is programmed in machine code but for simplicity it uses the denary rather than the binary number system. -![LMC_5.gif](/static/LMC_5.gif) +![LMC_5.gif](static/LMC_5.gif) On the left is the instruction set. Each number constitutes and execution routine and the `xx` stand for the address in RAM that the execution will work diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/The_PATH.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/The_PATH.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/The_PATH.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/The_PATH.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/The_Pragmatic_Programmer_1999.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/The_Pragmatic_Programmer_1999.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/The_Pragmatic_Programmer_1999.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/The_Pragmatic_Programmer_1999.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/The_kernel.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/The_kernel.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/The_kernel.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/The_kernel.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/The_memory_hierarchy.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/The_memory_hierarchy.md similarity index 78% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/The_memory_hierarchy.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/The_memory_hierarchy.md index 4122566..9d7c553 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/The_memory_hierarchy.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/The_memory_hierarchy.md @@ -8,4 +8,4 @@ created: Friday, July 12, 2024 The diagram below compares the different forms of memory within a computing device in terms of speed, monetary cost and capacity: -![Memory hierarchy diagram](/static/Memory-Hierarchy.jpg) +![Memory hierarchy diagram](static/Memory-Hierarchy.jpg) diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Theorems_and_empty_sets.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Theorems_and_empty_sets.md similarity index 95% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Theorems_and_empty_sets.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Theorems_and_empty_sets.md index bdcb2e0..46af6b6 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Theorems_and_empty_sets.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Theorems_and_empty_sets.md @@ -14,7 +14,7 @@ the case that the starting set contains members. The set can in fact be empty. _Demonstration_ -![](/static/proofs-drawio-Page-5.drawio_2.png) +![](static/proofs-drawio-Page-5.drawio_2.png) We see in this example that there is no starting set and thus no primary assumptions. Instead we start with nothing other than the proposition we wish to diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Threads.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Threads.md similarity index 91% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Threads.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Threads.md index 97235ad..b8bb449 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Threads.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Threads.md @@ -6,7 +6,7 @@ created: Wednesday, June 26, 2024 # Threads -A ![process](/static/Processes.md) is a running instance of a given program. A program +A ![process](static/Processes.md) is a running instance of a given program. A program runs sequentially handling one task at a time, however we may need to run certain tasks in parallel. @@ -39,4 +39,4 @@ by the process that the thread belongs to. ## Related notes -![Processes](/static/Processes.md) +![Processes](static/Processes.md) diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Three_bit_counter.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Three_bit_counter.md similarity index 98% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Three_bit_counter.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Three_bit_counter.md index 8c12efb..85c42af 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Three_bit_counter.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Three_bit_counter.md @@ -58,7 +58,7 @@ since the only state change we need is a single bit toggle three times that retains its value. Using these pulse patterns we can construct a circuit as follows: -![](/static/3-bit-adder-diagram.png) +![](static/3-bit-adder-diagram.png) diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Time_and_computers.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Time_and_computers.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Time_and_computers.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Time_and_computers.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Torrenting.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Torrenting.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Torrenting.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Torrenting.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Transistors.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Transistors.md similarity index 96% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Transistors.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Transistors.md index 1c0bbca..3bf1498 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Transistors.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Transistors.md @@ -21,7 +21,7 @@ represented by [voltage](Voltage.md) values within set parameters. There are different types of transistors but the simplest for the purposes of explanation are **bipolar junction transistors**. -![BJT transistor terminals](/static/bjt-terminals.jpg) +![BJT transistor terminals](static/bjt-terminals.jpg) The pins: @@ -57,6 +57,6 @@ emitter of the other. If either voltage input is low then the voltage of the combined line is low (equivalent to the circuit being broken) and there is no current flowing. -![](/static/and-transistor.png) +![](static/and-transistor.png) // Add example of OR gate created with transistors diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Transport_Layer_of_Internet_Protocol.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Transport_Layer_of_Internet_Protocol.md similarity index 97% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Transport_Layer_of_Internet_Protocol.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Transport_Layer_of_Internet_Protocol.md index c57f185..e087bb3 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Transport_Layer_of_Internet_Protocol.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Transport_Layer_of_Internet_Protocol.md @@ -18,7 +18,7 @@ Protocol** (TCP). A TCP **fragment** fits within an IP packet's data section, giving us the following iteration of the network stack: -![Transport layer fragment](/static/transport-layer-segment.png) +![Transport layer fragment](static/transport-layer-segment.png) The segment header contains a destination network port number. The port number identifies the specific service or process on the host device which will receive diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Troubleshooting_MongoDB.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Troubleshooting_MongoDB.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Troubleshooting_MongoDB.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Troubleshooting_MongoDB.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Truth_functional_connectives.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Truth_functional_connectives.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Truth_functional_connectives.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Truth_functional_connectives.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Truth_tables.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Truth_tables.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Truth_tables.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Truth_tables.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Truth_trees.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Truth_trees.md similarity index 93% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Truth_trees.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Truth_trees.md index 7bb6682..9ab73a3 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Truth_trees.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Truth_trees.md @@ -118,7 +118,7 @@ inconsistency in terms of truth trees: The following is a truth tree for the set ${P \lor Q, \sim P }$: -![basic-open-tree 1.svg](/static/basic-open-tree%201.svg) +![basic-open-tree 1.svg](static/basic-open-tree%201.svg) ### Interpretation @@ -163,7 +163,7 @@ not the right hand side. The following is a truth tree for the set ${A & \sim B, C, \sim A \lor \sim B }$. -![basic-closed-tree 1.svg](/static/basic-closed-tree%201.svg) +![basic-closed-tree 1.svg](static/basic-closed-tree%201.svg) ### Interpretation @@ -203,19 +203,19 @@ of each of the main connectives and these rules rely on logical equivalences ### Negated negation decomposition: `~~D` -![negated-negation-decomposition-rule 2.svg](/static/negated-negation-decomposition-rule%202.svg) +![negated-negation-decomposition-rule 2.svg](static/negated-negation-decomposition-rule%202.svg) Truth passes only if $P$ is true ### Conjunction decomposition: `&D` -![conjunction-decomposition-rule.svg](/static/conjunction-decomposition-rule.svg) +![conjunction-decomposition-rule.svg](static/conjunction-decomposition-rule.svg) Truth passes only $P$ and $Q$ are both true. ### Negated Conjunction decomposition: `~&D` -![negated-conjunction-decomposition-rule.svg](/static/negated-conjunction-decomposition-rule.svg) +![negated-conjunction-decomposition-rule.svg](static/negated-conjunction-decomposition-rule.svg) Truth passes if either $\sim P$ or $\sim Q$ is true. This rule is a consequence of the equivalence between $\sim (P & Q)$ and $\sim P \lor \sim Q$ , the first @@ -223,13 +223,13 @@ of DeMorgan’s Laws. ### Disjunction decomposition: `vD` -![disjunction-decomposition-rule.svg](/static/disjunction-decomposition-rule.svg) +![disjunction-decomposition-rule.svg](static/disjunction-decomposition-rule.svg) Truth passes if either $P$or $Q$ are true. ### Negated Disjunction decomposition: `~vD` -![negated-disjunction-decomposition-rule.svg](/static/negated-disjunction-decomposition-rule.svg) +![negated-disjunction-decomposition-rule.svg](static/negated-disjunction-decomposition-rule.svg) Truth passes if both $P$ and $Q$ are false. This rule is a consequence of the equivalence between $\sim (P \lor Q)$ and $\sim P & \sim Q$, the second of @@ -237,7 +237,7 @@ DeMorgan’s Laws. ### Conditional decomposition: `⊃D` -![conditional-decomposition-rule.svg](/static/conditional-decomposition-rule.svg) +![conditional-decomposition-rule.svg](static/conditional-decomposition-rule.svg) Truth passes if either $\sim P$ or $Q$ are true. This rule is a consequence of the equivalence between $P \supset Q$ and $\sim P \lor Q$ therefore this branch @@ -248,11 +248,11 @@ has the shape of a disjunction with $\sim P$ , $Q$ as its disjuncts. Truth passes if both $P$ and $\sim Q$ are true. This is a consequence of the equivalence between $\sim (P \supset Q)$ and $P & \sim Q$. -![negated-conditional-decomposition-rule.svg](/static/negated-conditional-decomposition-rule.svg) +![negated-conditional-decomposition-rule.svg](static/negated-conditional-decomposition-rule.svg) ### Biconditional decomposition: `≡D` -![biconditional-decomposition-rule.drawio(1).svg](/static/biconditional-decomposition-rule.drawio%281%29.svg) +![biconditional-decomposition-rule.drawio(1).svg](static/biconditional-decomposition-rule.drawio%281%29.svg) Truth passes if either $P$ and $Q$ are true or $\sim P & \sim Q$ are true. This is an interesting rule because it combines the disjunction and conjunction tree @@ -260,7 +260,7 @@ shapes. ### Negated biconditional decomposition: `~≡D` -![negated-biconditional-decomposition-rule.drawio.svg](/static/negated-biconditional-decomposition-rule.drawio.svg) +![negated-biconditional-decomposition-rule.drawio.svg](static/negated-biconditional-decomposition-rule.drawio.svg) Truth passes if either $P$ and $\sim Q$ is true or if $\sim P$ and $Q$ is true. @@ -281,7 +281,7 @@ following heuristic techniques followed in order, facilitate this: Here are some examples of these rules applied: -![complex-tree.svg](/static/complex-tree.svg) +![complex-tree.svg](static/complex-tree.svg) Observe that here we don’t bother to decompose the sentence on line 1. This is because, having decomposed the sentences on lines 2 and 3 we have arrived at a @@ -320,7 +320,7 @@ A logically false sentence cannot be true on any assignment. This is the same thing as an inconsistent set. Thus it will be represented in a truth tree as inconsistency which is disclosed via a closed tree. -![logical-falsity-tree.svg](/static/logical-falsity-tree.svg) +![logical-falsity-tree.svg](static/logical-falsity-tree.svg) ### Logical truth @@ -369,7 +369,7 @@ equivalent. > Sentences $P$ and $Q$ are truth-functionally equivalent if and only if the set > $\sim (P \equiv Q)$ has a closed tree -![logical-equivalence-tree.svg](/static/logical-equivalence-tree.svg) +![logical-equivalence-tree.svg](static/logical-equivalence-tree.svg) ### Logical entailment and validity diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Tuples_in_Python.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Tuples_in_Python.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Tuples_in_Python.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Tuples_in_Python.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Turing_completeness.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Turing_completeness.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Turing_completeness.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Turing_completeness.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Turing_machines.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Turing_machines.md similarity index 95% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Turing_machines.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Turing_machines.md index ac1d589..2f7c2a8 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Turing_machines.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Turing_machines.md @@ -20,7 +20,7 @@ of the tape is a head, which can either move left or right, and can read the symbols written in the cells. The head is also capable of erasing symbols and writing new symbols into the cells. -![Turing_machines_01.gif](/static/Turing_machines_01.gif) +![Turing_machines_01.gif](static/Turing_machines_01.gif) The direction that the head moves, which values it erases, and which values it writes in, are dependent on a set of instructions provided to the machine. diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Twos_complement.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Twos_complement.md similarity index 97% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Twos_complement.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Twos_complement.md index bfb486c..3d89de7 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Twos_complement.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Twos_complement.md @@ -38,12 +38,12 @@ To derive the complement of an unsigned number: `0` 2. Add one -![](/static/unsigned-to-signed.png) +![](static/unsigned-to-signed.png) To derive the unsigned equivalent of a signed number you invert the process but still make the smallest digit `1`: -![](/static/signed-to-unsigned.png) +![](static/signed-to-unsigned.png) ### Formal expression diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Type_guarding_and_narrowing_in_TS.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Type_guarding_and_narrowing_in_TS.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Type_guarding_and_narrowing_in_TS.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Type_guarding_and_narrowing_in_TS.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Type_hinting.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Type_hinting.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Type_hinting.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Type_hinting.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Union_types_in_TS.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Union_types_in_TS.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Union_types_in_TS.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Union_types_in_TS.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Unknown_type_in_TS.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Unknown_type_in_TS.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Unknown_type_in_TS.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Unknown_type_in_TS.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Untitled.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Untitled.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Untitled.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Untitled.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Update_a_Mongo_document.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Update_a_Mongo_document.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Update_a_Mongo_document.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Update_a_Mongo_document.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Update_an_SQL_table.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Update_an_SQL_table.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Update_an_SQL_table.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Update_an_SQL_table.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Update_existing_data_in_SQL_table.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Update_existing_data_in_SQL_table.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Update_existing_data_in_SQL_table.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Update_existing_data_in_SQL_table.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Useful_operators_in_SQL.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Useful_operators_in_SQL.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Useful_operators_in_SQL.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Useful_operators_in_SQL.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/User_Space.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/User_Space.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/User_Space.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/User_Space.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/User_management_in_Linux.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/User_management_in_Linux.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/User_management_in_Linux.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/User_management_in_Linux.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/User_management_on_AWS.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/User_management_on_AWS.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/User_management_on_AWS.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/User_management_on_AWS.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Using_GraphQL_with_Node.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Using_GraphQL_with_Node.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Using_GraphQL_with_Node.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Using_GraphQL_with_Node.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Using_arguments_with_Apollo_Client.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Using_arguments_with_Apollo_Client.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Using_arguments_with_Apollo_Client.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Using_arguments_with_Apollo_Client.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Utilities_operators_flags.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Utilities_operators_flags.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Utilities_operators_flags.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Utilities_operators_flags.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Validating_Mongoose_schemas.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Validating_Mongoose_schemas.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Validating_Mongoose_schemas.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Validating_Mongoose_schemas.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Validation_in_NodeJS.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Validation_in_NodeJS.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Validation_in_NodeJS.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Validation_in_NodeJS.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Validity_and_entailment.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Validity_and_entailment.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Validity_and_entailment.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Validity_and_entailment.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Variable_indirection_in_Bash.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Variable_indirection_in_Bash.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Variable_indirection_in_Bash.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Variable_indirection_in_Bash.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Variables_and_data_types_in_Bash.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Variables_and_data_types_in_Bash.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Variables_and_data_types_in_Bash.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Variables_and_data_types_in_Bash.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Variables_in_C.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Variables_in_C.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Variables_in_C.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Variables_in_C.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Viewing_remote_changes_without_merging.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Viewing_remote_changes_without_merging.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Viewing_remote_changes_without_merging.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Viewing_remote_changes_without_merging.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Views_in_relational_databases.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Views_in_relational_databases.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Views_in_relational_databases.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Views_in_relational_databases.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/VirtualMemory.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/VirtualMemory.md similarity index 98% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/VirtualMemory.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/VirtualMemory.md index 4c03462..03beb6f 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/VirtualMemory.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/VirtualMemory.md @@ -74,4 +74,4 @@ superset of all available virtual memory. It can access user space virtual memory because it sets up the tables and locations, not because it is a subset of its own virtual memory. -![Virtual memory diagram](/static/virtual-memory-diagram.jpg) +![Virtual memory diagram](static/virtual-memory-diagram.jpg) diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Virtual_private_cloud.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Virtual_private_cloud.md similarity index 96% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Virtual_private_cloud.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Virtual_private_cloud.md index 0219c6b..9181bd7 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Virtual_private_cloud.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Virtual_private_cloud.md @@ -17,7 +17,7 @@ are to remain isolated from the internet. The diagram below details a basic VPC configuration: -![](/static/aws-vpc-example.png) +![](static/aws-vpc-example.png) - Within a given AWS region we have created a VPC network. - This comprises public and private subnets diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Voltage.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Voltage.md similarity index 99% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Voltage.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Voltage.md index a8e62da..c8b4b1f 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Voltage.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Voltage.md @@ -88,7 +88,7 @@ Kirchoff's Voltage Law: The application of the Law is illustrated in the following diagram: -![](/static/voltage-drop.png) +![](static/voltage-drop.png) The explanation for the voltage drop at the positions $V^{A}$ and $V^{D}$ are obvious enough: they are at the beginning and end of the loop so are equal to diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Voltage_sources.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Voltage_sources.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Voltage_sources.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Voltage_sources.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/What_are_disks.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/What_are_disks.md similarity index 97% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/What_are_disks.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/What_are_disks.md index 3350399..1704137 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/What_are_disks.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/What_are_disks.md @@ -20,7 +20,7 @@ can write to and read from. The following diagram represents the basic anatomy of a disk device. -![](/static/harddisk.png) +![](static/harddisk.png) - A disk is divided up into [partitions](Partitions.md) which are subsections of the overall disk. The kernel presents each partition diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/What_is_memory.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/What_is_memory.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/What_is_memory.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/What_is_memory.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Whole_numbers.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Whole_numbers.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Whole_numbers.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Whole_numbers.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Why_computers_use_binary.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Why_computers_use_binary.md similarity index 96% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Why_computers_use_binary.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Why_computers_use_binary.md index a8c16ef..dbe80c8 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Why_computers_use_binary.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Why_computers_use_binary.md @@ -15,7 +15,7 @@ to represent two states: on (1) and off (0) which corresponds to the switch on an electrical circuit. A single circuit representing the binary values of 1 and 0: -![multi_on_off 1.gif](/static/multi_on_off.gif) +![multi_on_off 1.gif](static/multi_on_off.gif) It would be much more complicated to have to represent ten different states under the decimal number system, although denary computers do exist. @@ -25,7 +25,7 @@ represent as large a binary number as we need. We just need one switch for every digit we want to represent. The switches used in modern computers are so cheap and so small that billions can be fitted on a single circuit board. -![multiple_circuits.gif](/static/multiple_circuits.gif) +![multiple_circuits.gif](static/multiple_circuits.gif) When we use the term 'switch' we actually mean the transistor components of a circuit. We don't need to know the physical details at this level but we can say diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Wildcards_in_SQL.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Wildcards_in_SQL.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Wildcards_in_SQL.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Wildcards_in_SQL.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Williams_Tube_memory.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Williams_Tube_memory.md similarity index 83% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Williams_Tube_memory.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Williams_Tube_memory.md index a305cb5..8ff7ab9 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Williams_Tube_memory.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Williams_Tube_memory.md @@ -17,6 +17,6 @@ created: Tuesday, September 17, 2024 - Each dot position could be written to and read from and the pattern was constantly refreshed as the dots would fade over time. -![A Williams CRT tube](/static/williams-tube.jpg) +![A Williams CRT tube](static/williams-tube.jpg) -![Memory dot pattern from a Williams Tube](/static/williams-tube-dots.jpg) +![Memory dot pattern from a Williams Tube](static/williams-tube-dots.jpg) diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Working_with_CSVs_in_Python.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Working_with_CSVs_in_Python.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Working_with_CSVs_in_Python.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Working_with_CSVs_in_Python.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Working_with_JSON_in_Python.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Working_with_JSON_in_Python.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Working_with_JSON_in_Python.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Working_with_JSON_in_Python.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Working_with_numbers_in_Bash.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Working_with_numbers_in_Bash.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Working_with_numbers_in_Bash.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Working_with_numbers_in_Bash.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Zero_property_of_multiplication.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Zero_property_of_multiplication.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Zero_property_of_multiplication.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Zero_property_of_multiplication.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Zip_function_in_Python.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Zip_function_in_Python.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/Zip_function_in_Python.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/Zip_function_in_Python.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/fs.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/fs.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/fs.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/fs.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/head.html b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/head.html similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/head.html rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/head.html diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/http_in_Node.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/http_in_Node.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/http_in_Node.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/http_in_Node.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/index.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/index.md similarity index 97% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/index.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/index.md index fce261c..68e6d6e 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/index.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/index.md @@ -11,9 +11,9 @@ is a [Zettelkasten](https://en.wikipedia.org/wiki/Zettelkasten) work in progess comprising notes from my self-directed study of software engineering and computer science. -**Build ID:** d0ed26d0-cdc8-4643-8c09-445408195f9b +**Build ID:** 280992a4-57c0-4395-82a5-94bb2aefe389 -**Published:** Sat 19 Oct 2024 13:00:06 +**Published:** Sun 20 Oct 2024 19:49:39 ### Recent edits @@ -27,14 +27,8 @@ computer science. - [[Turing_machines]] -### All notes (463) +### All notes (462) -- [[0_Introduction]] -- [[1726814727_LUWV]] -- [[1_GET]] -- [[2_POST]] -- [[3_PUT]] -- [[5__Integrating_the_Mongo_database]] - [[API_Gateway]] - [[AWS_CLI]] - [[AWS_SAM_and_Docker]] @@ -124,6 +118,11 @@ computer science. - [[Creating_a_Docker_image]] - [[Creating_a_Linux_partition_table]] - [[Creating_a_Mongo_schema_and_model]] +- [[Creating_a_RESTful_API_GET]] +- [[Creating_a_RESTful_API_Integrating_the_Database]] +- [[Creating_a_RESTful_API_Introduction]] +- [[Creating_a_RESTful_API_POST]] +- [[Creating_a_RESTful_API_PUT]] - [[Creating_memory_with_NAND]] - [[Cron]] - [[Current]] diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/journald.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/journald.md similarity index 97% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/journald.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/journald.md index 5cabc09..e994cf6 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/journald.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/journald.md @@ -13,7 +13,7 @@ all [kernel](The_kernel.md) processes. It is invaluable when tracing the source of problems and errors that may arise on the system level. It keeps a track of all kernal processes. -![](/static/journald.png) +![](static/journald.png) ## `journalctl` diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/jq.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/jq.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/jq.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/jq.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/neuron.dhall b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/neuron.dhall similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/neuron.dhall rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/neuron.dhall diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/ps.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/ps.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/ps.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/ps.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/python_advent_learnings.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/python_advent_learnings.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/python_advent_learnings.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/python_advent_learnings.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/scrap.txt b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/scrap.txt similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/scrap.txt rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/scrap.txt diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/1.4-Input-Process-Output.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/1.4-Input-Process-Output.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/1.4-Input-Process-Output.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/1.4-Input-Process-Output.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/3-bit-adder-diagram.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/3-bit-adder-diagram.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/3-bit-adder-diagram.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/3-bit-adder-diagram.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/540px-PDP-8_(1).jpg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/540px-PDP-8_(1).jpg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/540px-PDP-8_(1).jpg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/540px-PDP-8_(1).jpg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/DMUX.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/DMUX.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/DMUX.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/DMUX.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/Domain _ Billing.pdf b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/Domain _ Billing.pdf similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/Domain _ Billing.pdf rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/Domain _ Billing.pdf diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/EDSAC.jpg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/EDSAC.jpg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/EDSAC.jpg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/EDSAC.jpg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/FL-Databases-1.5_terminology.gif b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/FL-Databases-1.5_terminology.gif similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/FL-Databases-1.5_terminology.gif rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/FL-Databases-1.5_terminology.gif diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/Harvard_Mark_1.jpg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/Harvard_Mark_1.jpg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/Harvard_Mark_1.jpg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/Harvard_Mark_1.jpg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/LMC_5.gif b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/LMC_5.gif similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/LMC_5.gif rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/LMC_5.gif diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/MANIAC_computer.jpg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/MANIAC_computer.jpg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/MANIAC_computer.jpg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/MANIAC_computer.jpg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/MUX.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/MUX.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/MUX.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/MUX.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/Memory-Hierarchy.jpg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/Memory-Hierarchy.jpg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/Memory-Hierarchy.jpg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/Memory-Hierarchy.jpg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/ORelim1.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/ORelim1.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/ORelim1.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/ORelim1.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/ORelim2.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/ORelim2.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/ORelim2.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/ORelim2.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/OS-api.svg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/OS-api.svg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/OS-api.svg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/OS-api.svg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/Pasted_image_20220319135558.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/Pasted_image_20220319135558.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/Pasted_image_20220319135558.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/Pasted_image_20220319135558.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/Pasted_image_20220319135805.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/Pasted_image_20220319135805.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/Pasted_image_20220319135805.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/Pasted_image_20220319135805.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/Pasted_image_20220319135823.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/Pasted_image_20220319135823.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/Pasted_image_20220319135823.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/Pasted_image_20220319135823.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/Pasted_image_20220411082627.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/Pasted_image_20220411082627.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/Pasted_image_20220411082627.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/Pasted_image_20220411082627.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/REST_request-load.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/REST_request-load.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/REST_request-load.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/REST_request-load.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/SAGE_command_post.jpg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/SAGE_command_post.jpg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/SAGE_command_post.jpg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/SAGE_command_post.jpg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/Screenshot_2020-08-09_at_21.34.48.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/Screenshot_2020-08-09_at_21.34.48.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/Screenshot_2020-08-09_at_21.34.48.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/Screenshot_2020-08-09_at_21.34.48.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/Screenshot_2021-05-11_at_18.51.02.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/Screenshot_2021-05-11_at_18.51.02.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/Screenshot_2021-05-11_at_18.51.02.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/Screenshot_2021-05-11_at_18.51.02.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/Screenshot_2021-05-11_at_18.55.23.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/Screenshot_2021-05-11_at_18.55.23.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/Screenshot_2021-05-11_at_18.55.23.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/Screenshot_2021-05-11_at_18.55.23.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/TCP_IP.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/TCP_IP.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/TCP_IP.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/TCP_IP.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/Turing_machines_01.gif b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/Turing_machines_01.gif similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/Turing_machines_01.gif rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/Turing_machines_01.gif diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/Zuse-Z3.jpeg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/Zuse-Z3.jpeg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/Zuse-Z3.jpeg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/Zuse-Z3.jpeg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/abc-computer.jpg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/abc-computer.jpg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/abc-computer.jpg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/abc-computer.jpg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/access-key-aws.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/access-key-aws.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/access-key-aws.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/access-key-aws.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/all-layers-of-IP.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/all-layers-of-IP.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/all-layers-of-IP.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/all-layers-of-IP.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/altair-8800.jpg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/altair-8800.jpg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/altair-8800.jpg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/altair-8800.jpg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/analog-digital.svg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/analog-digital.svg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/analog-digital.svg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/analog-digital.svg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/and-gate-new-2.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/and-gate-new-2.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/and-gate-new-2.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/and-gate-new-2.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/and-transistor.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/and-transistor.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/and-transistor.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/and-transistor.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/api-gateway-trigger.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/api-gateway-trigger.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/api-gateway-trigger.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/api-gateway-trigger.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/apollo-explorer.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/apollo-explorer.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/apollo-explorer.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/apollo-explorer.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/apple1.jpg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/apple1.jpg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/apple1.jpg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/apple1.jpg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/apple2.jpg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/apple2.jpg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/apple2.jpg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/apple2.jpg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/application-layer-data.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/application-layer-data.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/application-layer-data.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/application-layer-data.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/arithmometer.jpg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/arithmometer.jpg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/arithmometer.jpg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/arithmometer.jpg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/async.svg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/async.svg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/async.svg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/async.svg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/atom-diagram.svg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/atom-diagram.svg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/atom-diagram.svg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/atom-diagram.svg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/awk-outline.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/awk-outline.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/awk-outline.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/awk-outline.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/basic-circuit.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/basic-circuit.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/basic-circuit.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/basic-circuit.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/bi-intro.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/bi-intro.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/bi-intro.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/bi-intro.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/biconditional-elim.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/biconditional-elim.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/biconditional-elim.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/biconditional-elim.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/bjt-terminals.jpg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/bjt-terminals.jpg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/bjt-terminals.jpg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/bjt-terminals.jpg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/breadboard-DIP.jpg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/breadboard-DIP.jpg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/breadboard-DIP.jpg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/breadboard-DIP.jpg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/breadboard-diagram.jpg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/breadboard-diagram.jpg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/breadboard-diagram.jpg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/breadboard-diagram.jpg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/breakdown.svg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/breakdown.svg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/breakdown.svg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/breakdown.svg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/cell-comparison.svg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/cell-comparison.svg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/cell-comparison.svg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/cell-comparison.svg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/change-dns-server.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/change-dns-server.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/change-dns-server.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/change-dns-server.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/charge-cylinder.svg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/charge-cylinder.svg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/charge-cylinder.svg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/charge-cylinder.svg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/cherry-pick.svg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/cherry-pick.svg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/cherry-pick.svg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/cherry-pick.svg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/circ-batt-final.svg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/circ-batt-final.svg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/circ-batt-final.svg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/circ-batt-final.svg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/clock_pulses.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/clock_pulses.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/clock_pulses.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/clock_pulses.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/cloud-formation-stack.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/cloud-formation-stack.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/cloud-formation-stack.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/cloud-formation-stack.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/cloudwatch-logs.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/cloudwatch-logs.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/cloudwatch-logs.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/cloudwatch-logs.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/combined-merge-hist.svg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/combined-merge-hist.svg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/combined-merge-hist.svg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/combined-merge-hist.svg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/complex-number-calculator-bell-labs.jpg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/complex-number-calculator-bell-labs.jpg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/complex-number-calculator-bell-labs.jpg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/complex-number-calculator-bell-labs.jpg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/complex-tree.svg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/complex-tree.svg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/complex-tree.svg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/complex-tree.svg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/comptometer.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/comptometer.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/comptometer.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/comptometer.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/cond-elim.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/cond-elim.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/cond-elim.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/cond-elim.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/cond-intro.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/cond-intro.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/cond-intro.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/cond-intro.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/conditional-decomposition-rule.svg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/conditional-decomposition-rule.svg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/conditional-decomposition-rule.svg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/conditional-decomposition-rule.svg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/conjunc-elim.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/conjunc-elim.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/conjunc-elim.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/conjunc-elim.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/conjunc-intro.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/conjunc-intro.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/conjunc-intro.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/conjunc-intro.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/conjunction-decomposition-rule.svg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/conjunction-decomposition-rule.svg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/conjunction-decomposition-rule.svg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/conjunction-decomposition-rule.svg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/container-lifecycle.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/container-lifecycle.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/container-lifecycle.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/container-lifecycle.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/container-versus-vm.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/container-versus-vm.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/container-versus-vm.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/container-versus-vm.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/containers-in-userspace.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/containers-in-userspace.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/containers-in-userspace.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/containers-in-userspace.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/correct_push_button.jpg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/correct_push_button.jpg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/correct_push_button.jpg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/correct_push_button.jpg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/derivation_from_contradiction.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/derivation_from_contradiction.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/derivation_from_contradiction.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/derivation_from_contradiction.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/differential_analyser_bush.jpg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/differential_analyser_bush.jpg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/differential_analyser_bush.jpg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/differential_analyser_bush.jpg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/diode-led.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/diode-led.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/diode-led.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/diode-led.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/diode.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/diode.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/diode.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/diode.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/dipole-again.svg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/dipole-again.svg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/dipole-again.svg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/dipole-again.svg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/disjunc-elim.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/disjunc-elim.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/disjunc-elim.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/disjunc-elim.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/disjunc-intro.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/disjunc-intro.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/disjunc-intro.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/disjunc-intro.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/disjunction-decomposition-rule.svg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/disjunction-decomposition-rule.svg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/disjunction-decomposition-rule.svg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/disjunction-decomposition-rule.svg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/dock-architecture.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/dock-architecture.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/dock-architecture.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/dock-architecture.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/draw.io-Page-8.drawio.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/draw.io-Page-8.drawio.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/draw.io-Page-8.drawio.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/draw.io-Page-8.drawio.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/draw.io-Page-9.drawio.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/draw.io-Page-9.drawio.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/draw.io-Page-9.drawio.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/draw.io-Page-9.drawio.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/drawio-Page-7.drawio.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/drawio-Page-7.drawio.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/drawio-Page-7.drawio.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/drawio-Page-7.drawio.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/dsfdsfsdfwe.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/dsfdsfsdfwe.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/dsfdsfsdfwe.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/dsfdsfsdfwe.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/dynamodb.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/dynamodb.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/dynamodb.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/dynamodb.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/em-spectrum.jpg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/em-spectrum.jpg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/em-spectrum.jpg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/em-spectrum.jpg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/em-wave.gif b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/em-wave.gif similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/em-wave.gif rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/em-wave.gif diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/eniac.jpg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/eniac.jpg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/eniac.jpg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/eniac.jpg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/equiv-fractions.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/equiv-fractions.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/equiv-fractions.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/equiv-fractions.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/full-adder-new.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/full-adder-new.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/full-adder-new.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/full-adder-new.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/gateway-services.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/gateway-services.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/gateway-services.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/gateway-services.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/gateway-trigger.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/gateway-trigger.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/gateway-trigger.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/gateway-trigger.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/git-bisect.svg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/git-bisect.svg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/git-bisect.svg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/git-bisect.svg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/git-interactive-mode-2.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/git-interactive-mode-2.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/git-interactive-mode-2.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/git-interactive-mode-2.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/git-interactive-rebase.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/git-interactive-rebase.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/git-interactive-rebase.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/git-interactive-rebase.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/git-manual-hunk.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/git-manual-hunk.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/git-manual-hunk.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/git-manual-hunk.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/git-patch-mode.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/git-patch-mode.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/git-patch-mode.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/git-patch-mode.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/graphQL_request_load.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/graphQL_request_load.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/graphQL_request_load.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/graphQL_request_load.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/graphql-architecture.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/graphql-architecture.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/graphql-architecture.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/graphql-architecture.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/graphql-journey-two.svg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/graphql-journey-two.svg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/graphql-journey-two.svg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/graphql-journey-two.svg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/graphql_multiple_resources.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/graphql_multiple_resources.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/graphql_multiple_resources.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/graphql_multiple_resources.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/greyscale-encoding.svg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/greyscale-encoding.svg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/greyscale-encoding.svg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/greyscale-encoding.svg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/ground-symbol.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/ground-symbol.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/ground-symbol.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/ground-symbol.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/grub.jpg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/grub.jpg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/grub.jpg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/grub.jpg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/half-adder-gates-three.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/half-adder-gates-three.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/half-adder-gates-three.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/half-adder-gates-three.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/half-adder-new.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/half-adder-new.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/half-adder-new.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/half-adder-new.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/harddisk.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/harddisk.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/harddisk.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/harddisk.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/hardware-abstraction-hierarchy.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/hardware-abstraction-hierarchy.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/hardware-abstraction-hierarchy.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/hardware-abstraction-hierarchy.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/hardware-sim-basic.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/hardware-sim-basic.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/hardware-sim-basic.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/hardware-sim-basic.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/hd-sim-test.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/hd-sim-test.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/hd-sim-test.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/hd-sim-test.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/hertz_wave_freq.gif b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/hertz_wave_freq.gif similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/hertz_wave_freq.gif rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/hertz_wave_freq.gif diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/hexadecimal-to-bytes.svg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/hexadecimal-to-bytes.svg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/hexadecimal-to-bytes.svg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/hexadecimal-to-bytes.svg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/htop.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/htop.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/htop.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/htop.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/hydraulic_computer.jpg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/hydraulic_computer.jpg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/hydraulic_computer.jpg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/hydraulic_computer.jpg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/ibm-1401.jpg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/ibm-1401.jpg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/ibm-1401.jpg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/ibm-1401.jpg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/ibm-360-in-use.jpeg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/ibm-360-in-use.jpeg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/ibm-360-in-use.jpeg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/ibm-360-in-use.jpeg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/ibm-360.jpg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/ibm-360.jpg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/ibm-360.jpg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/ibm-360.jpg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/ibm-650-console-panel.jpg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/ibm-650-console-panel.jpg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/ibm-650-console-panel.jpg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/ibm-650-console-panel.jpg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/ibm-650.jpg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/ibm-650.jpg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/ibm-650.jpg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/ibm-650.jpg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/ibm-701-control-unit.jpeg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/ibm-701-control-unit.jpeg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/ibm-701-control-unit.jpeg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/ibm-701-control-unit.jpeg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/ibm-add.jpeg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/ibm-add.jpeg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/ibm-add.jpeg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/ibm-add.jpeg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/ibm-pc.jpg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/ibm-pc.jpg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/ibm-pc.jpg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/ibm-pc.jpg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/incorrect_push_button.jpg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/incorrect_push_button.jpg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/incorrect_push_button.jpg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/incorrect_push_button.jpg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/integrated-circuit.jpeg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/integrated-circuit.jpeg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/integrated-circuit.jpeg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/integrated-circuit.jpeg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/intel-4004.jpg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/intel-4004.jpg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/intel-4004.jpg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/intel-4004.jpg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/internet-layer-packet-revised.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/internet-layer-packet-revised.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/internet-layer-packet-revised.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/internet-layer-packet-revised.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/internet-layer-packet.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/internet-layer-packet.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/internet-layer-packet.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/internet-layer-packet.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/ip-address-anatomy.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/ip-address-anatomy.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/ip-address-anatomy.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/ip-address-anatomy.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/javascript-recursion.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/javascript-recursion.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/javascript-recursion.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/javascript-recursion.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/jk-flip-flops.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/jk-flip-flops.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/jk-flip-flops.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/jk-flip-flops.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/journald.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/journald.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/journald.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/journald.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/kernel-cpu-interaction.svg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/kernel-cpu-interaction.svg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/kernel-cpu-interaction.svg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/kernel-cpu-interaction.svg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/knowledge_graph.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/knowledge_graph.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/knowledge_graph.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/knowledge_graph.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/lambda-cloudwatch.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/lambda-cloudwatch.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/lambda-cloudwatch.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/lambda-cloudwatch.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/lambda-func-three.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/lambda-func-three.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/lambda-func-three.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/lambda-func-three.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/lambda-func-two.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/lambda-func-two.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/lambda-func-two.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/lambda-func-two.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/lambda-overview.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/lambda-overview.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/lambda-overview.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/lambda-overview.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/lambda_func_one.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/lambda_func_one.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/lambda_func_one.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/lambda_func_one.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/leibniz-stepped-drum.jpg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/leibniz-stepped-drum.jpg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/leibniz-stepped-drum.jpg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/leibniz-stepped-drum.jpg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/lin.svg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/lin.svg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/lin.svg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/lin.svg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/link-layer-frame-revised.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/link-layer-frame-revised.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/link-layer-frame-revised.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/link-layer-frame-revised.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/link-layer-frame.drawio.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/link-layer-frame.drawio.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/link-layer-frame.drawio.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/link-layer-frame.drawio.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/link-layer-internet-diagram.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/link-layer-internet-diagram.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/link-layer-internet-diagram.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/link-layer-internet-diagram.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/local-sam-docker.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/local-sam-docker.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/local-sam-docker.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/local-sam-docker.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/logical-equivalence-tree.svg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/logical-equivalence-tree.svg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/logical-equivalence-tree.svg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/logical-equivalence-tree.svg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/logical-falsity-tree.svg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/logical-falsity-tree.svg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/logical-falsity-tree.svg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/logical-falsity-tree.svg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/lsof.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/lsof.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/lsof.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/lsof.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/magnetic-core-closeup.jpg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/magnetic-core-closeup.jpg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/magnetic-core-closeup.jpg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/magnetic-core-closeup.jpg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/magnetic-core-memory.jpg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/magnetic-core-memory.jpg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/magnetic-core-memory.jpg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/magnetic-core-memory.jpg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/magnetic-drum-memory.jpg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/magnetic-drum-memory.jpg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/magnetic-drum-memory.jpg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/magnetic-drum-memory.jpg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/magnetic-tape-disk.jpeg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/magnetic-tape-disk.jpeg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/magnetic-tape-disk.jpeg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/magnetic-tape-disk.jpeg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/magnetic-tape-ibm.jpeg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/magnetic-tape-ibm.jpeg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/magnetic-tape-ibm.jpeg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/magnetic-tape-ibm.jpeg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/magnetic_field.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/magnetic_field.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/magnetic_field.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/magnetic_field.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/manchester_baby.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/manchester_baby.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/manchester_baby.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/manchester_baby.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/memory-flow.svg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/memory-flow.svg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/memory-flow.svg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/memory-flow.svg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/mongo-collection.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/mongo-collection.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/mongo-collection.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/mongo-collection.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/mongo-compass.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/mongo-compass.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/mongo-compass.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/mongo-compass.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/mongo-db-structure.svg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/mongo-db-structure.svg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/mongo-db-structure.svg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/mongo-db-structure.svg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/mongo-doc-added.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/mongo-doc-added.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/mongo-doc-added.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/mongo-doc-added.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/mongoose-hierarchy.svg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/mongoose-hierarchy.svg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/mongoose-hierarchy.svg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/mongoose-hierarchy.svg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/motherboard-pi.jpg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/motherboard-pi.jpg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/motherboard-pi.jpg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/motherboard-pi.jpg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/mount-directory.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/mount-directory.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/mount-directory.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/mount-directory.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/multi_on_off.gif b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/multi_on_off.gif similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/multi_on_off.gif rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/multi_on_off.gif diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/multiple_circuits.gif b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/multiple_circuits.gif similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/multiple_circuits.gif rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/multiple_circuits.gif diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/nand-gate-new.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/nand-gate-new.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/nand-gate-new.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/nand-gate-new.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/nand-mem-demonstrated.gif b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/nand-mem-demonstrated.gif similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/nand-mem-demonstrated.gif rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/nand-mem-demonstrated.gif diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/nand-mem-first.gif b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/nand-mem-first.gif similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/nand-mem-first.gif rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/nand-mem-first.gif diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/nand-mem-second.gif b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/nand-mem-second.gif similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/nand-mem-second.gif rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/nand-mem-second.gif diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/nand_latch_logic_circuit.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/nand_latch_logic_circuit.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/nand_latch_logic_circuit.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/nand_latch_logic_circuit.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/negate-elim.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/negate-elim.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/negate-elim.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/negate-elim.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/negate-intro.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/negate-intro.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/negate-intro.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/negate-intro.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/negated-biconditional-decomposition-rule.drawio.svg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/negated-biconditional-decomposition-rule.drawio.svg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/negated-biconditional-decomposition-rule.drawio.svg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/negated-biconditional-decomposition-rule.drawio.svg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/negated-conditional-decomposition-rule.svg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/negated-conditional-decomposition-rule.svg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/negated-conditional-decomposition-rule.svg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/negated-conditional-decomposition-rule.svg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/negated-conjunction-decomposition-rule.svg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/negated-conjunction-decomposition-rule.svg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/negated-conjunction-decomposition-rule.svg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/negated-conjunction-decomposition-rule.svg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/negated-disjunction-decomposition-rule.svg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/negated-disjunction-decomposition-rule.svg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/negated-disjunction-decomposition-rule.svg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/negated-disjunction-decomposition-rule.svg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/network-request-layers.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/network-request-layers.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/network-request-layers.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/network-request-layers.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/node-event-loop.svg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/node-event-loop.svg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/node-event-loop.svg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/node-event-loop.svg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/nor-gate-new.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/nor-gate-new.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/nor-gate-new.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/nor-gate-new.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/normal-merge-again.svg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/normal-merge-again.svg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/normal-merge-again.svg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/normal-merge-again.svg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/one-eighth-a.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/one-eighth-a.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/one-eighth-a.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/one-eighth-a.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/opensearch-architecture.drawio.svg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/opensearch-architecture.drawio.svg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/opensearch-architecture.drawio.svg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/opensearch-architecture.drawio.svg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/or-gate-new.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/or-gate-new.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/or-gate-new.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/or-gate-new.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/or-transistor.svg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/or-transistor.svg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/or-transistor.svg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/or-transistor.svg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/parallel-battery-diagram.svg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/parallel-battery-diagram.svg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/parallel-battery-diagram.svg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/parallel-battery-diagram.svg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/parallel-transmission.jpg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/parallel-transmission.jpg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/parallel-transmission.jpg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/parallel-transmission.jpg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/pascaline.jpg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/pascaline.jpg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/pascaline.jpg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/pascaline.jpg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/pilot-ace.jpg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/pilot-ace.jpg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/pilot-ace.jpg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/pilot-ace.jpg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/postman-aws-output.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/postman-aws-output.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/postman-aws-output.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/postman-aws-output.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/postman-lambda.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/postman-lambda.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/postman-lambda.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/postman-lambda.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/programming_a_digital_electronic_computter.jpg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/programming_a_digital_electronic_computter.jpg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/programming_a_digital_electronic_computter.jpg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/programming_a_digital_electronic_computter.jpg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/proof.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/proof.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/proof.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/proof.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/proofs-drawio-Page-5.drawio.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/proofs-drawio-Page-5.drawio.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/proofs-drawio-Page-5.drawio.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/proofs-drawio-Page-5.drawio.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/proofs-drawio-Page-5.drawio_2.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/proofs-drawio-Page-5.drawio_2.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/proofs-drawio-Page-5.drawio_2.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/proofs-drawio-Page-5.drawio_2.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/proofs-drawio-Page-6.drawio.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/proofs-drawio-Page-6.drawio.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/proofs-drawio-Page-6.drawio.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/proofs-drawio-Page-6.drawio.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/ps-tree.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/ps-tree.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/ps-tree.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/ps-tree.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/push-button-legs.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/push-button-legs.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/push-button-legs.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/push-button-legs.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/python-exception-hierarchy.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/python-exception-hierarchy.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/python-exception-hierarchy.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/python-exception-hierarchy.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/queue.svg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/queue.svg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/queue.svg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/queue.svg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/react-lifecycle.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/react-lifecycle.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/react-lifecycle.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/react-lifecycle.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/rebase-tip-chage.svg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/rebase-tip-chage.svg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/rebase-tip-chage.svg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/rebase-tip-chage.svg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/red-encoding.svg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/red-encoding.svg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/red-encoding.svg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/red-encoding.svg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/reiteration.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/reiteration.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/reiteration.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/reiteration.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/relay.gif b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/relay.gif similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/relay.gif rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/relay.gif diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/s3-package-again.svg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/s3-package-again.svg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/s3-package-again.svg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/s3-package-again.svg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/sam-build.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/sam-build.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/sam-build.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/sam-build.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/sam-directory.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/sam-directory.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/sam-directory.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/sam-directory.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/sam-template-yaml.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/sam-template-yaml.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/sam-template-yaml.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/sam-template-yaml.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/serial-transmission.jpg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/serial-transmission.jpg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/serial-transmission.jpg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/serial-transmission.jpg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/series-battcircuit.svg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/series-battcircuit.svg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/series-battcircuit.svg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/series-battcircuit.svg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/series-battery-diagram.svg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/series-battery-diagram.svg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/series-battery-diagram.svg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/series-battery-diagram.svg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/server-listening.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/server-listening.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/server-listening.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/server-listening.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/signed-to-unsigned.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/signed-to-unsigned.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/signed-to-unsigned.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/signed-to-unsigned.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/single-git-history-rebase.svg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/single-git-history-rebase.svg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/single-git-history-rebase.svg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/single-git-history-rebase.svg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/sql-full-outer-join.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/sql-full-outer-join.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/sql-full-outer-join.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/sql-full-outer-join.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/sql-inner-join.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/sql-inner-join.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/sql-inner-join.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/sql-inner-join.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/sql-left-outer-join.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/sql-left-outer-join.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/sql-left-outer-join.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/sql-left-outer-join.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/sql-right-outer-join.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/sql-right-outer-join.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/sql-right-outer-join.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/sql-right-outer-join.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/square.svg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/square.svg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/square.svg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/square.svg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/sr_latch_diagram.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/sr_latch_diagram.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/sr_latch_diagram.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/sr_latch_diagram.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/sr_latch_logic_circuit.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/sr_latch_logic_circuit.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/sr_latch_logic_circuit.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/sr_latch_logic_circuit.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/stack1.svg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/stack1.svg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/stack1.svg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/stack1.svg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/stack2.svg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/stack2.svg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/stack2.svg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/stack2.svg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/standard-userspace.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/standard-userspace.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/standard-userspace.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/standard-userspace.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/state-machine-definition.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/state-machine-definition.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/state-machine-definition.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/state-machine-definition.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/state-machine-execution.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/state-machine-execution.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/state-machine-execution.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/state-machine-execution.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/step1.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/step1.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/step1.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/step1.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/step2.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/step2.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/step2.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/step2.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/step3.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/step3.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/step3.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/step3.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/step4.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/step4.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/step4.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/step4.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/stibitz-teletype.jpg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/stibitz-teletype.jpg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/stibitz-teletype.jpg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/stibitz-teletype.jpg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/switch-and-gate.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/switch-and-gate.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/switch-and-gate.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/switch-and-gate.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/switch-or-gate.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/switch-or-gate.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/switch-or-gate.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/switch-or-gate.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/sync-thread.svg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/sync-thread.svg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/sync-thread.svg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/sync-thread.svg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/systemd-global-files.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/systemd-global-files.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/systemd-global-files.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/systemd-global-files.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/systemd-local-files.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/systemd-local-files.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/systemd-local-files.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/systemd-local-files.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/t-flip-flops.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/t-flip-flops.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/t-flip-flops.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/t-flip-flops.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/terminal_colours.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/terminal_colours.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/terminal_colours.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/terminal_colours.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/theoremproof.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/theoremproof.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/theoremproof.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/theoremproof.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/transistor-off.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/transistor-off.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/transistor-off.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/transistor-off.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/transistor-on.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/transistor-on.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/transistor-on.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/transistor-on.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/transport-layer-segment.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/transport-layer-segment.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/transport-layer-segment.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/transport-layer-segment.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/trigger-info.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/trigger-info.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/trigger-info.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/trigger-info.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/univac-1.jpg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/univac-1.jpg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/univac-1.jpg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/univac-1.jpg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/univac-operator-console.jpeg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/univac-operator-console.jpeg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/univac-operator-console.jpeg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/univac-operator-console.jpeg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/unsigned-to-signed.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/unsigned-to-signed.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/unsigned-to-signed.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/unsigned-to-signed.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/valence-shell.svg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/valence-shell.svg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/valence-shell.svg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/valence-shell.svg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/vertical-circuit.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/vertical-circuit.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/vertical-circuit.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/vertical-circuit.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/virtual-memory-diagram.jpg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/virtual-memory-diagram.jpg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/virtual-memory-diagram.jpg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/virtual-memory-diagram.jpg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/voltage-drop.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/voltage-drop.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/voltage-drop.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/voltage-drop.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/von_neumann_architecture.jpeg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/von_neumann_architecture.jpeg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/von_neumann_architecture.jpeg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/von_neumann_architecture.jpeg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/whirlwind-magnetic-cores.JPG b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/whirlwind-magnetic-cores.JPG similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/whirlwind-magnetic-cores.JPG rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/whirlwind-magnetic-cores.JPG diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/williams-tube-dots.jpg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/williams-tube-dots.jpg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/williams-tube-dots.jpg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/williams-tube-dots.jpg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/williams-tube.jpg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/williams-tube.jpg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/williams-tube.jpg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/williams-tube.jpg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/xor-addition-four.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/xor-addition-four.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/xor-addition-four.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/xor-addition-four.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/xor-gate-new.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/xor-gate-new.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/xor-gate-new.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/xor-gate-new.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/xor-hdl.png b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/xor-hdl.png similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/xor-hdl.png rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/xor-hdl.png diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/yellow-encoding.svg b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/yellow-encoding.svg similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/static/yellow-encoding.svg rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/static/yellow-encoding.svg diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/systemd.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/systemd.md similarity index 98% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/systemd.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/systemd.md index d612724..3ae7c51 100644 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/systemd.md +++ b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/systemd.md @@ -79,13 +79,13 @@ at `/usr/lib/systemd/system`. You shouldn't change or manipulate these files or attempt to add new config files here since they will be overwritten by the system. -![](/static/systemd-global-files.png) _`systemd` global unit files_ +![](static/systemd-global-files.png) _`systemd` global unit files_ Local definitions that relate to the specific user and where the user herself can define units are located in the _system configuration_ directory: `/etc/systemd/system`. -![](/static/systemd-local-files.png) +![](static/systemd-local-files.png) _`systemd` local unit files, specific to the currently logged-in user_ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/systemd_status.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/systemd_status.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/systemd_status.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/systemd_status.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/v8.md b/neuron/280992a4-57c0-4395-82a5-94bb2aefe389/v8.md similarity index 100% rename from neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/v8.md rename to neuron/280992a4-57c0-4395-82a5-94bb2aefe389/v8.md diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/0_Introduction.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/0_Introduction.html deleted file mode 100644 index a4e54b8..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/0_Introduction.html +++ /dev/null @@ -1,67 +0,0 @@ -Creating a RESTful API: Introduction - My Zettelkasten - - - - -

Creating a RESTful API: Introduction

We are going to use Express to create a RESTful API in Node.js.

Request types

Express provides us with methods corresponding to each of the HTTP request types:

  • .get()
  • .post()
  • .put()
  • .delete()

Our data set

Typically when you create a RESTful API you are going to be returning data from a database. For simplicity we are just going simulate this with a simple data array so that we can focus on the Express syntax rather than database handling. Later we will integrate this with a MongoDB database.

We will mainly work with the following array of objects:

const courses = [
-  {
-    id: 1,
-    name: "First course",
-  },
-  {
-    id: 2,
-    name: "Second course",
-  },
-  {
-    id: 3,
-    name: "Third course",
-  },
-];

Creating an Express instance

We first create an instance of Express within index.js. This will be the main coordinating file and we will aim to minimise the amount of business logic we have in this file. It should really just be for initialization and managing middleware.

const express = require("express");
-const app = express();

Routing

We are going to receive all our HTTP requests at the path /api/courses and we will place all code related to this route in a dedicated Node module (routes/courses.js) rather than within index.js which should remain as uncluttered as possible.

First we need to declare this in index.js:

const courses = require("./routes/courses");
-app.use("/api/courses", courses);

Then within courses.js we instantiate an express router that app.js will route to:

const router = express.Router();

Our REST requests will all follow the following pattern:

router.get("/", (req, res) => {
-  res.send(courses);
-});

We target the Router instance we created and all paths will be expressed as / since the app will route by default to /courses/api from index.js

Create listener

With the routing established and the Express instance created we can now listen for requests:

app.listen(3000, () => console.log("Listening on port 30000..."));

REST endpoints

We can now proceed to set up our RESTful endpoints:

GET requests

POST requests

PUT requests

4_DELETE

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/1726814727_LUWV.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/1726814727_LUWV.html deleted file mode 100644 index ba667aa..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/1726814727_LUWV.html +++ /dev/null @@ -1,50 +0,0 @@ -Turing Mach - My Zettelkasten - - - - -

Turing Mach

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/1_GET.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/1_GET.html deleted file mode 100644 index 5b02fb4..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/1_GET.html +++ /dev/null @@ -1,76 +0,0 @@ -Creating a RESTful API: GET requests - My Zettelkasten - - - - -

Creating a RESTful API: GET requests

With our GET request we will simply return the array of course objects.

We create an event emitter and listener that listens for GET requests on a specified port and sends data in response to requests.

// Return a value as response from specified URI
-router.get("/", (req, res) => {
-  res.send(courses);
-});

Our server is now set up:

When creating our API this structure of creating handlers for specific routes will be iterated. Every endpoint will be specified with [app].[http_request_type] and followed by a callback.

We can now call the endpoint:

const getAllCourses = async () => {
-  try {
-    const resp = await axios.get("http://localhost:3000/api/courses");
-    console.log(resp.data);
-  } catch (err) {
-    console.error(err);
-  }
-};
-
-getAllCourses();

Returns:

[
-  { id: 1, name: "First course" },
-  { id: 2, name: "Second course" },
-  { id: 3, name: "Third course" },
-];

Parameters

The previous example serves the entire set of our data. But we will also need to retrieve specific values, we do this by adapting the GET callback to accept parameters. These parameters will correspond to the specific entry in our main data array.

router.get("/:id", (req, res) => {
-  res.send(req.params.id);
-});

We use the : symbol in the URI to indicate that we looking to parse for a specific value in the data. Now if we call /api/courses/2, we will get the second item in the array.

The block above is the most basic format but we would want to add some kind of error handling, for example:

router.get("/:id", (req, res) => {
-  const course = courses.find((c) => c.id === parseInt(req.params.id));
-  if (!course) res.status(404).send("A course with the given ID was not found");
-  res.send(course);
-});

Queries

Whereas parameters return specific data points, queries don’t get data they aggregate or present the data that is returned in a certain way, such as for instance applying a search function. We indicate queries with a ? in our URI. For example: /api/posts/2018/1?sortBy=name. To facilitate a request like this we have to create a GET path that allows for it:

router.get("/:year/:month", (req, res) => {
-  res.send(req.query);
-})[]();

We would get the following back:

{
-  "sortBy": "name"
-}

Again a JSON object with key-value pairs is returned.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/2_POST.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/2_POST.html deleted file mode 100644 index b0fce2e..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/2_POST.html +++ /dev/null @@ -1,87 +0,0 @@ -Creating a RESTful API: POST requests - My Zettelkasten - - - - -

Creating a RESTful API: POST requests

To demonstrate the handling of POST requests, we will create a handler that add a new element to the array of courses.

router.post("/", (req, res) => {
-  const course = {
-    id: courses.length + 1,
-    name: req.body.name,
-  };
-  courses.push(course);
-  res.send(course);
-});

Here we use the body that is sent from the client and isolate the field name. This presupposes that the client is sending us data with the following shape as the body:

{
-  "name": "Biology and Life Sciences"
-}

To execute the PUT request from the frontend:

const addCourse = async (newCourse) => {
-  try {
-    const resp = await axios.post("http://localhost:3000/api/courses", {
-      name: newCourse,
-    });
-    console.log(resp.data);
-  } catch (err) {
-    console.error(err);
-  }
-};
-addCourse("Biology and Life Sciences");

Which returns:

{ id: 4, name: 'Biology and Life Sciences' }

The id is added by the server, not the client. Having created the new value we add it to our courses array. (In reality we would be creating a new entry in a database.) Then we follow the convention of returning the new value back to the client.

Validation

We should accept alterations to the database that are not first validated. We can use the Joi validator to vet the request:

function validateCourse(course) {
-  const schema = Joi.object({
-    name: Joi.string().min(3).required(),
-  });
-
-  const { error } = schema.validate(course);
-  return error;
-}

We can then add the validation as part of our general error handling:

router.post("/", (req, res) => {
-  const course = {
-    id: courses.length + 1,
-    name: req.body.name,
-  };
-  const { error } = schema.validate(req.body);
-  if (error)
-    return error.details.map((joiErr) => res.status(400).send(joiErr.message));
-
-  courses.push(course);
-  res.send(course);
-});
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/3_PUT.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/3_PUT.html deleted file mode 100644 index c12b615..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/3_PUT.html +++ /dev/null @@ -1,74 +0,0 @@ -Creating a RESTful API: PUT requests - My Zettelkasten - - - - -

Creating a RESTful API: PUT requests

To demonstrate the handling of PUT requests, we will create a handler that updates an element in the course array, based on its id and return the updated entry:

router.put("/:id", (req, res) => {
-  const course = courses.find((c) => c.id === parseInt(req.params.id));
-
-  if (!course)
-    return res.status(404).send("A course with the given ID was not found");
-
-  const { error } = validateCourse(req.body);
-
-  if (error)
-    return error.details.map((joiErr) => res.status(400).send(joiErr.message));
-
-  course.name = req.body.name;
-  res.send(course);
-});

Our request:

const updateCourse = async (courseChange) => {
-  try {
-    const resp = await axios.put("http://localhost:3000/api/courses/1", {
-      name: courseChange.name,
-    });
-    console.log(resp.data);
-  } catch (err) {
-    console.error(err);
-  }
-};
-
-updateCourse({ name: "A new course" });

Returns:

{ id: 1, name: 'A new course' }
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/5__Integrating_the_Mongo_database.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/5__Integrating_the_Mongo_database.html deleted file mode 100644 index b825a43..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/5__Integrating_the_Mongo_database.html +++ /dev/null @@ -1,187 +0,0 @@ -Creating a RESTful API: Integrating the database - My Zettelkasten - - - - -

Creating a RESTful API: Integrating the database

So far we have set up the application and an /api/courses route which handles requests for RESTful API operations on a local array of course objects. We now want to have the endpoints operate on a MongoDB courses collection rather than the array.

Set-up

We will follow the routine for establishing a MongoDB instance as detailed in my notes on Mongo:

Our index.js now looks like the following:

// index.js
-
-// Connect to database
-mongoose
-  .connect("mongodb://127.0.0.1/playground")
-  .then(() => console.log("Connected to MongoDB"))
-  .catch((err) => console.error(err));
-
-app.use(express.json());
-
-// Link to `courses` route which contains our REST request handlers for this part of the API
-app.use("/api/courses", courses);

Integrating Mongo with our our courses module

Create the schema

Now we go the router module for courses and start to use Mongoose, defining our Course schema:

// index.js
-
-// Connect to database
-mongoose
-  .connect("mongodb://127.0.0.1/playground")
-  .then(() => console.log("Connected to MongoDB"))
-  .catch((err) => console.error(err));
-
-app.use(express.json());
-
-// Link to `courses` route which contains our REST request handlers for this part of the API
-app.use("/api/courses", courses);
-
-+ const courseSchema = new mongoose.Schema({
-+  name: {type: String, required: true, minlength: 5, maxlength: 255},
-+  author: String,
-+  tags: [String],
-+  data: {type: Date, default: Date.now}, // if unspecified, entry will default to current date
-+  isPublished: Boolean,
-+ });
-

Create a model

const courseSchema = new mongoose.Schema({
-  name: {type: String, required: true, minlength: 5, maxlength: 255},
-  author: String,
-  tags: [String],
-  data: {type: Date, default: Date.now}, // if unspecified, entry will default to current date
-  isPublished: Boolean,
- });
-
-+ const Course = new mongoose.model('Course', courseSchema);

With this established we can remove our local array as we are ready to start getting our data from the database:

const Course = mongoose.model('Course', courseSchema);
-
-- const courses = [
--  {
--    id: 1,
--    name: "First course",
--  },
--  ...
--];

We could actually simplify the syntax here and combine our schema and model declaration into a single block:

const Course = mongoose.model(
-  "Course",
-  new mongoose.Schema({
-    name: { type: String, required: true, minlength: 5, maxlength: 255 },
-    author: String,
-    tags: [String],
-    data: { type: Date, default: Date.now }, // if unspecified, entry will default to current date
-    isPublished: Boolean,
-  })
-);

N.B In a real project we wouldn’t keep our models in the same file as our handlers. We would keep them in the dedicated /models/ directory. We should stick to the single responsibility principle and keep /routes/ for API handlers and /model/ for schema declarations and models.

Rewriting the REST handlers

Now we need to rewrite our RESTful request handlers so that the data is sourced from and added to the database. We will mainly be using the Mongo syntax defined at Querying a collection and Adding documents to a collection. We will also keep API validation within the /model/ file.

GET

Instead of simply returning the array, we use the Mongoose find method.

- router.get("/", (req, res) => {
--  res.send(courses);
- });
-
-+ router.get("/", async (res, res) => {
-+  const courses = await Courses.find();
-  res.send(courses)
-})

POST

Now we make our new course an instance of the Courses model:

// Original formulation
-
-router.post("/", (req, res) => {
--  const course = {
--    id: courses.length + 1,
--    name: req.body.name,
--  };
-  courses.push(course);
-  res.send(course);
-});
router.post("/", async (req, res) => {
-+  let course = new Course({ // make new course instance of Course model
--   id: courses.length + 1, // not needed as DB automatically adds an id
-    name: req.body.name,
-  });
-- courses.push(course); // not pushing to the array anymore
-+ await course.save() // save to Mongo
-  res.send(course);
-});
-

PUT

When updating a value in the database we are going to use the query-first approach to updating a Mongo document.

  name: {type: String, required: true, minlength: 5, maxlength: 255},
-  author: String,
-  tags: [String],
-  data: {type: Date, default: Date.now}, // if unspecified, entry will default to current date
-  isPublished: Boolean,
- });
-router.put("/:id", (req, res) => {
-  const course = courses.find((c) => c.id === parseInt(req.params.id));
-
-  if (!course)
-    return res.status(404).send("A course with the given ID was not found");
-
-  const { error } = validateCourse(req.body);
-  if (error)
-    return error.details.map((joiErr) => res.status(400).send(joiErr.message));
-const courseSchema = new mongoose.Schema({
-  name: {type: String, required: true, minlength: 5, maxlength: 255},
-  author: String,
-  tags: [String],
-  data: {type: Date, default: Date.now}, // if unspecified, entry will default to current date
-  isPublished: Boolean,
- });
-  course.name = req.body.name;
-  res.send(course);
-});
router.put("/:id", async (req, res) => {
-- const course = courses.find((c) => c.id === parseInt(req.params.id));
- const { error } = validateCourse(req.body);
- if (!course) return res.status(404).send("A course with the given ID was not found");
-+ const updatedCourse = await Course.findByIdAndUpdate(req.params.id,
-+  { name: req.body.name },
-+  { new: true}
-+ )
-
--   if (error)
--   return error.details.map((joiErr) => res.status(400).send(joiErr.message));
-- })
-
-- course.name = req.body.name;
-  res.send(course);

DELETE

router.delete("/:id", (req, res) => {
-  const course = courses.find((c) => c.id === parseInt(req.params.id));
-  if (!course)
-    return res.status(404).send("A course with the given ID was not found");
-
-  courses.indexOf(course);
-  courses.splice(index, 1);
-  res.send(course);
-});

-router.delete("/:id", async (req, res) => {
- const courseToDelete = await Course.findByIdAndRemove(req.params.id)
-
- if (!course) return res.status(404).send("A course with the given ID was not found");
-
-- courses.indexOf(course);
-- courses.splice(index, 1);
-
-res.send(course);
-})
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/API_Gateway.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/API_Gateway.html deleted file mode 100644 index 093fac8..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/API_Gateway.html +++ /dev/null @@ -1,50 +0,0 @@ -AWS API Gateway - My Zettelkasten - - - - -

AWS API Gateway

We can use Gateway as the front-door to our application. It will create an HTTP endpoint that you can call from a client. In response to a client request you can then call a lambda function that executes a backend process.

See using API Gateway as Lambda trigger for a basic example of usage.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/AWS_CLI.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/AWS_CLI.html deleted file mode 100644 index 7574b86..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/AWS_CLI.html +++ /dev/null @@ -1,52 +0,0 @@ -AWS CLI frequent commands - My Zettelkasten - - - - -

AWS CLI frequent commands

Retrieve current user

aws-sts get-caller-identity

List users

aws configure list
-aws configure list-profiles

View profile data

vim ./aws/credentials

CloudFormation

List stacks

aws cloudformation --list-stacks

Delete a stack

aws cloudformation delete-stack --stack-name <my_stack> --region <region>

region is optional especially if only deployed to one region

Billing (“Cost explorer”)

Usage for month

 aws ce get-cost-and-usage --time-period Start=$(date +%Y-%m-01),End=$(date -d @$(( $(date +%s) + 86400 )) +%Y-%m-%d) --granularity MONTHLY --metrics "UnblendedCost" "UsageQuantity

Retrieve current user

aws-sts get-caller-identity

List users

aws configure list
-aws configure list-profiles

View profile data

vim ./aws/credentials
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/AWS_SAM_and_Docker.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/AWS_SAM_and_Docker.html deleted file mode 100644 index 2b14de3..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/AWS_SAM_and_Docker.html +++ /dev/null @@ -1,50 +0,0 @@ -AWS SAM and Docker - My Zettelkasten - - - - -

AWS SAM and Docker

How would you use docker containers in AWS. How would this integrate with SAM. What are the benefits over just deploying from local via SAM

Amazon Web Services (AWS) provides several services for running Docker containers, such as Amazon Elastic Container Service (ECS) and AWS Fargate. To integrate Docker containers with AWS Serverless Application Model (SAM), you can use the AWS Lambda container image support feature, which allows you to package and deploy Lambda functions as container images.

Here’s a brief overview of how to use Docker containers in AWS with SAM:

  1. Create a Dockerfile for your Lambda function, using one of the AWS-provided base images for your preferred runtime (e.g., Python, Node.js, etc.).
  2. Build the Docker image using the docker build command.
  3. Push the Docker image to Amazon Elastic Container Registry (ECR) using the docker push command.
  4. In your AWS SAM template (template.yaml), define a Lambda function with the ImageUri property pointing to the Docker image stored in ECR.
  5. Deploy the serverless application using the sam deploy command.

Benefits of using Docker containers with AWS SAM over deploying from local:

  • Consistency:

    • Packaging your Lambda function as a container image ensures that the environment and dependencies are consistent across development, testing, and production stages. It eliminates the “it works on my machine” problem.
  • Custom runtimes:

    • AWS Lambda provides a set of pre-defined runtimes, but with container image support, you can use custom runtimes, giving you more flexibility and control over the execution environment.
  • Easier dependency management:

    • For complex applications with numerous dependencies or large package sizes, using container images simplifies dependency management and can help you stay within the Lambda package size limits.
  • Reuse of existing Docker workflows:

    • If you already have Docker workflows in place for building, testing, and deploying containerized applications, you can easily extend these workflows for your Lambda functions, reducing the learning curve and operational overhead.
  • Ease of local testing:

    • With AWS SAM CLI, you can test your Lambda functions locally as container images, closely mimicking the actual execution environment and reducing the chances of unexpected issues when deploying to AWS.

While using Docker containers with AWS SAM has its benefits, it may not be suitable for every use case. If your Lambda functions have minimal dependencies and simple execution environments, deploying directly from local using SAM might be more straightforward and faster. However, for more complex applications, using Docker containers can provide better consistency, flexibility, and control over the execution environment.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/AWS_architecture_hierarchy.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/AWS_architecture_hierarchy.html deleted file mode 100644 index 399505a..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/AWS_architecture_hierarchy.html +++ /dev/null @@ -1,51 +0,0 @@ -AWS architecture hierarchy - My Zettelkasten - - - - -

AWS architecture hierarchy

From bottom up:

flowchart TD
-    Data centres --> Availability Zones--> Regions
EntityDescription
Data centerWarehouse full of servers
Availability ZonesA cluster of data centers
RegionA cluster of Availability Zones
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Accessing_metadata_about_SQL_database.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Accessing_metadata_about_SQL_database.html deleted file mode 100644 index a53c225..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Accessing_metadata_about_SQL_database.html +++ /dev/null @@ -1,59 +0,0 @@ -Accessing metadata about SQL database - My Zettelkasten - - - - -

Accessing metadata about SQL database

SHOW DATABASES
-
-SHOW TABLES
-
--- View column names and data types
-DESCRIBE [table_name]
-
--- View disk usage per column
-SHOW TABLE STATUS
-
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Accessing_secrets_from_a_Lambda.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Accessing_secrets_from_a_Lambda.html deleted file mode 100644 index f29e1f9..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Accessing_secrets_from_a_Lambda.html +++ /dev/null @@ -1,62 +0,0 @@ -Accessing secrets from a Lambda - My Zettelkasten - - - - -

Accessing secrets from a Lambda

If a Lambda connects to a database or calls an API, it is going need access to authentication tokens/passwords.

You obviously should not store these in your code. Instead you should store them in AWS Secrets Manager and access them via the aws-sdk in your Lambda function.

In order for your function to be able to access the secrets however, it will need to be given permission. While the Lambda is not itself a “user” it does have an identity in the form of its IAM role. This is disclosed by its ARN.

To allow the Lambda to access the secret you should add a resource permission on the secret that designates the Lambda.

When you create a Lambda function, you specify an IAM role that AWS Lambda can assume to execute the function on your behalf. This role is referred to as the execution role. The execution role grants the function the necessary permissions to call other AWS services, access resources, and perform other operations.

Here is an example of a resource permission giving access to a Lambda:

{
-  "Version": "2012-10-17",
-  "Statement": [
-    {
-      "Effect": "Allow",
-      "Principal": {
-        "AWS": "arn:aws:iam::885135949562:role/pocket-api-lambda-QueryPocketFunctionRole-GY5ZN3RW31KE"
-      },
-      "Action": "secretsmanager:GetSecretValue",
-      "Resource": "arn:aws:secretsmanager:eu-west-2:885135949562:secret:pocket-api-credentials-wEvQMI"
-    }
-  ]
-}

See Fetch from Secrets Manager for a code example of retrieving a value from Secrets Manager.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Add_Subtract_Fractions.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Add_Subtract_Fractions.html deleted file mode 100644 index 0609fd1..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Add_Subtract_Fractions.html +++ /dev/null @@ -1,81 +0,0 @@ -Adding and subtracting fractions - My Zettelkasten - - - - -

Adding and subtracting fractions

Adding/ subracting fractions with common denominators

For two fractions \(\frac{a}{c}\) and \(\frac{b}{c}\) with a common denominator, their sum is defined as:

$$ -\frac{a}{c} + \frac{b}{c} = \frac{a + b}{c} -$$

For example:

$$ -\frac{2}{8} + \frac{3}{8} = \frac{5}{8} -$$

The same applies to subtraction:

$$ -\frac{a}{c} - \frac{b}{c} = \frac{a - b}{c} -$$

Adding/ subracting fractions without common denominators

  • Find the lowest common denominator for the two fractions
  • Use this to create two equivalent fractions
  • Add/subtract
  • Reduce

Lowest common denominator and lowest common multiple

Given the symmetry between factors and divisors these properties are related. Note however that the LCM is more generic: it applies to any set of numbers not just fractions. Whereas the LCD is explicitly to do with fractions (hence ‘denominator’).

  • For two fractions \(a, b\) (or a set), the LCD is the smallest number divisble by both the denominator of \(a\) and the denominator of \(b\) (or each member of the set).

  • For two fractions \(a, b\) (or a set), the LCM is the smallest number that is a multiple of the denominator of \(a\) and the denominator of \(b\) (or each member of the set).

In order to find the LCM of the set \(\{12, 16\}\) we list the multiples of both:

$$ -12, 24, 36, 48 \\ -16, 32, 48 -$$

Until we identify the smallest number common to both lists. In this case it is 48. Thus the LCM of 12 and 16 is 48.

The relationship between LCM and LCD is that the least common denominator is the least common multiple of the fractions’ denomintors.

Demonstration: addition

We can now use this to calculate the addition of two fractions without common denominators: \(\frac{4}{9} + \frac{1}{6}\).

First identify the common multiples of 9 and 6:

$$ -9, 18, ... \\ -6, 12, 18, ... -$$

The least common multiple is 18. We then think: what do we need to multiply each denominator by to get 18?

In the case of the first fraction (\(\frac{4}{9}\)) it is 2:

$$ -\frac{4}{9 \cdot 2} = \frac{4}{18} -$$

But what we do to the denominator, we must also do to the numerator, hence:

$$ -\frac{4 \cdot 2}{9 \cdot 2} = \frac{8}{18} -$$

We then do the same to the second fraction (\(\frac{1}{6}\)). We need to multiply its denominator by 3 to get 18 and we apply this also to the numerator.

$$ -\frac{1 \cdot 3}{6 \cdot 3} = \frac{3}{18} -$$

We now have two fractions that share a common denominator so we can sum:

$$ -\frac{8}{18} + \frac{3}{18} = \frac{11}{18} -$$

Demonstration: subtraction

Calculate:

$$ -\frac{3}{5} - \frac{2}{3} -$$

Once again we need to find the least common denominator for the two fractions. We start by listing the common multiples for the two denominators 5 and 3:

$$ -5, 10, 15, ... \\ -3, 6, 9, 12, 15,... -$$

The lowest common multiple is 15. From the first fraction we get 15 by multiplying by 3. With the second fraction we get 15 by multiplying by 5. Thus:

$$ -\frac{3 \cdot 3}{5 \cdot 3} = \frac{9}{15} -$$

$$ -\frac{2 \cdot 5}{3 \cdot 5} = \frac{10}{15} -$$

We can now carry out the subtraction:

$$ -\frac{9}{15} - \frac{10}{15} = -\frac{1}{15} -$$

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Adding_documents_to_a_Mongo_collection.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Adding_documents_to_a_Mongo_collection.html deleted file mode 100644 index e86f4d4..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Adding_documents_to_a_Mongo_collection.html +++ /dev/null @@ -1,74 +0,0 @@ -Adding documents to a collection - My Zettelkasten - - - - -

Adding documents to a collection

We have our database (playground) and collection (courses) established. We now need to add documents to our collection. We will do this via a function since this will be an asynchronous process:

const pythonCourse = new Course({
-  name: "Python Course",
-  author: "Terry Ogleton",
-  tags: ["python", "backend"],
-  isPublished: true,
-});
-
-async function addCourseDocToDb(courseDocument) {
-  try {
-    const result = await courseDocument.save();
-    console.log(result);
-  } catch (err) {
-    console.error(err.message);
-  }
-}
-
-addCourseDocToDb(nodeCourse);

When we run this, we call the save method on the Mongoose schema. We will then have the Mongo document outputted to the console:

{
-  name: 'Python Course',
-  author: 'Terry Ogleton',
-  tags: [ 'python' ],
-  isPublished: true,
-  _id: new ObjectId("62f4ac989d2fec2f01596b9b"),
-  date: 2022-08-11T07:15:36.978Z,
-  __v: 0
-}

This will also be reflected in Compass:

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Additive_identity.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Additive_identity.html deleted file mode 100644 index c1ab04c..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Additive_identity.html +++ /dev/null @@ -1,50 +0,0 @@ -The Property of Additive Identity - My Zettelkasten - - - - -

The Property of Additive Identity

Let \(a\) represent any member of \(\mathbb{W}\) or \(\mathbb{Z}\) then:

$$ a + 0 = a $$

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Additive_inverse_property.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Additive_inverse_property.html deleted file mode 100644 index 15db019..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Additive_inverse_property.html +++ /dev/null @@ -1,50 +0,0 @@ -Additive inverse property - My Zettelkasten - - - - -

Additive inverse property

Let \(a\) represent any member of \(\mathbb{Z}\). Then there is a unique member of \(\mathbb{Z}\) \(-a\) such that:

$$ a + (-a) = 0 $$

The sum of a number and it’s negative (called the additive inverse) is always zero.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Aggregate_functions_in_SQL.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Aggregate_functions_in_SQL.html deleted file mode 100644 index 835ddab..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Aggregate_functions_in_SQL.html +++ /dev/null @@ -1,55 +0,0 @@ -Aggregate functions in SQL - My Zettelkasten - - - - -

Aggregate functions in SQL

Aggregate functions enable us to return data about the data that a table holds. For example the sum of a given column or its average.

Count return with custom variable

SELECT COUNT(*) AS total_sales
-FROM SALES

Sum

SELECT SUM(price) as total_value
-FROM sales

Average

SELECT AVG(price) as average_income
-FROM sales

Applying aggregate function with sorting applied

SELECT COUNT(*) AS total_sales
-FROM sales
-GROUP BY employee_id
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Algebra_key_terms.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Algebra_key_terms.html deleted file mode 100644 index 5a2d3cf..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Algebra_key_terms.html +++ /dev/null @@ -1,50 +0,0 @@ -Algebra key terms - My Zettelkasten - - - - -

Algebra key terms

  • Variable
    • A symbol that stands for a value which may vary
  • Equation
    • A mathematical statement that equates two mathematical expressions (states that they are the same/ establishes an identity relation)
  • Solution ^678811
    • A numerical value that satisfies an equation. When the variable in the equation is replaced by the solution, a true statement results

Example

$$ 4 = y - 11 $$

The example above is an equation. \(y\) is the variable. This can be replaced by \(15\) which is the solution to the equation:

$$ 4 = 15 -11 $$

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Algorithmic_complexity.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Algorithmic_complexity.html deleted file mode 100644 index 5702806..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Algorithmic_complexity.html +++ /dev/null @@ -1,84 +0,0 @@ -Algorithmic complexity - My Zettelkasten - - - - -

Algorithmic complexity

Screenshot_2021-05-11_at_18.55.23.png Summary of the main classes of algorithmic complexity

Distinguish algorithms from programs

Test commit Algorithms are general sets of instructions that take data in one state, follow a prescribed series of steps and return data in another state. Programs are a specific application of one or more algorithms to achieve an outcome in a specific context. With algorithms, the actual detail of the steps is mostly abstracted and it is irrelevant to what end the algorithm is being put. For instance you may create a program that returns addresses from a database using a postcode. It is irrelevant to the efficiency or value of the algorithm whether or not you are looking up postcodes or some other form of alphanumeric string.

Algorithmic efficiency

Algorithms can be classified based on their efficiency. Efficiency is function of the runtime speed. However this doesn’t always mean that the fastest algorithms are best.

If we are landing the Curiosity Rover on Mars we may choose an algorithm that is slower on average for a guarantee that it will never take longer than we find acceptable. In other cases for example a video game, we may choose an algorithm that keeps the average time down, even if this occasionally leads to processes that need to be aborted because they take too long.

We need a generalised measure of efficiency to compare algorithms, across variant hardware. We can’t simply use the number of steps, since some steps will be quicker to complete than others in the course of the overall algorithm and may take longer on different machines. Moreover the same algorithm could run at different speeds on the same machine, depending on its internal state at the given time that it ran. So we use the following: the number of steps required relative to the input.

Two given computers may differ in how quickly they can run an algorithm depending on clock speed, available memory and so forth. They will however tend to require approximately the same number of instructions and we can measure the rate at which the number of instructions increases with the problem size.

This is what asymptotic runtime means: the rate at which the runtime of an algorithm grows compared to the size of its input. For precision and accuracy we use the worst case scenario as the benchmark.

So: the efficiency of algorithm A can be judged relative to the efficiency of algorithm B based on the rate at which the runtime of A grows compared to its input, compared to the same property in B, assuming the worst possible performance.

From now on we will use the word ‘input’ to denote the data that the algorithm receives (in most cases we will envision this as an array containing a certain data type) and ‘execution’ to denote the computation that is applied by the algorithm to each item of the data input. Rephrasing the above with these terms we can say that ‘algorithmic efficiency’ is a measure that describes the rate at which the execution time of an algorithm increases relative to the size of its input.

We will find that for the runtime of some algorithms, the size of the input does not change the execution time. In these cases, the runtime is proportional to the input quantity. In this case, regardless of whether the input is an array of one hundred elements or an array of ten elements, the amount of work that is executed on each element is the same.

For other cases, this will not hold true. We will find that there is a relationship between input size and execution time such that the length of the input affects the amount of work that needs to be performed on each item at execution.

Linear time

Let’s start with linear time, which is the easiest runtime to grasp.

We need an example to make this tangible and show how an algorithm’s runtime changes compared to the size of its input. Let’s take a simple function that takes a sequence of integers and returns their sum:

function findSum(arr){
-	let total = 0;
-	for (let i = 0; i < arr.length; i++){
-		total = total += arr[i];
-	)
-	return total
-}

The input of this function is an array of integers. It returns their sum as the output. Let’s say that it takes 1ms for the function to sum an array of two integers.

If we passed in an array of four integers, how would this change the runtime? The answer is that, providing that the time it takes to sum two integers doesn’t change, it would take twice as long.

As the time it takes to execute findSum doesn’t change, we can say confidently that the runtime is as long as the number of integers we pass in.

A more general way to say this is that the runtime is equal to size of the input. For algorithms of the class of which findSum is a member: the total runtime is proportional to the number of items to be processed.

Introducing asymptotic notation

If we say that it takes 1ms for two integers to be summed, this gives us the following data set:

Length of inputRuntime
22
33
44
55

If we plotted this as a graph it is clear that this is equivalent to a linear distribution:lin.svg

Algorithms which display this distribution are therefore called linear algorithms.

The crucial point is that the amount of time it takes to sum the integers does not increase as the algorithm proceeds and the input size grows. This time remains the same. If it did increase, we would have a fluctuating curve on the graph. This aspect remains constant, only the instructions increase. This is why we have a nice steadily-advancing distribution in the graph.

We can now introduce notation to formalise the algorithmic properties we have been discussing.

Big O notation

To express linear time algorithms formally, we say that:

it takes some constant amount of time (\(C\)) to sum one integer and n times as long to sum n integers

Here the constant is the time for each execution to run and n is the length of the input. Thus the complexity is equal to that time multiplied by the input.

The algebraic expression of this is \(cn\) : the constant multiplied by the length of the input. In algorithmic notation, the reference to the constant is always removed. Instead we just use n and combine it with a ‘big O’ which stands for ‘order of complexity’. Likewise, if we have an array of four integers being passed to findSum we could technically express it as O(4n), but we don’t because we are interested in the general case not the specific details of the runtime. So a linear algorithm is expressed algebraically as \(O(n)\) which is read as “oh of n” and means

\(O(n)\) = with an order of complexity equal to (some constant) multiplied by n

Applied, this means an input of length 6 (\(n\)) where runtime is constant (\(c\)) at 1ms has a total runtime of 6 x 1 = 6ms in total. Exactly the same as our table and graph. O n is just a mathematical way of saying the runtime grows on the order of the size of the input.

It’s really important to remember that when we talk about the execution runtime being constant at 1ms, this is just an arbitrary placeholder. We are not really bothered about whether it’s 1ms or 100ms: ‘constant’ in the mathematical sense doesn’t mean a unit of time, it means ‘unchanging’. We are using 1ms to get traction on this concept but the fundamental point being expressed is that the size of the input doesn’t affect the execution time across the length of the execution time.

Constant time

Constant time is another one of the main classes of algorithmic complexity. It is expressed as O(1). Here, we do away with n because with constant time we are only ever dealing with a single execution so we don’t need a variable to express nth in a series or ‘more than one’. Constant time covers all singular processes, without iteration.

An example in practice would be printing array[0] . Regardless of the size of the array, it is only ever going to take one step, or constant times one. On a graph this is equivalent to a flat line along the time axis. Since it only happens for one instant, it doesn’t persist over time or have multiple iterations.

Relation to linear time

If you think about it, there is a clear logical relationship between constant and linear time: because the execution time of a linear algorithm is constant, regardless of the size of n, each execution of O(n) is equal to O(1). Thus O(n) is simply O(1) writ large or iterated. At any given execution of an O(n) algorithm n is going to be equal to 1.

Quadratic time

With the examples of constant and linear time, the total number of instructions doesn’t change the amount of work that needs to be performed for each item, but this only covers one subset of algorithms. In cases other than O(1) and O(n), the length of the input can affect the amount of work that needs to be performed at execution. The most common example of this scenario is known as quadratic time, represented as \(O(n^2)\).

Let’s start with an example.

const letters = ['A', 'B', 'C'];
-
-function quadratic(arr) {
-  for (let i = 0; i < arr.length; i++) {
-    for (let j = 0; j < arr.length j++) {
-      console.log(arr[i]);
-    }
-  }
-}
-
-quadratic(letters);

This function takes an array . The outer loop runs once for each element of the array that is passed to the function. For each iteration of the outer loop, the inner loop also runs once for each element of the array.

In the example this means that the following is output:

A A A B B B C C C (length: 9)

Mathematically this means that n (the size of the input) grows at a rate of n2 or the input multiplied by itself. Our outer loop (i) is performing n iterations (just like in linear time) but our inner loop (j) is also performing n iterations, three js for every one i . It is performing n iterations for every nth iteration of the outer loop. So runtime here is directly proportional to the squared size of the input data set. As the input array has a length of 3, and the inner array runs once for every element in the array, this is equal to 3 x 3 or 3 squared (9).

If the input had length 4, the runtime would be 16 or 4x4. For every execution of linear time (the outer loop) the inner loop runs as many times as is equal to the length of the input.

This is not a linear algorithm because as n grows the runtime increases as a factor of it. Therefore the runtime is not growing proportional to the size of the input, it is growing proportional to the size of the input squared.

Graphically this is represented with a curving lines as follows: square.svg

We can clearly see that as n grows, the runtime gets steeper and more pronounced,

Logarithmic time (log n)

A logarithm is best understood as the inverse of exponentiation:

$$ \log \_{2}8 = 3 \leftrightarrow 2^3 = 8 $$

When we use log in the context of algorithms we are always using the binary number system so we omit the 2, we just say log.

With base two logarithms, the logarithm of a number roughly measures the number of times you can divide that number by 2 before you get a value that is less than or equal to 1

So applying this to the example of \(\log 8\) , it is borne out as follows:

  • 8 / 2 = 4 — count: 1
  • 4 / 2 = 2 — count: 2
  • 2 / 2 = 1 — count: 3

As we are now at 1, we can’t divide any more, so \(\log 8\) is equal to 3.

Obviously this doesn’t work so neatly with odd numbers, so we approximate.

For example, with \(\log 25\):

  • 25 / 2 = 12.5 — count: 1

  • 12.5 / 2 = 6.25 — count: 2

  • 6.25 / 2 = 3.125 — count: 3

  • 3.125 / 2 = 1.5625 — count: 4

  • 1.5625 / 2 = 0.78125

    Now we are lower than 1 so we have to stop. We can only say that the answer to \(\log 25\) is somewhere between 4 and 5.

    The exact answer is \(\log 25 \approx 4.64\)

Back to algorithms: \(O(\log n)\) is a really good complexity to have. It is close to O(1) and in between O(1) and O(n). Represented graphically, it starts of with a slight increase in runtime but then quickly levels off:

Screenshot_2021-05-11_at_18.51.02.png

Many sorting algorithms run in log n time, as does recursion.

Reducing O complexity to the general case

When we talk about big O we are looking for the most general case, slight deviations, additions or diminutions in n are not as important as the big picture. We are looking for the underlying logic and patterns that are summarised by the classes of O(1), O(n), O(n2) and others.

For example, with the following function:

function sumAndAddTwo(arr) {
-  let total = 0;
-  for (let i = 0; i < arr.length; i++) {
-    total += arr[i];
-  }
-  total = total += 2;
-}

The formal representation of the above complexity would be O(n) + O(1). But it’s easier just to say O(n), since the O(1) that comes from adding two to the result of the loop, makes a marginal difference overall.

Similarly, with the following function:

function processSomeIntegers(integers){
-	let sum, product = 0;
-
-	integers.forEach(function(int){
-		return sum += int;
-	}
-
-	integers.forEach(function(int){
-		return product *= int;
-	}
-
-	console.log(`The sum is ${sum} and the product is ${product}`);
-}

It might appear to be more complex than the earlier summing function but it isn’t really. We have one array (integers ) and two loops. Each loop is of O(n) complexity and does a constant amount of work. If we add O(n) and O(n) we still have O(n), not O(2n). The constant isn’t changed in any way by the fact that we are looping twice through the array in separate processes, it just doubles the length of n. So rather than formalising this as O(n) + O(n), we just reduce it to O(n).

When seeking to simplify algorithms to their most general level of complexity, we should keep in mind the following shorthands:

  • Arithmetic operations always take constant time
  • Variable assignment always takes constant time
  • Accessing an element in an array by index or an object value by key is always constant
  • in a loop the complexity is the length of the loop times the complexity of whatever happens inside of the loop

With this in mind we can break down the findSum function like so:

breakdown.svg

This gives us:

$$ O(1) + O(1) + O(n) $$

Which, as noted above can just be reduced to O(n).

Space complexity

So far we have talked about time complexity only: how the runtime changes relative to the size of the input. With space complexity, we are interested in how much memory (conceived as an abstract spatial quantity corresponding to the machine’s hardware) is required by the algorithm. We can use Big O notation for space complexity as well as time complexity.

Space complexity in this sense is called ‘auxiliary space complexity’. This means the space that the algorithm itself takes up, independent of the the size of the inputs. We are not focusing on the space that each input item takes up, only the overall space of the algorithm.

Again there are some rules of thumb:

  • Booleans, undefined, and null take up constant space
  • Strings require O(n) space, where n is the sting length
  • Reference types take up O(n): an array of length 4 takes up twice as much space as an array of length 2

So with space complexity we are not really interested in how many times the function executes, if it is a loop. We are looking to where data is stored: how many variables are initialised, how many items there are in the array.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Analogue_and_digital.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Analogue_and_digital.html deleted file mode 100644 index da41b84..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Analogue_and_digital.html +++ /dev/null @@ -1,50 +0,0 @@ -Analogue and digital - My Zettelkasten - - - - -

Analogue and digital

Analogue and digital are paradigms for recording information, specifically information about an object or state that obtains in the world.

Analogue

Here are two examples of analogue measurement/ capture:

  • Measuring the temperature of a room with a mercury barometer
    • The mercury in the barometer expands or contracts in response to the heat of the ambient environment.
    • We say that the position of the mercury relative to the container represents the current temperature
  • Measuring the weight of an object by placing it on a weighing scale
    • We say the position of the needle on the scale represents the weight of the object

In each case, the position of the needle or the mercury isn’t actually the temperature or the weight, it is a representation of this property. Thus in both cases, the analogue device works by analogy hence why we call it analogue.

This isn’t the only sense in which “analogue” is used however. It doesn’t always mean an analagous representation of a physical property. We talk about analogue signals as signals that vary continuously and which do not align to digital values.

Digital

Limitations of analogue for computation

From a computing point of view, the data that can be captured and recorded by analogue devices is simply too diverse and non-uniform. Computers are universal machines whereas analogue devices typically only measure one property well. Whereas a computer can record and playback music and take the temperature, to do this in an analogue way would require a complex machine that can represent two unrelated data sources. Imagine if a computer was able to achieve universality through analogue means, it would most likely be very large physically and very complex computationally since the computer would need to be able process data from, e.g. for grooves on vinyl, needles on weighing sensors and mercury in vacuum tubes.

The types of analogue systems used are so different and variable that creating a common computing device that can understand all of them is nearly impossible.

Furthermore:

Computers require highly reliable and accurate representations of certain types of data. Analogue representations of data can be difficult to measure precisely (and are potentially infinite), tend to decay over time, and lose fidelity when copied.

Computers need a way to represent all types of data in a format that can be accurately processed, stored and copied.

Why digital is better suited to computational requirements

A digital system represents data as a sequence of symbols where each symbol is one of a limited set of values.

Computers only use two symbols for each value: 0 and 1.

Although a digital system could use more than two symbols, adding more would increase the complexity and cost of the system. A set of only two symbols allows for simplified hardware and improved reliability.

All data within a computer from images to sounds are sequences of 0s and 1s. In practice, the sequences are stored in various ways. On a CD, the binary digits are stored as bumps (0) or flat spaces (1). On a flash drive, the 1s and 0s are electrical charges etc.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Any.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Any.html deleted file mode 100644 index 0b7040a..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Any.html +++ /dev/null @@ -1,50 +0,0 @@ -Any - My Zettelkasten - - - - -

Any

any is a TS-specific type that we can think of it as a higher level parent to all the other types that exist in TypeScript.

It means in effect that either no type declaration has been asserted or that the TS compiler cannot infer the type that you mean. Because any does not have a data type it is equivalent to all the individual scalar and reference types combined. In TS this kind of type is called a supertype, and specific types that actually correspond to a scalar or reference type are known as subtypes. anyis the supertype of all types and string for example is a subtype of any.

Every value of string can be assigned to its supertypeany but not every value of any can be assigned to its subtype string

You can declare any as a type if you wish however it is discouraged because it effectively undermines the whole purpose of TS. Doing so is basically the same thing as declaring a value in normal JS - there is no designation at left hand assignation of which type the data belongs to.

any reflects JavaScript’s overarching flexibility; you can see it as a backdoor to a world where you want neither tooling nor type safety.

any means you can escape errors during development. If you are using custom types/interfaces and you keep getting an annoying error saying that property X doesn’t exist on type,, any will allow you to overcome it until you go back later and refine.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Apollo_Client.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Apollo_Client.html deleted file mode 100644 index 5a90db0..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Apollo_Client.html +++ /dev/null @@ -1,84 +0,0 @@ -Apollo Client - My Zettelkasten - - - - -

Apollo Client

Apollo Client is the client-side counterpart to Apollo Server. We use it for managing queries and mutations from the frontend to our Apollo GraphQL server. It is specifically designed to work with React.

We will be working with the schema we defined when working on the server

Initializing the client

We initialise the client and set-up in memory caching to reduce network requests:

const client = new ApolloClient({
-  uri: "http://localhost:4000",
-  cache: new InMemoryCache(),
-});

The uri property must match the location of our Apollo server.

Utilising the provider

Apollo provides a top level application context that we can wrap our React app in. This will provide access to the client object from anywhere within the app, eg:

ReactDOM.render(
-  <ApolloProvider client={client}>
-    <GlobalStyles />
-    <Pages />
-  </ApolloProvider>,
-  document.getElementById("root")
-);

Running a query

Queries as entry points

From the client point of view, the queries in the schema are entry points. Although the queries exist in the schema, this alone is not sufficient for them to be entry points. Remember a schema is just a specification or contract between the frontend and the backend, it is not itself executable code.

Therefore, for each query in the schema we must write a frontend implementation. We do this with query constants. The frontend implementation has a backend analogue: the resolver that is invoked when the frontend issues a query. The schema standardises this relationship so that every query on the client must have a corresponding resolver on the backend.

Query constants

To run a query against our server we must define a query contant first. We use a gql literal again:

import { gql } from "@apollo/client";
-const TRACKS = gql`
-  query GetTracks {
-    tracksForHome {
-      id
-      title
-      thumbnail
-      length
-      modulesCount
-      author {
-        name
-        photo
-      }
-    }
-  }
-`;

The convention is to name the query constant in ALL_CAPS.

Note that the name of the query on the client doesn’t have to match the query type defined in the schema (there is no GetTracks in the schema), this is just a client-side designator. However it should reference the schema on the second line (tracksForHome).

useQuery hook

The useQuery hook provides a straightforward wrapper for sending queries and receiving data back from the server.

When a component renders, useQuery returns an object from the Apollo Client that contains loading, error, and data properties.

const { loading, error, data } = useQuery(TRACKS);
-
-const Tracks = () => {
-  const { loading, error, data } = useQuery(TRACKS);
-
-  if (loading) return "Loading...";
-
-  if (error) return `Error! ${error.message}`;
-
-  return <Layout grid>{JSON.stringify(data)}</Layout>;
-};
  • We destructure the loading, error, data variables that are returned from the hook
  • We pass in our query constant as an argument.
  • In the example we just render the serialized data but we could of course pass the data as a prop and map through it in an embedded child component.
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Apollo_Server.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Apollo_Server.html deleted file mode 100644 index c6411b9..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Apollo_Server.html +++ /dev/null @@ -1,144 +0,0 @@ -Apollo Server - My Zettelkasten - - - - -

Apollo Server

Apollo Server is the part of the Apollo suite that we use to create the backend of a GraphQL project: a GraphQL server.

It is able to do the following:

  • Receive an incoming GraphQL query from a client
  • Validate that query against the server schema
  • Populate the queried schema fields
  • Return the fields as a JSON response object

Example schema

We will use the following schema in the examples.

// schema.js
-
-const typeDefs = gql`
-  " Our schema types will be nested here
-`;
-module.exports = typeDefs;
type Query {
-  tracksForHome: [Track!]!
-}
-
-type Track {
-  id: ID!
-    author: Author!
-  thumbnail: String
-  length: Int
-  modulesCount: Int
-}
-
-type Author {
-  id: ID!
-  name: String!
-  photo: String
-}

Setting up the server

We instantiate an ApolloServer instance and pass our schema to it. We then subscribe to it with a listener.

// index.js
-
-const { ApolloServer } = require("apollo-server");
-const typeDefs = require("./schema");
-const server = new ApolloServer({ typeDefs });
-
-server.listen().then(() => {
-  console.log(`
-        Server is running!
-        Listening on port 4000
-        Query at http://localhost:4000
-  `);
-});

When we access the local URL we are able to access the Apollo server using the Explorer GUI. This automatically loads our schema and is basically a more fancy version of GraphiQL:

It makes it easy to read descriptions of the dataypes and to construct queries by clicking to insert fields.

Adding some mock data

We are not connected to a database yet but we can create a mock that will enable us to run test queries.

We do this just by updating the Apollo Server options. We can either use generic dummy data or provide our own mock.

Generic mock

const server = new ApolloServer({ typeDefs, mocks: true });

Custom mock

const mocks = {
-  Track: () => ({
-    id: () => "track_01",
-        author: () => {
-      return {
-        name: "Grumpy Cat",
-        photo:
-          "https://res.cloudinary.com/dety84pbu/image/upload/v1606816219/kitty-veyron-sm_mctf3c.jpg",
-      };
-    },
-    thumbnail: () =>
-      "https://res.cloudinary.com/dety84pbu/image/upload/v1598465568/nebula_cat_djkt9r.jpg",
-    length: () => 1210,
-    modulesCount: () => 6,
-  }),
-};
-
-const server = new ApolloServer({ typeDefs, mocks });

We can now run queries against our server.

Implementing resolvers

A resolver is a function that populates data for a given query. It should have the same name as the field for the query. So far we have one query in our schema: tracksForHome which returns the tracks to be listed on the home page. We must therefore also name our resolver for this query tracksForHome.

It can fetch data from a single data source or multiple data sources (other servers, databases, REST APIs) and present this as a single integrated resource to the client, matching the shape requested.

As per the generic example, you write write your resolvers as keys on a resolvers object, e.g:

const resolvers = {};

The resolvers object’s keys will correspond to the schema’s types and fields. You distinguish resolvers which directly correspond to a query in the schema from other resolver types by wraping them in Query {}.

const resolvers = {
-  Query: {
-    tracksForHome: () => {},
-  },
-};

Resolver parameters

Each resolver function has the same standard parameters that you can invoke when implementing the resolution: resolverFunction(parent, args, context, info).

  • parent
  • args
    • an object comprising arguments provided for the given field by the client. For instance if the client requests a field with an accompanying id argument, id can be parsed via the args object
  • context
    • shared state between different resolvers that contains essential connection parameters such as authentication, a database connection, or a RESTDataSource (see below). This will be typically instantiated via a class which is then invoked within the ApolloServer instance under the dataSources key.
  • info
    • not used so frequently but employed as part of caching

Typically you won’t use every parameter with every resolver. You can ommit them with _, __; the number of dashes indicating the argument placement.

RESTDataSource

A resolver can return data from multiple sources. One of the most common sources is a RESTful endpoint. Apollo provides a specific class for handling REST endpoints in your resolvers: RESTDataSource.

REST APIs fall victim to the “n + 1” problem: say you want to get an array of one resource type, then for each element returned you need to send another request using one of its properties to fetch a related resource.

This is implicit in the case of the Track type in the schema. Each Track has an author key but the Author type isn’t embedded in Track it has to be fetched using an id. In a REST API, this would require a request to a separate end point for each Track returned, increasing the time complexity of the request.

Here is an example of RESTDataSource being used. It is just a class that can be extended and which provides inbuilt methods for running fetches against a REST API:

const { RESTDataSource } = require("apollo-datasource-rest");
-
-class TrackAPI extends RESTDataSource {
-  constructor() {
-    super();
-    this.baseURL = "https://odyssey-lift-off-rest-api.herokuapp.com/";
-  }
-
-  getTracksForHome() {
-    return this.get("tracks");
-  }
-
-  getAuthor(authorId) {
-    return this.get(`author/${authorId}`);
-  }
-}

Using our RESTDataSource in our resolver

As our GraphQL server is sourcing data from a REST API, we can now integrate the RESTDataSource class with our resolver.

First thing, we need to instantiate an instance of our TrackApi class, otherwise we won’t be able to use any of its methods in the resolver.

We will create an instance of this class and pass it into ApolloServer object we established at the beginning. We will pass it to the dataSources key. This will allow us to access it from within the context parameter in our resolver function

We can also get rid of the mocks object since we don’t need it any more. We will replace it with our resolvers constant:

const server = new ApolloServer({
-  typeDefs,
--  mocks,
-+  resolvers,
-+  dataSources: () => {
-+  return {
-+    trackApi: new TrackApi()
-+  }
-  }
-})

Now we can complete our resolver:

const resolvers = {
-  Query: {
-    tracksForHome: (_, __, {dataSources}) => {},
-      return dataSources.trackApi.getTracksForHome()
-  },
-};

So we destructure the dataSources object from the parent Apollo Server instance (in the place of the context parameter) which gives us access to our trackApi class. This resolver will now make the API request and return the tracks.

The tracksForHome query returns Track objects and these have a required author key that returns an Author type. So we are also going to need a resolver that can return the author data that will be populated along with Track.

We already have this functionality in our class: getAuthor so we just need to integrate it:

const resolvers = {
-  Query: {
-    tracksForHome: (_, __, { dataSources }) => {
-      return dataSources.trackApi.getTracksForHome();
-    },
-  },
-  Track: {
-    author: ({ authorId }, _, { dataSources }) => {
-      return dataSources.trackApi.getAuthor(authorId);
-    },
-  },
-};
  • Just as we nest the tracksForHome resolver under Query, we must nest author under Track to match the structure of the schema. This resolver doesn’t respond to a query that is exposed to the client so it shouldn’t go under Query.
  • We invoke the context again when we destructure dataSources from the ApolloServer instance.
  • This time we utilise the args parameter in the resolver since an id will be provided as a client-side argument to return a specific author.

The useMutation hook

We invoke the useMutation hook to issue mutations from the client-side.

As with queries and query constants

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Application_Layer_of_Internet_Protocol.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Application_Layer_of_Internet_Protocol.html deleted file mode 100644 index 3354c68..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Application_Layer_of_Internet_Protocol.html +++ /dev/null @@ -1,50 +0,0 @@ -Application Layer of the Internet Protocol - My Zettelkasten - - - - -

Application Layer of the Internet Protocol

The final, topmost layer of the Internet Protocol suite.

Data at the Application Layer

The Application Layer is where we get to the protocols that describe the behaviour of applications. All the preceding lower levels are effectively plumbing that enables applications to do the things they want accross the internet.

Whereas the lower levels facilitate communication accross the internet, the Application Layer is concerned with achieving a specific task once the ability to communicate is assured.

Application Layer protocols include HTTP, the Simple Mail Transfer Protocol (SMTP), and FTP.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Application_state_management_with_React_hooks.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Application_state_management_with_React_hooks.html deleted file mode 100644 index 7086631..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Application_state_management_with_React_hooks.html +++ /dev/null @@ -1,82 +0,0 @@ -Application state management - My Zettelkasten - - - - -

Application state management

Although React_useReducer and React_useContext have many sound use cases by themselves, when they are combined they offer a way to acheive a system of global state management, without utilising third-party libraries like Redux.

Requirements

The Context API combined with a reducer addresses the following needs:

  • be able to consume global state from anywhere in the component hierarchy without prop-drilling
  • update global state from within child components from anywhere in the component hierarchy
  • access, maintain and update complex structured data (arrays/objects) not just single values, as global state

Implementation

In essence the approach is as follows:

  • Create a context provider that houses the global state object
  • Attach this state to a reducer function that operates on the state object through dispatch methods

First off, our initial state and overall state object:

const initialState = {
-  count: 0,
-};

Next, we create our context. This is what we will invoke when we want to consume our state.

export const CounterContext = React.createContext({});

Now we need a reducer that will handle the state updates. We will just use the same setup as we used in the example of React_useReducer:

function reducer(state, action) {
-  switch (action.type) {
-    case "increase":
-      return { ...state, counter: state.counter + 1 };
-      break;
-    case "decrease":
-      return { ...state, counter: state.counter - 1 };
-      break;
-    case "increase_by_payload":
-      return { ...state, counter: state.counter + action.payload };
-    default:
-      throw new Error();
-  }
-  return newState;
-}

Finally, we need to make a provider as a top-level component that receives the reducer’s state and dispatch methods as props:

export const CounterProvider = ({children}) => {
-    // We pass our reducer function and initial state to useReducer as params
-    const [state, dispatch] = React.useReducer(reducer, initialState)
-
-    // We create our provider and pass the reducer state and update method as props. This is the provider to the CounterContext consumer
-    <CounterContext.Provider value={{state, dispatch}}>
-        {children}
-    </CounterContext.Provider>
-}

Now whenever we want to consume or update our global state, we can invoke the context within a lower-level component, for example:

const {state, dispatch} = useContext(CounterContext);
-
-dispatch({
-    type 'increase_by_payload',
-    payload: 4
-})
-
-console.log(state.counter) // 4
-
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Application_structure.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Application_structure.html deleted file mode 100644 index ae4bb2e..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Application_structure.html +++ /dev/null @@ -1,58 +0,0 @@ -React application structure - My Zettelkasten - - - - -

React application structure

When you use create-react-app it creates a default directory structure that is a sensible one to follow:

build/
-public/
-	index.html
-src/
-	index.js
-	App.js

public/

  • public constains the index.html file via which React connects to the traditional DCOM. Within index.html you have <div id="root">...</div> as the entry point where your application is injected into the standard DOM.

  • Everything in this folder is as per standard web development practice.

  • You shouldn’t include React code here but you can paste necessary links and metadata to the head of index.html

src/

  • It automatically contains index.js . This imports React and ReactDOM and contains the ReactDOM.render() method:
    ReactDOM.render(
    -  <App />
    -document.getElementById('root')
    -);
  • The App component is your parent component and the container for your app. It is where you will import your sub-components.
  • If you are using React Router App becomes the index for the different page components. See Routing for more detail.

build

build houses the compiled version of your application, ready to be deployed to a server. All contents are minified, compressed and optimised using Webpack.

Once you have executed npm run build you can test the output by using serve via the console:

serve -s build

build will comprise a minified version of index.html and a static/ directory which holds your compiled CSS and JS that index.html links to, as per a standard static website.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Arithmetic_Logic_Unit.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Arithmetic_Logic_Unit.html deleted file mode 100644 index a8ed1ee..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Arithmetic_Logic_Unit.html +++ /dev/null @@ -1,50 +0,0 @@ -Arithmetic Logic Unit (ALU) - My Zettelkasten - - - - -

Arithmetic Logic Unit (ALU)

The ALU is the centerpiece or core of the CPU architecture, where the binary calculations occur. All the other components on the CPU chip are appendanges to the execution that occurs within the ALU.

The ALU comprises logic gates that execute the instructions passed from memory and where the data stored by the registers is acted upon. A processor’s ALU is just a complex combinatorial logic circuit.

It executes arithmetic and logical operations on binary numbers and where you will find operations conducted by full-adders and half adders etc.

More specifically, the ALU is responsible for the execute phase of the fetch, decode, execute cycle.

ALU execution lifecycle

  1. Inputs: The ALU receives two operands and a control signal as inputs. The operands are the data on which the operations will be performed. The control signal tells the ALU which operation it needs to perform.
  2. Perform operation: The ALU carries out the requested operation. For instance, if the control signal indicates an addition operation, the ALU sums the two operands.
  3. Output: The ALU then sends the operation to another part of the CPU for further processing or storage. The ALU also outputs a status bit that can be used by other parts of the CPU to make decisions. For instance if the additon results in a value that is too large to be stored, the ALU will set an overflow flag.
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Arrays.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Arrays.html deleted file mode 100644 index 2eadbad..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Arrays.html +++ /dev/null @@ -1,50 +0,0 @@ -Arrays - My Zettelkasten - - - - -

Arrays

Arrays are used both on their own and to implement many other data structures that place additional restrictions on how the data is manipulated.

Algorithmic complexity

In terms of data retrieval arrays have a good runtime since retrieving an element or storing an element takes constant time. Also an entire array takes up O(n) space.

This only applies in the case of strict arrays that exist in strictly typed and more advanced languages such as Java and C++. In JavaScript an array is really closer to a list in other languages. That is to say, it’s size (and of course the types it holds) does not need to be known in advance or specified at all. In stricter languages, you would cast the type for the array and specify its length, for example:

int anArray[10] = { 1, 2, 3, 4,  5, 6, 7, 8, 9, 10 }

Whilst storage and retrieval take place in constant time, deleting and inserting elements through methods like pop and shift are more time consuming, since the index of every item has to be updated in response.

Random access

As we can access any element of the array at any time through index notation, arrays offer random and non-sequential access. This is in contrast to stacks and queues (where only the top/bottom can be accessed) and linked lists.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Assembly.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Assembly.html deleted file mode 100644 index b85f0bd..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Assembly.html +++ /dev/null @@ -1,50 +0,0 @@ -Assembly - My Zettelkasten - - - - -

Assembly

  • Assembly is one level up from machine code and provides a more human-friendly abstraction layer

  • An assembly instruction is a mneumonic that comprises an “op code” plus operands

  • It is translated back to machine code by an assembler for the computer to execute.

Example instruction

We can translate the machine instruction e3a07004 into the assembly instruction mov r7, #4. This translates to: move the value number 4 to the register r7.

Assemblers

Although assembly is useful for humans, computers still work at the level of machine code. Therefore you need an assembler to translate the assembly code to machine code. An assembly language text file is fed into an assembler and a binary object file containing machine code is returned.

A disassembler does the opposite: translate machine code into assembly.

Relation to instruction set architectures

  • the ISA defines the hardware capabilities and the instructions that can be run on the hardware
  • machine code is a binary representation of these instructions and can be directly executed by the CPU
  • humans use an assembly language version of the machine code which is then translated back to machine code for the computer to execute.

Hexadecimal number system, Instruction Set Architectures, CPU architecture

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Associativity.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Associativity.html deleted file mode 100644 index ace5176..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Associativity.html +++ /dev/null @@ -1,50 +0,0 @@ -The Associative Property of Addition and Multiplication - My Zettelkasten - - - - -

The Associative Property of Addition and Multiplication

Let \(a\), \(b\) , \(c\) represent members of \(\mathbb{W}\) or \(\mathbb{Z}\) then:

$$ (a + b) + c = a + (b + c) $$

$$ a \cdot (b \cdot c) = (a \cdot b) \cdot c $$

When grouping symbols (parentheses, brackets, braces) are used with the multiplication and addition of whole numbers and integers, the particular placement of the grouping symbols relative to each of the addends or multiplicands does not change the sum/product.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Atomic_and_molecular_propositions.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Atomic_and_molecular_propositions.html deleted file mode 100644 index af29cb1..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Atomic_and_molecular_propositions.html +++ /dev/null @@ -1,52 +0,0 @@ -Atomic and molecular propositions - My Zettelkasten - - - - -

Atomic and molecular propositions

Propositions are expressions that have truth values, either true or false.

We call a proposition which does not contain a logical connective (or ‘sentential connective’) a simple proposition.

We call a proposition that does contain a logical connective, a compound proposition.

Simple propositions are represented within a formal language of sentential logic with a single character, customarily P or Q. When we refer to the formal representation of such propositions in our system of sentential logic (SL) we call them atomic propositions.

Compound propositions consist in single characters for each atomic proposition that they comprise, combined with a symbol for the logical connective. When we refer to the formal representation of such propositions in SL we call them molecular propositions.

Demonstration

Atomic proposition:

Socrates was a philosopher.
-(P)

Molecular proposition:

Socrates was a philosopher and a drinker.
-(P & Q)

Connectives in natural language often obscure the logical basis of the proposition being expressed (where such a proposition contains a proposition, i.e. excluding propositions that are logically indeterminate. The molecular proposition is above is such an example. In this instance the proposition can be expressed more precisely as:

Socrates was a philosopher and Socrates was a drinker.

Where propositions in natural language cannot be elucidated by the addition of implied logical connectives in the manner above, they must be treated not as molecular propositions but as atomic proposition. Example:

Two splashes of gin and a few drops of vermouth make a great martini.

If we were to formalise this as:

Two splashes of gin make a great martini and a few drops of vermouth make a great martini.

We would lose the sense of the original and we would not be uncovering any logic that is in the original.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Awk.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Awk.html deleted file mode 100644 index 49cb0e7..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Awk.html +++ /dev/null @@ -1,82 +0,0 @@ -Awk - My Zettelkasten - - - - -

Awk

Awk is a programming language designed for text processing and data extraction. It was created in the 1970s and remains widely used today for tasks such as filtering and transforming text data, generating reports, and performing basic calculations. Awk is known for its simplicity and versatility, making it a popular tool for Unix system administrators and data analysts.

Invocation

We can use awk directly in stdin or we can reference .awk files for more elaborate scripts

# CLI
-awk [program] file1, file2, file3
-
-# Script file
-awk -f [ref_to_script_file] file1, file2, file3

We can also pipe to it. This piped command receives output from the echo command and prints the value in the last field for each record:

echo -e "1 2 3 5\n2 2 3 8" | awk '{print $(NF)}'

Syntactic structure

awk is a line-oriented language.

An awk program consists in a sequence of pattern: action statements and optional functional definitions.

For most of the examples we will use this list as the input:

cloud
-existence
-ministerial
-falcon
-town
-sky
-top
-bookworm
-bookcase
-war
-Peter 89
-Lucia 95
-Thomas 76
-Marta 67
-Joe 92
-Alex 78
-Sophia 90
-Alfred 65
-Kate 46

awk particularly lends itself to inputs that are structured by whitespace or in columns, like what you get from commands like ls and grep

Patterns and actions

The basic structure of an awk script is as follows:

pattern {action}

A pattern is what you want to match against. It can be a literal string or a regex. The action is what process you want to execute against the lines in the input that match the pattern.

The following script prints the line that matches Joe:

awk '/Joe/ {print}' list.txt

/Joe/ is the patttern and {print} is the action.

Lines, records, fields

When awk receives a file it divides the lines into records.

Each line awk receives is broken up into a sequence of fields.

The fields are accessed by special variables:

  • $1 reads the first field, $2 reads the second field and so on.

  • The variable $0 refers to the whole record

So, in the picture cloud existence ministerial corresponse to $1 $2 $3

Basic examples

Match a pattern

awk '/book/ { print }' list.txt
-# bookworm
-# bookcase

Print all words that are longer that five characters

awk 'length($1) > 5 { print $0 }' list.txt

For the first field of every line (we only have one field per line), if it is greater than 5 characters print it. The “every line” part is provided for via the all fields variable - $0.

We actually don’t need to include the { print $0 } action, as this is the default behaviour. We could have just put length($1) > 5 list.txt

Print all words that do not have three characters

awk '!(length($1) == 3)' list.txt

Here we negate by prepending the pattern with ! and wrapping it in parentheses.

Return words that are either three characters or four characters in length

awk '(length($1) == 3) || (length($1) == 4)' list.txt

Here we use the logical OR to match against more than one pattern. Notice that whenever we use a Boolean operator such as NOT or OR, we wrap our pattern in parentheses.

Match and string-interpolate the output

awk 'length($1) > 0  {print $1, "has", length($1), "chars"}' list.txt
-
-# storeroom has 9 chars
-# tree has 4 chars
-# cup has 3 chars

Match against a numerical property

awk '$2 >= 90 { print $0 }' scores.txt
-
-# Lucia 95
-# Joe 92
-# Sophia 90

This returns the records where there is a secondary numerical field that is greater than 90.

Match a field against a regular expression

awk '$1 ~ /^[b,c]/ {print $1}' words.txt

This matches all the fields in the $1 place that begin with ‘b’ or ‘c’.

The tilde is the regex match operator. You must be passing a regex to use it, otherwise use ==.

Syntactic shorthands

  • For a statement like awk 'length($1) > 5 { print $0 }' list.txt. We actually don’t need to include the { print $0 } action, as this is the default behaviour and it is implied. We could have just put length($1) > 5 list.txt.

https://zetcode.com/lang/awk/

Built-in variables

NF

The value of NF is the number of fields in the current record. Awk automatically updates the value of NF every time it reads a record.

No matter how many fields there are, the last value in a record can always be represented by $NF.

NR

NR represents the number of records. It is set at the point at which the file is read.

FS

FS represents the field separator. The default field separator is a space. We can specify a different separator with the -F flag. E.g to separate by comma:

awk -F, '{print $1 }' list.txt
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Axioms_of_set_theory.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Axioms_of_set_theory.html deleted file mode 100644 index a4046af..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Axioms_of_set_theory.html +++ /dev/null @@ -1,50 +0,0 @@ -Axioms of set theory - My Zettelkasten - - - - -

Axioms of set theory

The basic notions of set theory are defined in Basic properties of sets. There we introduced a formal syntax that will be utilised to define the axioms. For easy reference:

  • variables \(a,b,c,...\) to range over sets
  • variables \(x,y,z\) to range over ordinary objects as well as sets.

Axiom of Extensionality

Sets which contain the same members are the same set. If sets A and B contain the same elements then A = B. $$\forall a \forall b [\forall x (x \in a \longleftrightarrow x \in b) \rightarrow a =b]$$

beta

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Basic_model_of_the_operating_system.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Basic_model_of_the_operating_system.html deleted file mode 100644 index 9d904f0..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Basic_model_of_the_operating_system.html +++ /dev/null @@ -1,77 +0,0 @@ -Basic model of a nix operating system - My Zettelkasten - - - - -

Basic model of a nix operating system

We can abstract the Linux OS into three operational levels or tiers, from the bottom up:

-
User processes: user space
-
The running programs that the kernel manages. Also known as the user space which is the memory that the kernal assigns for user processes. Comprising: -
    -
  • Graphical user interface
  • -
  • Servers
  • -
  • Shell
  • -
-
Kernel: kernel space
- -
The core of the operating system. Software residing in memory that tells the CPU where to look for its next task. Acts as a mediator and primary interface between the hardware and the user processes. Known as kernel space: the memory that the kernel allocates for itself. Comprising: -
    -
  • System calls
  • -
  • Process management
  • -
  • Memory management
  • -
  • Device drivers
  • -
-
-
Hardware
-
The base: one or more CPUs and RAM memory performing computations and writing to memory. Comprising: -
    -
  • Processor (CPU)
  • -
  • Main memory (RAM)
  • -
  • Disks
  • -
  • Network ports
  • -
-
-

!! Add info on kernel mode and user mode https://www.geeksforgeeks.org/user-mode-and-kernel-mode-switching/

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Basic_prop_passing_in_React.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Basic_prop_passing_in_React.html deleted file mode 100644 index 8d7f893..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Basic_prop_passing_in_React.html +++ /dev/null @@ -1,69 +0,0 @@ -Test: Basic prop passing - My Zettelkasten - - - - -

Test: Basic prop passing

import { render, screen } from "@testing-library/react";
-
-describe("<CertificateHtml />", () => {
-  it("should render the values passed as props", () => {
-    // Arrange:
-    const stub = {
-      titleOfActivityOrProgramme: "Filming",
-      nameOfDepartment: "The film department",
-    };
-
-    // Act:
-    render(<CertificateHtml {...stub} />);
-
-    // Assert:
-    expect(screen.getByText("Filming")).toBeInTheDocument();
-    expect(screen.getByText("The film department")).toBeInTheDocument();
-  });
-});

Or, loop:

for (const entry of Object.values(stub)) {
-  expect(screen.getByText(entry)).toBeInTheDocument();
-}
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Basic_properties_of_sets.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Basic_properties_of_sets.html deleted file mode 100644 index 6530834..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Basic_properties_of_sets.html +++ /dev/null @@ -1,50 +0,0 @@ -Basic properties of sets - My Zettelkasten - - - - -

Basic properties of sets

Set theory

Set theory is a sub-discipline of both mathematics and formal logic. In mathematics it is used as a universal framework for describing other mathematical theories. It is also utilised in computer science and linguistics.

It is useful because it provides tools for modelling an extraordinary variety of structures.

Set theory and the theory of infinite sets was created by Georg Cantor (1845-1918), a German mathematician.

Method of formalisation

We can use the symbols of predicate logic to simplify and clarify natural language expression of set-theoretic principles. There are different ways to do this but we will use the standard quantifiers and:

  • variables \(a,b,c,...\) to range over sets
  • variables \(x,y,z\) to range over ordinary objects as well as sets.

More generally we will use capital Latin letters (\(A, B, ...\)) to denote some specific set, i.e not a generalised/quantified notion of a set.

Example

’Everything is a member of some set or another:

$$ \forall x \exists a (x\in a) $$

What are sets?

A set is a collection of objects. In mathematics the objects are mathematical objects.

A finite set:

$$ BG = { \textsf{Barry, Maurice, Robin}} $$

An infinite set:

$$ I = {1, 2, 3, 4, ...} $$

When we use braces to indicate the members of a set we are providing a list description of the set.

Set membership

If a set S is a collection of objects, to say that object x is a member of S is just to say that x is one of those objects.

We might also express this in natural language as:

  • the object x is an element of the set S
  • the object x belongs to S
  • the set S contains the object x

Formally, we use epsilon to express set membership:

$$ x \in A $$

This asserts that x is a member of the set A.

The negation of this proposition is expressed:

$$ x \notin A $$

This asserts that x is not a member of the set A.

Subsets

Set A is a subset of set B if every member of A is also a member of B.

For example the set of women is a subset of the set of humans because every woman is a human. We express subset relations like so:

$$ A \subseteq B $$

This asserts that set A is a subset of set B.

The negation of this proposition is expressed:

$$ A \not\subset B $$

We must not confuse the relation of being a subset with being a member. Jane is a member of the set of women but Jane is not a subset of the set of women since Jane is not herself a set, she is an object/individual member.

There is also the notion of a proper subset.

If subset A of B is a proper subset of B then B contains some elements that are not in A.

In other words, if B contains objects other than/ in addition to A.

$$ A \subset B $$

This asserts that set A is a proper subset of set B.

For example, the set of women is a proper subset of the set of humans because the set of humans also includes the set of men. If there were only women and no men, then the set of women would be a subset of the set of humans.

Supersets

If A is a subset of B then we say that B is a superset of A. Being a superset, B contains every object of A and may also contain other objects in addition to A. This is just a different way of asserting that A is a proper subset of B.

$$ B \supseteq A $$

This asserts B is a superset of A. The negation:

$$ B \not\supset A $$

This asserts that B is not a superset of A.

Resources

symbols.html

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Basics_of_web_components.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Basics_of_web_components.html deleted file mode 100644 index 3d60df3..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Basics_of_web_components.html +++ /dev/null @@ -1,59 +0,0 @@ -Basics of Web Components - My Zettelkasten - - - - -

Basics of Web Components

Web Components are custom HTML elements like those we create with frameworks like React and Angular but which are native to HTML and the DOM and therefore do not require any special compilation or libraries.

  • Designed to be interoperable with normal HTML
  • Designed to be interoperable with component frameworks like React
  • Designed to be highly modular and reusable
  • Utilise the shadow DOM which is like the virtual DOM but native to the browser and invocable through plain JavaScript. A bit like an iFrame within the “light” DOM and helps greatly with style-scoping.

Example of composing a web component:

// MyComponent.js
-class MyComponent extends HTMLElement {
-  connectedCallback() {
-    this.innerHTML = `<h1>Hello world</h1>`;
-  }
-}
-
-customElements.define("my-component", MyComponent);
-``;
<!-- index.html -->
-<my-component></my-component>

Resources

A complete introdution to Web Components

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Biconditional_Elimination.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Biconditional_Elimination.html deleted file mode 100644 index bcddbd5..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Biconditional_Elimination.html +++ /dev/null @@ -1,50 +0,0 @@ -Biconditional Elimination - My Zettelkasten - - - - -

Biconditional Elimination

Give that the biconditional means that if \(P\) is the case, \(Q\) must be the case and if \(Q\) is the case, \(P\) must be the case, if we have \(P \leftrightarrow Q\) and \(P\), we can derive \(Q\) and vice versa.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Biconditional_Introduction.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Biconditional_Introduction.html deleted file mode 100644 index 4fa33ab..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Biconditional_Introduction.html +++ /dev/null @@ -1,50 +0,0 @@ -Biconditional introduction - My Zettelkasten - - - - -

Biconditional introduction

The biconditional means if \(P\) is the case, \(Q\) must be the case and if \(Q\) is the case, \(P\) must be the case. Thus to introduce this operator we must demonstrate both that \(Q\) follows from \(P\) and that \(P\) follows from \(Q\). We do this via two sub-proofs.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Binary_addition.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Binary_addition.html deleted file mode 100644 index 46bbffc..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Binary_addition.html +++ /dev/null @@ -1,79 +0,0 @@ -Binary addition - My Zettelkasten - - - - -

Binary addition

  • We add binary values in columns just like we would with denary addition.
  • Each column is classified on the basis of place-value. In denary this is 10, in binary it is 2.
  • When we conduct a binary addition, we add the binary values as if they were normal integers but we represent the sums as binary.
    • For example: \(1 + 1 = 2\) for the calculation but the sum is \(10\)

Examples

Example one

$$ -1010 + 0111 = 10001 -$$

$$ -10 + 7 = 17 -$$

In the first column: \(1 + 0 = 1\), so we simply put the binary value for \(1\):

1010
-0111
-____
-   1

In the second column: \(1 + 1 = 2\). In binary this is represented as \(10\). So we put \(0\) beneath the bar and carry the \(1\):

 1
-1010
-0111
-____
-  01

In the third column, we repeat the previous process. We are presented with \(1 + 0 + 1\) which is \(2\). As \(2\) is \(10\) in binary, we put the zero beneath the line and carry the \(1\):

11
-1010
-0111
-____
- 001

In the final column, we again have \(1+1\) giving us \(2\) or \(10\) but at this point we cannot carry any more because we have reached the final column. So instead of carrying the \(1\) we just put both digits beneath the line \(10\).

 11
- 1010
- 0111
-_____
-10001

Example two

$$ -1001 + 0111 = 10000 -$$

$$ -9 + 7 = 16 -$$

 111
- 1001
- 0111
-_____
-10000
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Binary_arithmetic.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Binary_arithmetic.html deleted file mode 100644 index 7f7e8a5..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Binary_arithmetic.html +++ /dev/null @@ -1,50 +0,0 @@ -Binary multiplication - My Zettelkasten - - - - -

Binary multiplication

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Binary_colour_encoding.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Binary_colour_encoding.html deleted file mode 100644 index a4469e2..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Binary_colour_encoding.html +++ /dev/null @@ -1,50 +0,0 @@ -Binary encoding of colours - My Zettelkasten - - - - -

Binary encoding of colours

The approach to encoding binary representations of colour is very similar to the approach we explored when looking at the encoding of Text_encoding.

We begin by determining the total number of colours and colour shades we want to represent. With this value established we then decide on the bit-length required that will accomodate this number of variations. Finally, we assign a binary number to each representation.

Greyscale

We can start with a limited palette: greyscale. Here there is black and white and number of interim shades of grey. The convention is to use an 8-bit number which, given \(2^8 = 256\) provides 256 shade variations.

In decimal, 0 is equal to black (zero light intensity) and 255 is equal to white (full light intensity). Some examples of this (including binary and hex representations are below):

Colour encoding

A single 8-bit number is sufficient for 256 greyscale combinations but with colour, the convention is to use three 8-bit numbers where each byte corresponds to a value for red, green and blue (RGB). Thus the overall bit-length is 24 (\(2^3 + 2^3 + 2^3\)). Each value corresponds to a light intensity for the given colour. Combined they are capable of representing all colours.

Some examples below

Red

Red is represented in RGB with all 8 red bits to set to 1 and the remaining 16 bits for the other two colours set to 0.

Yellow

Yellow is represented in RGB with both red and blue set to 1 and the remaining 8 green bits set to ):

Binary encoding of images

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Binary_encoding.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Binary_encoding.html deleted file mode 100644 index f2293b8..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Binary_encoding.html +++ /dev/null @@ -1,54 +0,0 @@ -Binary encoding - My Zettelkasten - - - - -

Binary encoding

We know that everything going on in a computer is the manipulation of binary digits. Thus all data must ultimately reduce to binary numbers manipulated through logic circuits.

Encoding is the process of establishing a correspondence between sets of binary numbers and sets of symbols that are representative of a given type of data. For certain fundamental data types, for example alphanumeric characters and colours, there are agreed standards of encoding such that, for example, that 111111 (binary) and 3F (hex) always corresponds to the character ?. The reverse is obviously decoding: deriving the data/ symbol from the binary format.

An encoding system maps each symbol to a unique sequence of bits. A computer then interprets that sequence of bits and displays the apppropriate symbol to the user.

The length of the binary number (sometimes called the word length) corresponding to 8-bit, 16-bit, 32-bit etc. that is used to represent a given data set is determined by the number of variations that you require to capture the entire range of the dataset:

An \(n\)-bit binary system can encode \(2^n\) different things

For example, say we know that there are 18 levels to a computer game. To encode a reference for each level we would need a binary number that is capable of at least 18 total variations. In this instance a 32-bit (\(2^{5}\) ) number would be best because the next smallest (16-bit) would not be sufficient. Our levels would have representations as follows:

00001 (1)
-00010 (2)
-00011 (3)
-00100 (4)
-...

Think about when you open a file format in a text editor that cannot decode it. For example trying to open a Word document in VSCode. The mangled letters it displays is the encoded binary data. When you open the file in Word, the decoding is applied and it resembles what you would expect.

When we save a file, the different file extensions denote different formats and these are encoding formats. For example if you save an image file as .png rather than .jpg, you are applying a different encoding algorithm to the data that compresses the raw binary data in a different way.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Binary_encoding_of_text.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Binary_encoding_of_text.html deleted file mode 100644 index 19234fb..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Binary_encoding_of_text.html +++ /dev/null @@ -1,50 +0,0 @@ -Text encoding - My Zettelkasten - - - - -

Text encoding

Text encoding is an applied instance of binary encoding.

ASCII

There are around 100 characters in total required to render A-Z, a-z, 0-9 and the special characters of Lating text. The ASCII (American Standard Code for Information Interchange) system achieves this with 8-bit code. Thus, each character symbol corresponds to a byte. As \(2^8 = 256\), this allows for a total of 256 characters (where only 7-bits are sufficient, a leading 0 is added).

Below are some examples of the ASCII correspondences:

BinaryHexCharacter
0010000020[space]
0010000121!
0010101122B+

However there are only 128 characters represented in ASCII, thus using 256-bits is somewhat excessive. This lead people to try and use the remaining, free 128 bits to accommodate characters from non-English languages. This was quickly found to be insufficient, necessitating the development of a new encoding standard, Unicode…

Unicode and UTF-8

Whereas ASCII only encodes 128 English alphanumeric characters, the scope of Unicode is much broader, as such it is a superset of ASCII (every character in ASCII is in Unicode but not the converse). Unicode is a universal character encoding that defines every character in every spoken language of the world. The Unicode standard is maintained by the Unicode Consortium and defines more than 1,40,000 characters from more than 150 modern and historic scripts along with emoji.

In contrast to ASCII, it doesn’t achieve this by mapping every character to a bit. Instead it provides an abstract representation of every character which is then encoded using a designated encoding protocol, such as UTF-8, UTF-16, UTF-32 etc. These abstract representations are called “code-points” and are represented as hexadecimal numbers between 0xO - 0x10FFFF (1114111), prepended by U+, for example U+00F7 which is the sign for division.

As the encoding names suggest they encode to different bit sizes:

  • UTF-8 and UTF-16 are variable length encodings.
  • In UTF-8, a character may occupy a minimum of 8 bits.
  • In UTF-16, a character length starts with 16 bits.
  • UTF-32 is a fixed length encoding of 32 bits.

Unicode can be stored using several different encodings, which translate the character codes into sequences of bytes. So, crucially Unicode is not itself an encoding.

UTF-8 uses the ASCII set for the first 128 characters. That’s handy because it means ASCII text is also valid in UTF-8.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Binary_number_system.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Binary_number_system.html deleted file mode 100644 index 2f19f94..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Binary_number_system.html +++ /dev/null @@ -1,64 +0,0 @@ -Binary number system - My Zettelkasten - - - - -

Binary number system

Decimal (denary) number system

Binary is a positional number system, just like the decimal number system. This means that the value of an individual digit is conferred by its position relative to other digits. Another way of expressing this is to say that number systems work on the basis of place value.

In the decimal system the columns increase by powers of 10. This is because there are ten total integers in the system:

\(1, 2, 3, 4, 5, 6, 7, 8, 9\)

When we have completed all the possible intervals between \(0\) and \(9\), we start again in a new column.

The principle of counting in decimal:

0009
-0010
-0011
-0012
-0013
-...
-0019
-0020
-0021

Thus each column is ten times larger than the previous column:

  • Ten (\(10^1\)) is ten times larger than one (\(10^0\))
  • A hundred (\(10^2\)) is ten times larger than ten (\(10^1\))

We use this knowledge of the exponents of the base of 10 to read integers that contain multiple digits (i.e. any number greater than 9).

Thus 264 is the sum of

$$[4 \cdot (10^0)] + [6 \cdot (10^1)] + [2 \cdot 10^2] $$

Binary number system

In the binary number system, the columns increase by powers of two. This is because there are only two integers: 0 and 1. As a result, you are required to begin a new column every time you complete an interval from 0 to 1.

So instead of:

$$ 10^0, 10^1, 10^2, 10^3 ... (1, 10, 100, 1000) $$

You have:

$$ 2^0, 2^1, 2^2, 2^3, 2^4... (0, 2, 4, 8, 16) $$

When counting in binary, we put zeros as placeholders in the columns we have not yet filled. This helps to indicate when we need to begin a new column. Thus the counting sequence:

$$ 1, 2, 3, 4 $$

is equal to:

$$ 0001, 0010, 0011, 0100 $$

Counting in binary:

000000
-000001
-000010
-000011
-000100
-000101
-000111

Binary prefix

To distinguish numbers in binary from decimal or hexadecimal numbers, it is common to use the prefix 0b. Thus, e.g, 0b110 for decimal 6.

Converting decimal to binary

Let’s convert 6 into binary:

If we have before us the binary place values (\(1, 2, 4, 8\)). We know that 6 is equal to: 1 in the two column and 1 in the 4 column → 110

More clearly:

And for comparison:

Or we can express the binary as:

$$ (1 _ 2) + (1 _ 4) $$

Or more concisely as:

$$ 2^1 + 2^2 $$

Another example

Let’s convert 23 into binary:

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Binary_units_of_measurement.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Binary_units_of_measurement.html deleted file mode 100644 index 54a04d4..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Binary_units_of_measurement.html +++ /dev/null @@ -1,53 +0,0 @@ -Binary units of measurement - My Zettelkasten - - - - -

Binary units of measurement

A single place or symbol in a decimal number is called a digit. For example the number 343 is a number containing three digits. A digit can be any one of the ten numerals through 0-9.

The equivalent entity in the binary number system is the bit. For example the binary number 110 has three bits. A bit can only have one of two values in contrast to a digit which can have one of ten values. These values are 0 and 1.

Sequences of bits

Informational complexity

The informational complexity of a single digit is much larger than a single bit: it can represent one of 10 states whereas a bit can only represent one of two states.

We can think of how much data can be stored in a number in terms of the total number of unique arrangements of bits or digits. With this in mind, compare a two digit digital number to a two bit binary number. For the decimal number each digit can represent one of ten states, hence the total number of unique states is equal to \(2^{10} (1024)\):

With the binary number we have \(2^{2} (4)\), giving us far fewer possible unique states. They are so few we can easily list them:

00
-01
-10
-11

Bytes

In order to express larger binary numbers and greater complexity we work with sequences of bits.

The standard base sequence of bits is called a byte. This is a binary number comprising eight bits. For example the number 11001110 is a byte equivalent to 206 in decimal.

A byte allows for a complexity of up to 256 possible states: \(2^{8} = 256\)

Metric units: kilobytes, megabytes etc

Having established that the core quantity of information is the byte, the convention is to apply the standard metric prefixes to the byte to establish units:

PrefixSymbolExpression as base ten exponentValueEnglish word
Terra-T\(10^{12}\)1,000,000,000,000trillion
Giga-G\(10^9\)1,000,000,000billion
Mega-M\(10^6\)1,000,000million
Kilo-k\(10^3\)1,000thousand

Hence 2MB is two million bytes, 4kb is four thousand bytes etc.

Whilst the metric prefixes are conventionally used to refer to aggregates of bytes, they are only approximate values due to the fact that metric is base ten whereas bytes are base two. Hence 1MB is not 1,000,000 bytes it is 1,048,576 bytes.

This is usually fine as a shorthand but an accurate representation of byte values is as follows:

PrefixSymbolExpression as base two exponentValueEnglish word
Terra-T / Ti\(2^{40}\)1,099,511,627,776trillion
Giga-G / Gi\(2^{30}\)1,073,741,824billion
Mega-M / Mi\(2^{20}\)1,048,576million
Kilo-k / Ki\(2^{10}\)1,024thousand

A special IEEE standard was introduced to distinguish base two within the metric nomenclature: kibi, mebi, gibi etc but this was not widely adopted. The symbols for this are included above as they are sometimes used by Linux programs (Gi, Mi, Ki etc)

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Bitwise_operators.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Bitwise_operators.html deleted file mode 100644 index 78a0c6b..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Bitwise_operators.html +++ /dev/null @@ -1,57 +0,0 @@ -Bitwise operators - My Zettelkasten - - - - -

Bitwise operators

In addition to mathematical, logical and comparison operators, there are bitwise operators. These operators execute conditions based on the actual bits of a value rather than the values that the bits are encoded to represent.

Bitwise operators are typically represented with single characters of existing operators, e.g. & instead of &&:

Bitwise operationOperator
AND&
OR(single pipe)
NOT~

An example of using the & operator:

x = 5
-y = 3
-a = x & y
-b = x | y

The value of a will be 1. The reason is we are looking at the bit values of x and y and then applying Boolean AND to each bit:

x = 5 = 0101
-y = 3 = 0011
-a = 1 = 0001

Working from right to left for each column:

  • true and true = true
  • false and true = false
  • true and false = false
  • false and false = false

This leaves us with 0001 which is equal to 1 in binary and denary.

For the case of bitwise OR we get 7 as the result of x | y:

x = 5 = 0101
-y = 3 = 0011
-b = 7 = 0111
  • true or true = true
  • false or true = true
  • true or false = true
  • false or false = true

This leaves us with 0111 which is equal to 7 in denary.

Why use them?

Bitwise operations are more of a hallmark of lower-level programming. As bit operations are the fastest and lowest level of computation, being able to directly access and operate on bits within a programming language can be beneficial when efficiency and speed of execution is a factor or when memory is constrained.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Bluetooth.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Bluetooth.html deleted file mode 100644 index 542cbb2..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Bluetooth.html +++ /dev/null @@ -1,56 +0,0 @@ -Bluetooth - My Zettelkasten - - - - -

Bluetooth

Connect to devices with bluetoothctl

# Start bluetooth first
-bluetoothctl power on

Then:

# Launch bluetoothctl
-bluetoothctl

This initiates [bluetooth] # prompt. Then follow this sequence:

[bluetooth]# agent on
-[bluetooth]# default-agent
-[bluetooth]# scan on
-pair [device_code]
-connect [device_code]
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Boolean_algebra.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Boolean_algebra.html deleted file mode 100644 index 50df469..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Boolean_algebra.html +++ /dev/null @@ -1,84 +0,0 @@ -Boolean algebra - My Zettelkasten - - - - -

Boolean algebra

Algebraic laws

Many of the laws that obtain in the mathematical realm of algebra also obtain for Boolean expressions.

The Commutative Law

$$ -x \land y = y \land x \\ -$$

$$

x \lor y = y \lor x

$$

Compare the Commutative Law in the context of arithmetic.

The Associative Law

$$ -x \land (y \land z) = (x \land y) \land z -$$

$$ -x \lor (y \lor z) = (x \lor y) \lor z -$$

Compare the Associative Law in the context of arithmetic.

The Distributive Law

$$ -x \land (y \lor z) = (x \land y) \lor (x \land z) -$$

$$ -x \lor (y \land z) = (x \lor y) \land (x \lor z) -$$

Compare how the Distributive Law applies in the case of algebra based on arithmetic:

$$ -a \cdot (b + c) = a \cdot b + a \cdot c -$$

Double Negation Elimination

$$ -\lnot \lnot x = x -$$

Idempotent Law

$$ -x \land x = x -$$

Combining a quantity with itself either by logical addition or logical multiplication will result in a logical sum or product that is the equivalent of the quantity

DeMorgan’s Laws

In addition we have DeMorgan’s Laws which express the relationship that obtains between the negations of conjunctive and disjunctive expressions:

$$ -\lnot(x \land y) = \lnot x \lor \lnot y -$$

$$ -\lnot (x \lor y) = \lnot x \land \lnot y -$$

Applying the laws to simplify complex Boolean expressions

Say we have the following expression:

$$ -\lnot(\lnot(x) \land \lnot (x \lor y)) -$$

We can employ DeMorgan’s Laws to convert the second conjunct to a different form:

$$ -\lnot (x \lor y) = \lnot x \land \lnot y -$$

So now we have:

$$ -\lnot(\lnot(x) \land (\lnot x \land \lnot y )) -$$

As we have now have an expression of the form P and (Q and R) we can apply the Distributive Law to simplify the brackets (P and Q and R):

$$ -\lnot( \lnot(x) \land \lnot(x) \land \lnot(y)) -$$

Notice that we are repeating ourselves in this reformulation. We have \(\lnot(x) \land \lnot(x)\) but this is just the same \(\lnot(x)\) by the principle of idempotence. So we can reduce to:

$$ -\lnot(\lnot(x) \land \lnot(y)) -$$

This gives our expression the form of the first DeMorgan Law (\(\lnot (P \land Q)\)), thus we can apply the law (\(\lnot P \lor \lnot Q\)) to get:

$$ -\lnot(\lnot(x)) \lor \lnot(\lnot(y)) -$$

Of course now we have two double negatives. We can apply the double negation law to get:

$$ -x \lor y -$$

Truth table

Whenever we simplify an algebraic expression the value of the resulting expression should match that of the complex expression. We can demonstrate this with a truth table:

\(x\)\(y\)\(\lnot(\lnot(x) \land \lnot (x \lor y))\)\(x \lor y\)
0000
0111
1011
1111

Significance for computer architecture

The fact that we can take a complex Boolean function and reduce it to a simpler formulation has great significance for the development of computer architectures, specifically logic gates. It would be rather resource intensive and inefficient to create a gate that is representative of the complex function. Whereas the simplified version only requires a single OR gate.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Boolean_function_synthesis.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Boolean_function_synthesis.html deleted file mode 100644 index a4e01a5..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Boolean_function_synthesis.html +++ /dev/null @@ -1,62 +0,0 @@ -Boolean function synthesis - My Zettelkasten - - - - -

Boolean function synthesis

When we looked at boolean functions we were working in a particular direction: from a function to a truth table. When we do Boolean function synthesis we work in the opposite direction: from a truth table to a function.

This is an important skill that we will use when constructing Digital_circuits. We will go from truth conditions (i.e. what we want the circuit to do and when we want it to do it) to a function expression which is then reduced to its simplest form and implemented with logic gates. Specifically, NAND gates.

We will show here that a complex logical expression can be reduced to an equivalent expression that uses only the NAND operator.

The process

The process proceeds as follows:

  1. Work out the truth conditions for the circuit we want to construct
  2. Identify the rows where the output is equal to 1
  3. For each of these rows construct a Boolean expression that evaluates to that output
  4. Join each expression with OR
  5. Reduce these expressions to a single expression in its simplest form

Example

Let’s say we have the following truth table:

Line\(x\)\(y\)\(z\)\(f\)
10000
20010
30101
40110
51001
61010
71100
81110

We only need to focus on lines 1, 3, and 5 since they have the output 1:

Line\(x\)\(y\)\(z\)\(f\)
10001
30101
51001

For each line we construct a Boolean expression that would result in the value in the \(f\) column. In other words we construct the function:

Line\(x\)\(y\)\(z\)\(f\)
1000\(\lnot(x) \land \lnot (y) \land \lnot(z)\)
3010\(\lnot(x) \land y \land \lnot(z)\)
5100\(x \land \lnot(y) \land \lnot(z)\)

We can now join each expression to create a complex expression that covers the entire truth table using OR:

$$ -(\lnot(x) \land \lnot (y) \land \lnot(z)) \\ \lor \\ (\lnot(x) \land y \land \lnot(z)) \\ \lor \\ (x \land \lnot(y) \land \lnot(z)) -$$

It’s clear that we have transcribed the truth conditions accurately but that we are doing so in a rather verbose way. We can simplify by just looking at the position of the 1s in the truth table. Notice:

  • \(z\) is always 0
  • \(x\) and \(y\) are either 0 or 1 but never both 1 in the same row

So we simplify:

$$ -(\lnot(x) \land \lnot(z)) \lor (\lnot(y) \land \lnot(z)) -$$

Notice that \(\lnot(z)\) is repeated so we can remove the repetition through idempotence:

$$ -\lnot z \land (\lnot(x) \lor \lnot(y)) -$$

The upshot is that we now have a simpler expression that uses only NOT, OR and AND. These are the fundamental logic gates thus we are able to construct a circuit that embodies the logic of the expression.

This is important and is an instance of the general theorem that any Boolean function can be represented using an expression containing AND, OR and NOT operations

But even this is too complex. We could get rid of the OR and just use AND and NOT:

We can prove this theorem by showing that an expression with AND, NOT, and OR can be formulated as an equivalent expression using just NOT and AND:

$$ -x \lor y = \lnot(\lnot(x) \land \lnot(y)) -$$

\(x\)\(y\)\(x \lor y\)\(\lnot(\lnot(x) \land \lnot(y)\)
0000
0111
1011
1111

Finally, we can simplify even further by doing away with AND and NOT and using a single NAND gate which embodies the logic of both, being true in all instances where AND would be false: \(\lnot (x \land y)\).

Let’s prove the theorem that every logical expression can be formulated as a NAND function. To do this we need to show that both NOT and AND can be converted to NAND.

NOT:

$$ -\lnot(x) = x \lnot\land x -$$

AND:

$$ -x \land y = \lnot(x \lnot\land y) -$$

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Boolean_functions.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Boolean_functions.html deleted file mode 100644 index f533b85..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Boolean_functions.html +++ /dev/null @@ -1,52 +0,0 @@ -Boolean functions - My Zettelkasten - - - - -

Boolean functions

An example of a Boolean function:

$$ -f(x,y,z) = (x \land y) \lor (\lnot(x) \land z ) -$$

Here is a work through where \(f(1, 0, 1)\):

  • The first disjunction : \(\lnot(x) \land z\) is false because \(x\) is 1 and \(z\) is 0
  • The second disjunction: \(x \land y\) is false because \(x\) is 1 and \(y\) is 1
  • The overall function returns false because the main connective is disjunction and both of its disjuncts are false

We can compute all possible outputs of the function by constructing a Truth-tables with each possible variable as the truth conditions and the output of the function as the truth value:

\(x\)\(y\)\(z\)\(f(x,y,z) = (x \land y) \lor (\lnot(x) \land z )\)
0000
0011
0100
0111
1000
1010
1101
1111
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Boot_process.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Boot_process.html deleted file mode 100644 index 01c55b5..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Boot_process.html +++ /dev/null @@ -1,88 +0,0 @@ -The boot process - My Zettelkasten - - - - -

The boot process

The primary or boot partition of a harddisk contains a bootloader. It is the job of the bootloader to locate the kernel on the harddrive and inject it into memory so that they operating system can start. This is the boot process.

Boot loaders

The boot loader loads the kernel into memory from the disk and then starts the kernel with a set of kernel parameters.

Like the kernel itself, the boot loader requires a driver in order to access the disk but it can’t use the same one as the kernel since at this point, the kernel is not yet loaded into memory. So it has its own special driver: this is either the BIOS or the UEFI firmware.

A boot loader’s core functionality includes the ability to do the following:

  • select from multiple kernels
  • switch between sets of kernel parameters
  • provide support for booting other operating systems

BIOS and UEFI

BIOS and UEFI are both firmware that is installed directly on the motherboard of the computer. They are firmware because they are software that is permanent and programmed into read-only memory.

In the context of disks, their most crucial role is locating the operating system on the harddisk and loading it into memory so that the bootstrapping process can begin. However they are also responsible for the computer clock and the management of peripherals.

As we can see from the fdisk readout, the boot partition uses EFI, the storage partition associated with UEFI.

Device            Start        End   Sectors   Size Type
-/dev/nvme0n1p1     2048    1001471    999424   488M EFI System
-/dev/nvme0n1p2  1001472   59594751  58593280  27.9G Linux filesystem
-/dev/nvme0n1p3 59594752 1000214527 940619776 448.5G Linux filesystem

Whilst UEFI is installed on the hardware, most of its configuration is stored in the EFI partition on the disk, whereas with BIOS, everything is on the chip. This makes booting faster with UEFI.

Even though most modern computers use UEFI, it may still be referred to as BIOS for user-continuity (for instance on WIndows). With Linux you have to explicitly create your boot process so the two are clearly distinguishable.

GRUB

The de facto standard boot loader for Linux is GRUB: Grand Unified Boot Loader.

You see the GRUB default menu when you first start a Linux machine. It will offer you various options for loading your installed OS or other OSs. GRUB is a filesystem like the main disk. If you press e in this screen you can view and edit specific boot parameters. Pressing c gives you access to the GRUB command line interface. This allows you to interact with GRUB in the same way as you would with any other filesystem, allowing for advanced configuration.

The boot sequence

  1. The machine’s BIOS or boot firmware (in the case of UEFI) loads and runs a boot loader. It finds the bootloader by looking for the part of the disk that contains either the MBR or GPT sector.
  2. The boot loader finds the kernel image on disk, loads it into memory and starts it.
  3. The kernel initializes the devices and its drivers.
  4. The kernel mounts the root filesystem.
  5. The kernel starts a program called init. It has a process id of 1. This is the point at which user space starts.
  6. Init sets the rest of the system processes in motion.
  7. At the end of the boot process, init starts a process allowing you to log in.

Boot diagnostics

Linux keeps a log of the boot process as part of the journal log of everything that happens on disk. We can use the command journalct -k to view the diagnostics generated during the boot. Here is a selection:

Jul 07 07:12:58 archbish kernel: Linux version 5.18.5-arch1-1 (linux@archlinux) (gcc (GCC) 12.1.0, GNU ld (GNU Binutils) 2.38) #1 SMP PREEMPT_DYNAMIC Thu, 16 Jun 2022 20:40:45 +0000
-Jul 07 07:12:58 archbish kernel: Command line: BOOT_IMAGE=/boot/vmlinuz-linux root=UUID=2ee6b834-0857-49dc-b8ba-a24d46d228ae rw loglevel=3 quiet
-Jul 07 07:12:58 archbish kernel: x86/fpu: Supporting XSAVE feature 0x002: 'SSE registers'
-Jul 07 07:12:58 archbish kernel: x86/fpu: Supporting XSAVE feature 0x004: 'AVX registers'
-Jul 07 07:12:58 archbish kernel: x86/fpu: Supporting XSAVE feature 0x020: 'AVX-512 opmask'
-Jul 07 07:12:58 archbish kernel: x86/fpu: Supporting XSAVE feature 0x040: 'AVX-512 Hi256'
-Jul 07 07:12:58 archbish kernel: x86/fpu: xstate_offset[2]:  576, xstate_sizes[2]:  256
-Jul 07 07:12:58 archbish kernel: x86/fpu: xstate_offset[5]:  832, xstate_sizes[5]:   64
-Jul 07 07:12:58 archbish kernel: x86/fpu: xstate_offset[6]:  896, xstate_sizes[6]:  512
-Jul 07 07:12:58 archbish kernel: x86/fpu: xstate_offset[7]: 1408, xstate_sizes[7]: 1024
-Jul 07 07:12:58 archbish kernel: x86/fpu: xstate_offset[9]: 2432, xstate_sizes[9]:    8
-Jul 07 07:12:58 archbish kernel: x86/fpu: Enabled xstate features 0x2e7, context size is 2440 bytes, using 'compacted' format.
-Jul 07 07:12:58 archbish kernel: signal: max sigframe size: 3632
-Jul 07 07:12:58 archbish kernel: BIOS-provided physical RAM map:
-Jul 07 07:12:58 archbish kernel: BIOS-e820: [mem 0x0000000000000000-0x000000000009efff] usable
-Jul 07 07:12:58 archbish kernel: BIOS-e820: [mem 0x000000000009f000-0x00000000000fffff] reserved
-Jul 07 07:12:58 archbish kernel: BIOS-e820: [mem 0x0000000000100000-0x000000008ef6efff] usable
-Jul 07 07:12:58 archbish kernel: BIOS-e820: [mem 0x000000008ef6f000-0x000000008f03efff] type 20
-Jul 07 07:12:58 archbish kernel: BIOS-e820: [mem 0x000000008f03f000-0x0000000093f2efff] reserved
-Jul 07 07:12:58 archbish kernel: BIOS-e820: [mem 0x0000000093f2f000-0x0000000094b2efff] ACPI NVS
-Jul 07 07:12:58 archbish kernel: BIOS-e820: [mem 0x0000000094b2f000-0x0000000094bfefff] ACPI data
-Jul 07 07:12:58 archbish kernel: BIOS-e820: [mem 0x0000000094bff000-0x0000000094bfffff] usable
-Jul 07 07:12:58 archbish kernel: NX (Execute Disable) protection: active
-Jul 07 07:12:58 archbish kernel: efi: EFI v2.70 by Lenovo
-Jul 07 07:12:58 archbish kernel: efi: ACPI=0x94bfe000 ACPI 2.0=0x94bfe014 SMBIOS=0x90cbd000 SMBIOS 3.0=0x90cb0000 TPMFinalLog=0x9498f000 MEMATTR=0x8aa30018 ESRT=0x8ab9c000
-Jul 07 07:12:58 archbish kernel: SMBIOS 3.2.0 present.
-Jul 07 07:12:58 archbish kernel: DMI: LENOVO 20W4000NUK/20W4000NUK, BIOS N34ET40W (1.40 ) 06/25/2021
-Jul 07 07:12:58 archbish kernel: tsc: Detected 2400.000 MHz processor
-Jul 07 07:12:58 archbish kernel: tsc: Detected 2419.200 MHz TSC
-Jul 07 07:12:58 archbish kernel: e820: update [mem 0x00000000-0x00000fff] usable ==> reserved
-Jul 07 07:12:58 archbish kernel: e820: remove [mem 0x000a0000-0x000fffff] usable
-Jul 07 07:12:58 archbish kernel: last_pfn = 0x45f800 max_arch_pfn = 0x400000000
-Jul 07 07:12:58 archbish kernel: x86/PAT: Configuration [0-7]: WB  WC  UC- UC  WB  WP  UC- WT
-Jul 07 07:12:58 archbish kernel: last_pfn = 0x94c00 max_arch_pfn = 0x400000000
-Jul 07 07:12:58 archbish kernel: esrt: Reserving ESRT space from 0x000000008ab9c000 to 0x000000008ab9c150.
-Jul 07 07:12:58 archbish kernel: e820: update [mem 0x8ab9c000-0x8ab9cfff] usable ==> reserved

We can see that the first thing that is registered is the OS image that contains the kernel. From this point on, the kernel is active and doing its work.

Initial kernel actions

The diagnostics above are a running commentary provided by the kernel itself about its actions. The details will be specific to the machine in question but the general sequence is as follows for all operating systems:

  1. CPU inspection
  2. Memory inspection
  3. Device bus discovery
  4. Device discovery
  5. Auxiliary kernel subsystem setup (networks etc)
  6. Mounting of the root filesystem
  7. Starting of user space
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Breadboards.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Breadboards.html deleted file mode 100644 index 1a62cb6..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Breadboards.html +++ /dev/null @@ -1,50 +0,0 @@ -Breadboards - My Zettelkasten - - - - -

Breadboards

Contact holes

Beneath the plastic casing, the contact holes are connected to one another making a continuous circuit connection

Terminal strips

The contact holes in the middle section, arranged in groups of five and designated by letters

The terminal strips are not connected accross the ditch thus each of the two strips are electrically separate regions (A-E and F-J).

Bus strips

The contact holes on the outer edges of the breadboard, designated by numbers (1-30). The chief role of the bus strips is to manage the power to the circuit. You will typically use the positive bus strip on one side for the voltage source and the negative bus strip on the other side for the ground outlet.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Built_in_React_hooks.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Built_in_React_hooks.html deleted file mode 100644 index a15b133..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Built_in_React_hooks.html +++ /dev/null @@ -1,98 +0,0 @@ -Typing built-in hooks - My Zettelkasten - - - - -

Typing built-in hooks

useState

const [amount, setAmount] = useState<number | string>(3);

With a ustom type

interface IState {
-  people: IPerson[];
-}
-
-interface IPerson {
-  name: string;
-  age: number;
-}
-
-const [people, setPeople] = useState<IState>({});
-
-// Alternative declaration
-
-interface IState {
-  people: {
-    name: string;
-    age: number;
-  }[];
-}
-
-const [people, setPeople] = useState<IState["people"]>({});

useReducer

Mostly the same. They key thing to type is the reducer function itself. You don’t need to type the intitial state unless it is a pre-existing type, you can just use type assertion:

interface IAction {
-  | { type: "increment"; payload: number }
-  | { type: "decrement"; payload: string };
-}
-
-const initialState = { count: 0 };
-
-function reducer(state: typeof initialState, action: IAction) {
-  switch (action.type) {
-    case "increment":
-      return { count: state.count + action.payload };
-    case "decrement":
-      return { count: state.count - Number(action.payload) };
-    default:
-      throw new Error();
-  }
-}

Then the syntax is as normal, i.e:

const [state, dispatch] = useReducer(reducer, initialState);

useEffect

Limited potential for typing here as this hook does not return a value. See if there is useful inferred typing from use and update.

useContext

We can use generics but mostly this is untyped:

type Theme = "light" | "dark";
-const ThemeContext = createContext < Theme > "dark";
-
-const App = () => (
-  <ThemeContext.Provider value="dark">
-    <MyComponent />
-  </ThemeContext.Provider>
-);
-
-const MyComponent = () => {
-  const theme = useContext(ThemeContext);
-  return <div>The theme is {theme}</div>;
-};

useCallback / useMemo

You must only type the parameters that are passed to the callback, the return value will be inferred.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Bus.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Bus.html deleted file mode 100644 index 9fceee9..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Bus.html +++ /dev/null @@ -1,52 +0,0 @@ -Bus - My Zettelkasten - - - - -

Bus

A bus is a communication system that transfers data between components inside a computer, or between computers.

A bus can be thought of as a kind of pipeline that allows different components of the computer to communicate with each other.

Note that the use of the word “bus” varies somewhat in points of emphasis. A bus can mean:

  • The physical wires that make up the bus
  • The communication channel that is established over those wires

Main buses

Bus typeDescription
System busThe primary pathway between the CPU and Memory. It comprises the data bus that transfers data from the memory to the CPU and the address bus which transmits requests from the CPU to memory.
Internal busConnects local devices for example the harddisk to the CPU.
External busConnects peripheral devices such as disks and printers to the motherboard
Expansion busAllows expansion boards to access the CPU and memory.
Frontside busMain computer bus that determines data transfer rate speed and is the primary data transfer path between the CPU, RAM and other motherboard devices.
Backside busTransfers secondary cache (L2 cache) data at faster speeds, allowing more efficient CPU operations

Bus standards

Parallel and serial transmission types

There is a distinction between buses that use serial and buses that use parallel transmission. They are distinguished by the way in which the bits are transferred from one point to another, along the bus.

Serial Transmission is the type of transmission in which a single communication link is used to transfer the data from an end to another. On other hand Parallel Transmission is the transmission in which multiple parallel links are used that transmit each bit of data simultaneously.

- -
  • Serial buses are cheaper to implement than parallel buses
  • Serial buses operate at greater latency than parallel buses

Latency

Latency means delay: the delay from the time the data is requested until the time it arrives. In the context of a microprocesser and buses a key locus of latency would be between the time a request takes to travel accross the system bus from the CPU to the memory.

Bandwidth

In general, bandwidth is a measure of the capacity for a communications channel to transmit data. A bus is a channel between two components thus we can talk about the bandwidth of buses. The speed and efficiency of a bus is a function of its bandwidth, although other factors such as its length and proximity to the source and receiver are also important.

Bandwidth can be calculated in terms of how many bits can be transferred per second. The wider the bus, the more bits that can be transferred. If we have a bus that can run at 66MHz and transfer 64 bits, 64 bits is 8Mb thus the bandwidth is 8 x 66 = 528Mb.

Standards

The mode of transmission is used to distinguish the different bus standards.

SCSI (Small Computer System Interface) and ATA (Advanced Technology Attachment) are used for hard drive devices (i.e. internal buses). USB (Univeral Serial Bus) and SATA (Serial Advanced Technology Attachment) are used for peripheral devices, keyboards and modem devices (i.e external buses).

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/CPU_architecture.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/CPU_architecture.html deleted file mode 100644 index 980d9eb..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/CPU_architecture.html +++ /dev/null @@ -1,50 +0,0 @@ -CPU architecture - My Zettelkasten - - - - -

CPU architecture

At the core of a computer sits the Central Processing Unit. This is the assembly of chips that execute all computation. Instructions are passed to the CPU along the data bus part of the system bus from the memory. The kernel, also residing in memory, sequences and schedules the sending of data to the CPU and manages requests from the CPU for data in memory.

The CPU comprises three core components:

  • Registers (a type of memory positioned on the same chip as the CPU )
  • the Arithmetic Logic Unit (ALU)
  • the Control Unit (CU)

This method of putting together a computer is known as the Von Neumann Architecture. It was devised by John von Neumann in about 1945, well before any of the components that would be needed to produce it had actually been invented.

Registers

This is the part of the CPU that stores data. The memory cells that comprise it do not have Memory (unlike RAM) so they cannot store very much data but they work faster, which is what is important. Because their memory capacity is so small, we measure the size of registers in bits rather than bytes.

In terms of speed, registers sit at the top part of the overall memory hierarchy.

There are five main types of register in the CPU:

Register typeWhat it stores
AccumulatorThe results of calculations
Instruction RegisterThe DRAM address of the instruction to be processed
Memory Address RegisterThe DRAM address of the data to be processed
Memory Data RegisterThe store of the data that is currently being processed
Program CounterThe RAM address of the next instruction to be processed

Arithmetic Logic Unit

See Arithmetic Logic Unit

Control Unit

The CPU’s controller. It takes the instructions in binary form from RAM memory (separate from the CPU, but connected) and then signals to the to ALU and memory registers what it is supposed to do to execute the instructions. Think of it as the overseer that gets the ALU and registers to work together to run program instructions.

The system clock

Whilst modern CPUs and multithreading make it appear as though the CPU is capable of running multiple processes at once, access to the CPU is in fact sequential. The illusion of simultaneous computation is due to the fact the processor is so fast that we do not detect the sequential changes. For this to happen, the CPU needs to have a means of scheduling and sequencing processes. This is made possible through the system clock, hence when talking about the speed of the CPU we do so with reference to clock speeds and the clock cycle.

The clock’s circuitry is based on a quartz crystal system like that used in watches. At precisely timed intervals, the clock sends out pulses of electricity that cause bits to move from place to place within logic gates or between logic gates and registers. This is covered in greater detail in the discussion of clock signals in digital circuits.

Simple instructions such as add can often be executed in just one clock cycle, whilst complex operations such as divide will require a number of smaller steps, each using one cycle.

We measure the speed of a chip process within the CPU in Hertz (Hz). One Hertz is equivalent to 1 cycle per second where a “cycle” is equivalent to a single clock tick. Thus a tick covers a period of 1 second.

A speed of 2GHz for example means two billion cycles per second. This would mean that the clock was completing two billion cycles at each tick. It is clock speed that is being referred to when computers are marketed in terms of the number of Hz a processor possesses.

Processing cycles

Each “cycle” is the execution of a process that commences once the kernel hands control to the CPU. Each cycle follows a sequence of events known as fetch, decode, and execute.

Electromagnetism: broader scientific context

Hertz was the scientist who detected electromagentic waves. We use Hertz as a measure of the frequency of electromatic wave cycles in a signal.

As the diagram above shows, a cycle is equal to one ascending and one descending crest. The more cycles per time unit, the greater the Hertz. We see the Hz increase as the number of cycles increases over time.

Processor cores

// TODO: add to dedicated file

// Add diagram The vast majority of general purpose computers are multi-core. This means that the CPU contains more than one processing unit. They are best thought of as mini-CPUs within the main CPU since they each have the same overall Von Neumann architecture.

With Intel processors the two main consumer processors are the i5 and i7. The latter has more cores than the former. Consequently it has faster clock speeds and greater concurrency due to increased threads.

Cache access

// See pp.129

History

The development of multi-core processors emerged because practical limits began to be reached when trying to increase the clock speeds of processors. For a period, increased transistor density meant that there were steady increases in clock speeds. This meant that more instructions could be executed per second.

When the 3GHz level was reached it became clear that pushing a CPU beyond this led to excessive heat production and the logic gates not being able to keep up at those speeds. Instead of maxing out the clock rate, attention turned to running multiple instructions in parallel in order to increase performance.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Call_stack.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Call_stack.html deleted file mode 100644 index 2042b65..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Call_stack.html +++ /dev/null @@ -1,56 +0,0 @@ -The call-stack - My Zettelkasten - - - - -

The call-stack

A stack data structure that holds the information of the functions called within a program that allows transfer of the application control from these functions to the main process after code inside the functions has been executed.

Example

function greet(who) {
-  console.log("Hello " + who);
-}
-
-greet("Harry");
-
-console.log("Bye");

Breakdown

  1. Interpreter receives call to greet()
  2. Goes to the definition of this function (function greet(who)...)
  3. Executes the console.log within this function
  4. Returns to the location that called it (greet("Harry"))
  5. Finds that there is nothing else to do in this function so moves to next function: the console.log("bye")
  6. Executes
  7. Returns to line that called it. Finds nothing else to do. Exits program.

Stack memory

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Capturing_user_input_in_Bash.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Capturing_user_input_in_Bash.html deleted file mode 100644 index 3bfd71e..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Capturing_user_input_in_Bash.html +++ /dev/null @@ -1,99 +0,0 @@ -Capturing user input in Bash - My Zettelkasten - - - - -

Capturing user input in Bash

We use read to gather user input.

Capturing raw inputs

# Wait for the input
-echo "What is your name?"
-read name
-
-# Silently gather the input and proceed (the input won't show up in the terminal)
-echo "What is your password?"
-read -s pass
-
-# Combine in single line
-read  -p "What's your favourite animal? " animal
-
-echo name: $name, pass $pass, animal: $animal

Offering a selection

We can use select to get the user to choose from a series of options.

select animal in "bird" "dog" "cow"
-do
-    echo "You selected $animal"
-    break
-done

This will present each option as number that can be inputted:

1) bird
-2) dog
-3) cow
-#? 1
-You selected bird

We could make this more robust by using a case statement:

select animal in "bird" "dog" "cow"
-do
-    case $animal in
-        bird) echo "Birds like to tweet";;
-        dog) echo "Dogs like to woof";;
-        cow) echo "Cows like to moo";;
-        quit) break;;
-        *) "I'm not sure what that means"
-    esac
-done

Ensuring you capture a valid response from the user

Set a default response value with -i

If the user doesn’t enter anything, the value will be set to the default.

read -ep "Favourite colour? " -i "blue" favecolour
-echo "$favecolour"
-# blue

Alternative formulation:


-read -p "Favourite colour? [blue]" fave
-
-# If response empty...
-if [[ -z $fave ]]; then
-    fave="blue"
-fi
-echo "$fave was selected"

Check right number of arguments supplied

Here we test that the right number of arguments have been passed to the script:

if (( $#<3 )); then
-    echo "This command requires three arguments:"a
-    echo "username, userId, and favouriteNumber"
-else
-    echo "username: $1"
-    echo "userid: $2"
-    echo "favourite number: $3"
-fi

Check the response is valid

The following example demonstrates checking an input for a pattern (a data-link integer sequence):

read -p "Which year? [nnnn] " year
-until [[ $year =~ [0-9{4} ]];
-    read -p "A four-digit year, please! [nnnn] " year
-done
-echo "Selected year: $year"
-
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Case_statements_in_Bash.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Case_statements_in_Bash.html deleted file mode 100644 index 14c2dee..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Case_statements_in_Bash.html +++ /dev/null @@ -1,66 +0,0 @@ -Case statements in Bash - My Zettelkasten - - - - -

Case statements in Bash

Usage against a variable

animal="dog"
-case $animal in
-    bird ) echo "Avian";;
-    dog|puppy ) echo "Canine";;
-    * ) echo "No match";;
-esac

Usage as part of a function:

function convertCharToInt {
-    case $1 in
-        A|X )
-            echo 1 ;;
-        B|Y )
-            echo 2 ;;
-        C|Z )
-            echo 3 ;;
-        *)
-            echo ;;
-    esac
-}

Usage:

declare -i intValue = $(convertCharToInt B)
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Cells_and_batteries.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Cells_and_batteries.html deleted file mode 100644 index 819c086..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Cells_and_batteries.html +++ /dev/null @@ -1,56 +0,0 @@ -Cells and batteries - My Zettelkasten - - - - -

Cells and batteries

Cells are a voltage source that generate a difference of potential via a positive and negative electrode separated by an electrolytic solution. The electrolytes pull free electrons from one of the materials which creates a positive charge. The other material gains the free electrons creating a negative charge.

A battery is a combination of two or more cells.

Cells which cannot be recharged are called primary cells. Cells which can be recharged are called secondary cells.

Connecting batteries

Cells and batteries can be connected to each other in electrical ciruits to increase the overall voltage and current that is produced. There are three main connection types:

  • series
  • parallel
  • series-parallel

The key thing to remember: cells configured in series increases the overall voltage available and cells configured in parallel increases the overall current available

The table below summarises the relative differences:

Series connections

With series connections we distinguish series aiding and series opposing configurations.

In the case of series aiding, cells are connected one in front of another with the positive terminal connecting to the negative terminal of the other in a line.

In this configuration the same current flows through all the cells; it is not cumulative. We represent this as follow> However the voltage is cumulative: it is the sum of the individual cell voltages, represented below as electrical field:

$$ -E_{T} = E_{1} + E_{2} + E_{3} \\ -$$

Thus series connections increase voltage but keep current constant.

Series battery connection:

Can be represented in a circuit diagram in one of the following two ways: as a series of cells or as a single battery:

In the case of series opposing, negative terminals are connected to each other and positive terminals are connected to each other in a series. This doesn’t have many applications.

Parallel connections

In parallel connections all positive terminals are connected to each other and all negative terminals are connected to each other.

This time the voltage is the same as each individual cell but the current is the sum of the individual cell currents. So the voltage is constant but the current is cumulative:

$$ -E_{T} = E_{1} = E_{2} = E_{3} \\ -$$

$$ -I_{T} = I_{1} + I_{2} + I_{3} -$$

Parallel battery connection:

Parallel battery circuit diagram:

Series-parrallel

If we want both a higher voltage and a higher current we can use series-parallel configurations. Connecting cells in series increases the voltage and connecting cells in parellel increases the current so doint both boosts the amount of both quantities.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Cherry_picking.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Cherry_picking.html deleted file mode 100644 index c83650a..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Cherry_picking.html +++ /dev/null @@ -1,50 +0,0 @@ -Cherry-picking a commit - My Zettelkasten - - - - -

Cherry-picking a commit

Cherry-picking is the act of selecting a specific commit or set of commits and applying them to a different branch. It allows you to extract a change or a series of changes from one branch and apply them to another branch without merging the entire branch.

It can also be used to apply a series of commits that are not sequential in a branch to another branch in a specific order.

Cherry-picking can sometimes result in conflicts, especially if the changes you’re trying to apply conflict with changes in the destination branch. In such cases, you’ll need to resolve the conflicts manually before completing the cherry-pick process.

Syntax

Suppose you have two branches: main and feature. You want to apply the changes from the commit with hash xyx from the main branch to the feature branch.

First, switch to the feature branch:

git checkout feature

Next, cherry-pick the commit from the main branch:

git cherry-pick xyz

This will apply the changes from the commit with hash xyz from thee main branch to the feature branch. This will create a new SHA on feature (pqr) but the changes will be identical.

The benefit is that you only take the select changes you want, you are not merging the whole main branch into feature.

Note that you can also cherry-pick multiple commits by specifying their hashes separated by spaces:

git cherry-pick abcdefg hijklmn opqrst

Limitations

  • You don’t have to just cherry-pick locally, you can also cherry-pick from a remote tracking branch.
  • You cannot cherry-pick merge commits since these commits do not implement a set of changes, they are connecting commits.

Use case

The time when I have cherry-picked is when a commit has been reverted via GitHub. This typically happens on the main branch when breaking changes have been merged and we want to undo this by reverting back to the previous commit, from before the problematic commit was merged in.

In this scenario, you will want to start from the reverted main branch and then cherry-pick the breaking commit. You can then fix the bug and keep an accurate record of the whole history.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Child_to_parent_data_flow_in_React.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Child_to_parent_data_flow_in_React.html deleted file mode 100644 index 2ec3985..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Child_to_parent_data_flow_in_React.html +++ /dev/null @@ -1,62 +0,0 @@ -Child to parent data flow - My Zettelkasten - - - - -

Child to parent data flow

Despite React having a uni-directional, downwards data-flow, it is sometimes necessary to pass events and data from a child back up to the parent. This need can arise when you want to modularize functionality within a child component rather than have everything happening in the parent, and you don’t want to use a common shared higher context.

For the example we will use the standard click incrementer.

We have a counter on the parent that is updated in response to a click event in the child component.

Our parent component is App and the child component is Child

export default function App() {
-  const [count, setCount] = useState(0);
-  return (
-    <>
-      <p>{count}</p>
-      <Child count={count} setCount={setCount} />
-    </>
-  );
-}
-
-const Child = ({ count, setCount }) => {
-  return <button onClick={() => setCount(count + 1)}>Increment</button>;
-};

So the overall state and updater function exists on the parent. The child is able to access this state by virtue of receiving {count, setCount} as props. It can therefore manipulate this state and have it be reflected in the parent.

It is not necessary to pass the state variable every time. You could just pass the updater. We have passed the count variable here because the child needs access to the current value, in order to be able to increment it.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Chipset_and_controllers.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Chipset_and_controllers.html deleted file mode 100644 index ef13b88..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Chipset_and_controllers.html +++ /dev/null @@ -1,50 +0,0 @@ -Chipset and controllers - My Zettelkasten - - - - -

Chipset and controllers

A controller is simply a circuit that controls a process. The chipset is a combination of controllers placed on the same piece of silicon.

The chipset manages the data flow between the different components that comprise the motherboard: processor, Memory, harddisk and peripherals.

Buses run in and out of the chipset into these key motherboard components. The main chipset is a kind of junction that sits between the memory and CPU through which the system bus passes.

The chipset is sometimes called the “glue” or “traffic controller” of the motherboard or an intelligent intersection of buses.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Class_inheritance_in_Python.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Class_inheritance_in_Python.html deleted file mode 100644 index 5ffa7b5..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Class_inheritance_in_Python.html +++ /dev/null @@ -1,81 +0,0 @@ -Class inheritance in Python - My Zettelkasten - - - - -

Class inheritance in Python

We distinguish the parent/source/superclass class and the subclass that extends it.

A subclass can have more than one parent class that it extends, but this is atypical.

The subclass will inherit all attributes and methods of the superclass unless it overrides them.

In addition to overriding the methods of the parent we can extend them in the child. This is a bit like using an abstract.

Example of class inheritance


-class Person:
-    """ Our superclass
-    """
-    def __init__(self, name, age):
-        self.name = name
-        self.age = age
-
-    def birthday(self):
-        print('Happy birthday you were', self.age)
-        self.age += 1
-        print('You are now', self.age)
-
-    def __str__(self):
-        return self.name + ' is ' + str(self.age)
-
-
-class Employee(Person):
-    """ Our subclass that extends `Person`
-    """
-    def __init__(self, name, age, id):
-        super().__init__(name, age)
-        self.id = id
-
-    def calculate_pay(self, hours_worked):
-        rate_of_pay = 7.50
-        if self.age >= 21:
-            rate_of_pay += 2.50
-        return hours_worked * rate_of_pay
-
-    def __str__(self):
-        return super().__str__() + ' - id(' + str(self.id) + ')'

Key points

  • We pass the name of the parent class to the child class as a parameter
  • We must include all of the parent class’s attributes in the constructor of the subclass
  • We must use a special super().__init__(..,...) method to enact the extension of the parent. This method references the __init__ class in the parent.

Protected/private methods and attributes

Protected methods and attributes are private to the class but can be accessed from any subclass

Private methods cannot be accessed from anywhere outside of the class

We declare private methods and attributes with a double underscore (__). We declare protected methods and attributes with a single underscore (_).

This is convention, there are not actually private and protected attributes or properties.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Classes.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Classes.html deleted file mode 100644 index 0507156..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Classes.html +++ /dev/null @@ -1,149 +0,0 @@ -Classes - My Zettelkasten - - - - -

Classes

Type declarations for classes

TypeScript offers full type annotations for classes. It also introduces several TypeScript-specific options (control access modifiers, interfaces etc) that do not exist in JavaScript but which seek to bring it into closer alignment with more strict object-oriented languages like Java and C#.

A class in JavaScript:

class Age {
-  constructor(name, birthYear) {
-    this.name = name;
-    this.birthYear = birthYear;
-  }
-  currentYear() {
-    return new Date().getFullYear();
-  }
-  get age() {
-    return this.currentYear() - this.birthYear;
-  }
-  get dataOutput() {
-    return `${this.personName} is ${this.age} years old`;
-  }
-}

The same class in TypeScript:

class Age {
-  personName: string;
-  birthYear: number;
-  constructor(personName: string, birthYear: number) {
-    this.personName = personName;
-    this.birthYear = birthYear;
-  }
-  currentYear(): number {
-    return new Date().getFullYear();
-  }
-  get age(): number {
-    return this.currentYear() - this.birthYear;
-  }
-  get dataOutput(): string {
-    return `${this.personName} is ${this.age} years old`;
-  }
-}

The main points to note are:

  • methods must specify their return type, as with functions
  • the constructor function must specify its parameters’ types
  • we must declare the types of any properties we intend to use at the start of the class.

Instantiating a class

In order to create an object instance of Age, we can use the standard constructor function, viz:

const mum = new Age("Mary Jo", 1959);
-console.log(mum);
-
-/* Age { personName: 'Mary Jo', birthYear: 1959 } */

But given that classes define objects, we can also now use Age as a new custom type and define an object that way

const thomas: Age = new Age("Thomas", 1988);

Without constructor

If your class does not use a constructor, you still need to define your class property types at the top:

class Dummy {
-  aNum: number = 4;
-  get getSquare(): number {
-    return this.aNum * this.aNum;
-  }
-}

Interfaces

In most cases the difference between using the type and interface keywords when defining a custom type is marginal however interfaces are specifically designed for classes and OOP style programming in TypeScript. This is obviously most apparent in a framework like Angular where interfaces are used heavily.

When we use an interface with a class we are asserting that the class must have certain properties and methods in order to qualify as that type. This is most helpful when you are working with several developers and want to ensure consistency.

Let’s say we have the following interface:

interface Person {
-  firstName: string;
-  secondName: string;
-  age: number;
-  employed: () => boolean;
-}

Now we want to create a class that must share this shape. We go ahead and create the class and say that it implements Person :

class Programmer implements Person {
-// If the below are not included, TS will generate an error
-	firstName: string,
-	secondName: string,
-	age: number,
-	employed: () => boolean
-}

Inheritance

We can extend classes in TypeScript by using sub-classes or abstract classes.

Sub-classes

In the case of sub-classes, we use the phrase [child_class] extends [parent_class] in the class declaration to designate the inheritance relationship between the base class and the new class that is derived from it.

A derived class has all the properies and methods of its base class but can also define additional members.

When you instantiate a child class from a parent class, if the parent class has constructor values, you must initialise these in the child. You do this by calling the parent constructor via the super() syntax. For example:

class Employee extends Person {
-  constructor(firstName: string, lastName: string, private jobTitle: string) {
-    // call the constructor of the Person class:
-    super(firstName, lastName);
-  }
-}

To override or alter a method that exists on the parent in the child, you can use the syntax super.[methodName]().

Abstract classes

Classes marked abstract are similar to parent in the case of sub-classes. The difference is that they are like templates. Several of their methods and properties may be directly inherited by classes that derive from them (just like sub-classes) but they can include ‘blank’ methods and properties that are placeholders for methods and properties that are defined in the derivation class.

I have found this useful for cases where you want to inherit methods from a parent class but implement a specific method differently in each derivation.

export abstract class IndexHyperlinksProvider
-   implements vscode.TreeDataProvider<TreeItem>
-{
-   public activeFile: string | undefined
-   private outlinks
-   private fileSystemUtils: FileSystemUtils
-
-   constructor(
-      activeFile: string | undefined,
-      workspaceRoot: string | undefined
-   ) {
-      this.setActiveFile(activeFile)
-      this.outlinks = this.generateLinks()
-      this.fileSystemUtils = new FileSystemUtils(workspaceRoot)
-   }
-
-   abstract generateLinks(): Promise<TreeItem[] | undefined>
-
-   public setActiveFile(activeFile: string | undefined) {
-      this.activeFile = activeFile
-   }
-  ...

Above we have a base class with a single abstract method generateLinks(). The class below extends this base. Note that it passes the parent constructor values to super and defines an actual method for the designated generateLinks() template:

export class IndexOutlinksProvider extends IndexHyperlinksProvider {
-  public workspaceFiles: string[];
-  public context: vscode.ExtensionContext;
-  constructor(
-    activeFile: string | undefined,
-    workspaceRoot: string | undefined,
-    workspaceFiles: string[],
-    context: vscode.ExtensionContext
-  ) {
-    super(activeFile, workspaceRoot);
-    this.workspaceFiles = workspaceFiles;
-    this.context = context;
-  }
-
-  public async generateLinks(): Promise<TreeItem[] | undefined> {
-    const indexer = new IndexHyperlinks(this.context, this.workspaceFiles);
-    if (typeof this.activeFile === "string") {
-      const outlinks = await indexer.indexOutlinks(this.activeFile);
-      if (outlinks !== undefined) {
-        return this.transformLinksToTreeItem(outlinks);
-      }
-    }
-    return;
-  }
-}

Importantly, you cannot instantiate abstract classes. You can only extend them and then instantiate their derivation. This is another important difference from sub-classes.

As with sub-classes, you must initialise the properties of the parent constructor with super.

implements vs extends

You shouldn’t confuse implements with extends. implements just checks the class as an interface in accordance with the principles of duck typing: i.e the implementing class should have the same properties and methods. It doesn’t affect anything internal to the methods or properties. So e.g, if you typed a method parameter as string in the base class, this would still default to any in the derived class.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Classes_in_Python.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Classes_in_Python.html deleted file mode 100644 index 74e0fec..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Classes_in_Python.html +++ /dev/null @@ -1,115 +0,0 @@ -Classes in Python - My Zettelkasten - - - - -

Classes in Python

General points

  • We don’t need to use new when instantiating an instance of a class.
  • All properties and methods must be defined in the constructor. This is in contrast to JavaScript where the properties in the constructor are those we want to initialise when the object is created and where there may be other properties and methods that are used outside of the instantiation process.
  • In contrast to TypeScript and other OOP languages it is not necessary to declare the properties you wish to define in the constructor, outside of the constructor. As long as they are defined in the constructor they are accessible.

Basic syntax

class Person:
-	""" An example class to hold a persons name and age"""
-
-	def __init__(self, name, age):
-		self.name = name
-		self.age = age
-
-	def birthday(self):
-        print('Happy birthday you were', self.age)
-        self.age += 1
-        print('You are now', self.age)
-
-p1 = Person('John', 36)
-p2 = Person('Thomas', 34)
-print(p1)
-print(p2)
-
-print(p1.name)
-
-# John

Key points to note:

  • The __init__ method is the constructor function and must exist on every class to define the properties of the class
  • self is a reference to the class itself and the object it will create, akin to this in other languages
  • You must pass self as a parameter to every method (this is a difference from JS)
  • As with functions, we can use docstrings to document the class. What you write here will show up in Intellisense etc

More complex class

class Person:
-	""" An example class to hold a persons name and age"""
-
-	def __init__(self, name, age):
-		self.name = name
-		self.age = age
-
-	def __str__(self):
-		return self.name + ' is ' + str(self.age)
-
-	def birthday(self):
-		print ('Happy birthday you were', self.age)
-		self.age += 1
-		print('You are now', self.age)
-
-	def calculate_pay(self, hours_worked):
-		rate_of_pay = 7.50
-		if self.age >= 21:
-			rate_of_pay += 2.50
-		return hours_worked * rate_of_pay
-
-	def is_teenager(self):
-		return self.age < 20

Object references

When you log a class you get a reference to its hexadecimal Memory reference.

p1 = Person('John', 36)
-p2 = Person('Thomas', 34)
-
-print(p1)
-print(p2)
-
-# <__main__.Person object at 0x102e75510>
-# <__main__.Person object at 0x102e75511>

This shows each object is unique. You can also generate a specific ID with the id() method:

print(id(p1))
-print(id(p2))
-
-# 4379088272
-# 4379088656

Copying objects

The same principle that applies to copying functions applies to copying objects created through classes: redeclaration results in a duplicate entity. Thus changes to the duplicate will affect the original.

This becomes obvious when you use id() but otherwise might not be apparent. To copy you should therefore declare a new instance of the class.

The str method

The memory reference isn’t very helpful for viewing the data contents. To get around this we can use the builtin __string__ method which automatically logs whatever properties you put in there:

class Person:
-    """ An example class to hold a persons name and age"""
-
-    def __init__(self, name, age):
-        self.name = name
-        self.age = age
-
-    def __str__(self):
-        return self.name + ' is ' + str(self.age)
-
-p3 = Person('Thomas', 34)
-print(p3)
-# Thomas is 34

Deleting objects

You might want to delete an object reference because:

  • the variable referencing the object goes out of scope
  • the variable is set to None

After the del statement is applied to a variable that holds an object, the object will no longer be available and any attempt to reference it will result in an error.

p1 = Person('J-Man', 76)
-del p1
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Clock_signals.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Clock_signals.html deleted file mode 100644 index 9e227c2..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Clock_signals.html +++ /dev/null @@ -1,50 +0,0 @@ -Clock signals - My Zettelkasten - - - - -

Clock signals

In the examples of digital circuits so far (i.e adders and latches) everything happens in a single instant or over several repeated instances. This is because of how simple the circuits are. In the case of latches only a single bit is updated. And even with rippled adders they are just a series of 1-bit updaters in a chain.

With more complex circuits that use multiple memory devices which store a series of bits at once, we need a way to ensure that the bits are set at the same time. We do this by sequencing the execution with the pulses of the system clock.

A single iteration of the volatage rising and falling is a pulse. A complete oscillation from low to high and back to low is a cycle. As with all electromagnetic signals we measure the frequency of the wave in Hertz: cylcles per second. We also further distinguish the rising and falling edge of a pulse. Rising represents the signal passing from ground to its maximum voltage and falling is the reverse (the electrons moving from the voltage source to ground).

The diagram below shows a pulse cycle of 2Hz.

Linking components to the clock

  • All components that need to be synchronised are connected to the clock
  • State changes in the component occur only when a clock pulse occurs
  • Clock-driven components will typically trigger their state changes on either the rising edge or the falling edge of the pulse.
  • Components that trigger state changes on the rising pulse are positive edge-triggered
  • Components that trigger state changes on the falling pulse are negative edge-triggered

The role of the clock is essential in the functioning of the CPU. It is the system clock that gives CPUs their performance rating: how many processes can execute within a given clock cycle.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/CloudWatch.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/CloudWatch.html deleted file mode 100644 index e5e2ced..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/CloudWatch.html +++ /dev/null @@ -1,50 +0,0 @@ -AWS CloudWatch - My Zettelkasten - - - - -

AWS CloudWatch

AWS CloudWatch is a monitoring and observability service offered by Amazon Web Services (AWS). It is designed to help users collect, track, and analyze various metrics, logs, and events related to their AWS resources and applications running on the AWS cloud. CloudWatch enables users to gain operational insights and take timely actions to maintain the performance, availability, and health of their infrastructure and applications.

Key features

  • Metrics
    • CloudWatch collects and stores metrics from various AWS services, such as EC2 instances, Lambda functions, and RDS databases. Users can monitor these metrics in real-time, set alarms based on thresholds, and visualize them through customizable dashboards.
  • Logs
    • CloudWatch Logs enables users to collect, store, and analyze log data from AWS resources and applications.
  • Events
    • Events allows users to respond to changes in their AWS resources automatically by triggering actions such as sending notifications, invoking Lambda functions, or starting/stopping EC2 instances.
  • Alarms
    • Users can set alarms based on specified metric thresholds. When an alarm is triggered, CloudWatch can send notifications or automatically take corrective actions.
  • Dashboards
    • Dashboards provide customizable, at-a-glance visualizations of various metrics and logs, making it easier to monitor the health and performance of AWS resources and applications.

Accessing CloudWatch

CloudWatch can usually be accessed directly from within the dashboard for the given AWS service under the “Monitor” tab. For example with AWS Lambda:

In addition to graphical metrics, we can also view specific logs for each event and execution of the given service. In the case of a Lambda function:

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Command_pattern.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Command_pattern.html deleted file mode 100644 index 63e2f40..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Command_pattern.html +++ /dev/null @@ -1,97 +0,0 @@ -Command pattern - My Zettelkasten - - - - -

Command pattern

This is typically used when you want to sequence a fairly large number of actions in a series with the option to undo or reverse them. Similarly to the mediator it has a one-to-many architecture (there is a central class that sequences the commands which are handled by other classes) but in addition to sending and routing requests between colleagues, it keeps a central store of them and can reverse actions.

The typical example is a calculator. Will will generate this using constructor function syntax, rather than ES6 class syntax.

You have a bunch of arithmetic functions:

function add(x, y) {
-  return x + y;
-}
-function sub(x, y) {
-  return x - y;
-}
-function mul(x, y) {
-  return x * y;
-}
-function div(x, y) {
-  return x / y;
-}

Then a generalised Command class that has three parameters: undo, execute, and return a value:

var Command = function (execute, undo, value) {
-  this.execute = execute;
-  this.undo = undo;
-  this.value = value;
-};

We then create the specific commands by combining the functions and the Command class:

var AddCommand = function (value) {
-  return new Command(add, sub, value);
-};
-
-// We would create one of these classes for each of the four operations

So now the add and subtract functions slot into execute and undo on the Command class.

Finally we create the centralised command class that will return values based on the individual commands it sequences and issues, store them and remove them:

var Calculator = function () {
-    var current = 0;
-    var commands = [];
-
-    function action(command) {
-        var name = command.execute.toString().substr(9, 3);
-        return name.charAt(0).toUpperCase() + name.slice(1);
-    }
-
-    return {
-        execute: function (command) {
-            current = command.execute(current, command.value);
-            commands.push(command);
-            log.add(action(command) + ": " + command.value);
-        },
-
-        undo: function () {
-            var command = commands.pop();
-            current = command.undo(current, command.value);
-            log.add("Undo " + action(command) + ": " + command.value);
-        },
-
-        getCurrentValue: function () {
-            return current;
-        }
-    }
calculator.execute(new AddCommand(100));
-calculator.execute(new SubCommand(24));
-calculator.execute(new MulCommand(6));
-calculator.execute(new DivCommand(2));

Or undo them with:

calculator.undo();
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Commutativity.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Commutativity.html deleted file mode 100644 index 3f76445..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Commutativity.html +++ /dev/null @@ -1,50 +0,0 @@ -The Commutative Property of Addition and Multiplication - My Zettelkasten - - - - -

The Commutative Property of Addition and Multiplication

Let \(a\), \(b\) represent members of \(\mathbb{W}\) or \(\mathbb{Z}\) then:

$$ a + b = b + a $$

$$ a \cdot b = b \cdot a $$

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Comparing_React_classes_to_hooks.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Comparing_React_classes_to_hooks.html deleted file mode 100644 index 2173072..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Comparing_React_classes_to_hooks.html +++ /dev/null @@ -1,113 +0,0 @@ -Comparing class components to hook-based components - My Zettelkasten - - - - -

Comparing class components to hook-based components

We will look at the same component written with hooks and classes. Both use this child component:

const CounterBox = (props) => {
-  return <div className="output">{props.counterValue}</div>;
-};

Class component

import CounterBox from "./CounterBox";
-
-class CounterClass extends React.Component {
-  constructor(props) {
-    super(props);
-    this.state = {
-      counterValue: 0,
-    };
-  }
-
-  addOne() {
-    this.setState({
-      counterValue: this.state.counterValue + 1,
-    });
-  }
-
-  render() {
-    return (
-      <React.Fragment>
-        <button onClick={() => this.addOne()}>Add One</button>
-        <CounterBox counterValue={this.state.counterValue} />
-      </React.Fragment>
-    );
-  }
-}

Hook version

import React, { useState } from "react";
-import CounterBox from "./CounterBox";
-
-function CounterHook() {
-  const [counter, setCounter] = useState(0);
-  const handleClick = () => setCounter(counter + 1);
-  return (
-    <React.Fragment>
-      <button onClick={handleClick}>Add One</button>
-      <CounterBox counterValue={counter}></CounterBox>
-    </React.Fragment>
-  );
-}

Main differences

  • Obviously with hooks we use a function, not a class. We can therefore think of them as simple components that are able to handle state as well as props.

  • We have written the hook as a declared function but we could just as easily write it as a function expression or arrow function.

  • With the class, the state versioning is managed via the following properties on the React.Component class: this.state (start state) and this.setState (the change).

  • In both cases the function that actually creates the change is handled via an arrow function. With the hook we use the customary name handleClick .

  • The same process is managed in the hook via the useState() method. We effectively set ‘before’ and ‘after’ destructured variables on this method:

    const [counter, setCounter] = useState(0);
    -
    -// Schematically:
    -const [val, setVal] = useState(initialVal);

Binding with class component state

In the class component example we use an inline arrow function to execute addOne() however the official way to do it is to bind the event via the constructor method to avoid the problems created by this scope in classes. Using arrows is mostly fine and is less verbose, but it is important to understand the ‘official’ approach.

The way to write the state change in this way is:

class CounterClass extends React.Component{
-  constructor(props){
-    super(props);
-		this.state = { counterValue: 0};
-    this.handleClick = this.handleClick.bind(this); // bind the click to the class scope
-  }
-
-  handleClick(event){
-    this.setState({
-            counterValue: this.state.counterValue + 1;
-    });
-  }
-
-  render(){
-    return (
-      <button type="button"
-      onClick={this.handleClick}> // reference the class scope with `this`
-      Click Me
-      </button>
-			<CounterBox counterValue={this.state.counterValue}></CounterBox>
-    );
-  }
-}

How hooks improve on class components

  • State, when managed via hooks can be easily decoupled from a specific component and reused elsewhere. This also means it can be tested separately from any specific component where it is applied. This is much harder to do with classes which are closely entangled with the non-state aspects of a component through this and binding:

    With Hooks, you can extract stateful logic from a component so it can be tested independently and reused. Hooks allow you to reuse stateful logic without changing your component hierarchy. This makes it easy to share Hooks among many components or with the community.

  • Hooks simplify lifestyle methods and the use of componentDidMount etc through the useEffect hook

  • Classes and this are confusing generally. Functions are easier to grasp and read.

Relation to function components

You can think of hooks as function components (previously known as stateless components) plus state. Previously function components were ‘dumb’ components. That is, they didn’t allow for state management and generally used for layout. They could receive data as props but not state. This changes with hooks: you can add state to functions and no longer need to use classes exclusively for state. In fact you no longer need to use classes at all, unless you want to.

The stateful portion of a function component must be placed before the return() statement in the function.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Compile_Python_app_to_single_executable.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Compile_Python_app_to_single_executable.html deleted file mode 100644 index 6df92c6..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Compile_Python_app_to_single_executable.html +++ /dev/null @@ -1,52 +0,0 @@ -Compile Python app to single executable - My Zettelkasten - - - - -

Compile Python app to single executable

Assume you are already using a Pip venv.

Install pyinstaller and/or add it to your requirements.txt:

souce venv/bin/activate
-pip install pyinstaller
-pip install -r requirements.txt

Then from root of project:

pyinstall -F src/app.py

The -F flag compiles the application to a single file containing all necessary external packages and local imports.

It outpute to /dist. Say the app is called hello, run the executable thus:

/my-python-application/dist/app
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Compile_from_source.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Compile_from_source.html deleted file mode 100644 index f1e3f89..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Compile_from_source.html +++ /dev/null @@ -1,50 +0,0 @@ -Compile package from source - My Zettelkasten - - - - -

Compile package from source

  1. Clone the repo from GitHub
  2. cd into the repo
  3. Run makepkg -c

Remove compiled package

  1. If build dir still exists for package try running make uninstall.
  2. Reinstall the package and run make uninstall
  3. Locate the installed package in /usr/local/bin and run sudo rm -rf
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Complete_Mongo_example.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Complete_Mongo_example.html deleted file mode 100644 index 06a55e3..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Complete_Mongo_example.html +++ /dev/null @@ -1,70 +0,0 @@ -MongoDB connection, set-up and data query: complete example - My Zettelkasten - - - - -

MongoDB connection, set-up and data query: complete example

const mongoose = require("mongoose");
-
-mongoose..connect("mongodb://127.0.0.1/[databse_name]");
-
-const courseSchema = new mongoose.Schema({
-    name: String,
-    author: String,
-    tags: [String],
-    data: Date,
-    isPublished: Boolean,
-    price: Number
-})
-
-const Course = mongoose.model("Course", courseSchema);
-
-async function getCourses(){
-    return await Course
-        .find({isPublished: true, tags: "backend"})
-        .sort({name: 1})
-        .select({name: 1, author: 1});
-}
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Components_props_classes.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Components_props_classes.html deleted file mode 100644 index 5c21f17..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Components_props_classes.html +++ /dev/null @@ -1,97 +0,0 @@ -Components and props with class-based components - My Zettelkasten - - - - -

Components and props with class-based components

A component is a class or a function that manages the content that is output on the page (the rendering of elements) and the data (props) and state that is applied to the elements that are output.

Components can be created using ES6 classes or using the newer hook methodology.

A class-based component is a mixture of standard Javascript, JSX Javascript and HTML wrapped within an extension of the React.Component class that you import into your custom JS when installing the React library:

class Welcome extends React.Component {
-  render() {
-    return <h1>Hello, {this.props.name}</h1>;
-  }
-}

The JSX content of the component lives within the render() method that belongs to the React.Component class.

Once we have defined a class component that contains a JSX element we can then use JSX tags to place the resulting React element in our page. This is a placeholder for the HTML that is rendered by the class component. For example:

<body>
-  <Welcome name="Thomas" />
-</body>

A class component must include render(), and the return can only return one parent element. Also there must be a parent component. Where this isn’t possible, the convention is to use empty opening and closing tags, viz: <>...</> . These are called React Fragments and this is actually a short hand for <React.Fragment>...</React.Fragment>

Class components with state

Most class components will also possess state. State is managed through the constructor method on the class component, for example:

class Clock extends React.Component {
-  constructor(props) {
-    super(props);
-    this.state = { date: new Date() };
-  }
-  render() {
-    return (
-      <div>
-        <h1>Hello, world!</h1>
-        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
-      </div>
-    );
-  }
-}

We use the super() method to inherit the parent constructor (because custom components extend the React Component parent class) and we pass state as a special kind of prop.

Class components and simple components

Within the class-based paradigm of React a distinction is made between simple and class components.

A class component is obviously a component that is created as a class and thus which can inherit fields and methods via super from the React.Component class. This is necessary for handling props and configuring state.

A simple component, in contrast, is a function, not a class. These are used for what we can call static or ‘dumb’ components, i.e they just output content and data, they don’t have reactive state. This is why they are also sometimes called functional stateless components.

Simple components can however take props. In fact props are just like arguments that you pass to a function. When you write a simple component, your parameters are props.

Here’s an example of a simple component that doesn’t take any props

function PageHeader() {
-  return (
-    <header>
-      <h1>Site Title</h1>
-    </header>
-  );
-}

We can safely use arrow functions with simple components. So the same component could be written:

const PageHeader = () => {
-  return (
-    <header>
-      <h1>Site Title</h1>
-    </header>
-  );
-};

Now adding a prop:

const PageHeader = (props) => {
-  return (
-    <header>
-      <h1>{props.sitename}</h1>
-    </header>
-  );
-};

Then, in JSX we would apply the component with:

<PageHeader sitename="The name of the site" />

When we are using simple (functional) components we don’t need to use this.props . this is only required with classes. As a simple component is a function we just say props .

It’s worth noting in passing that you don’t have to use functions for simple components. You can achieve the same outcome with a class and it won’t generate an error. But it requires more code and complexity than is actually needed for the job:

class PageHeader extends React.Component {
-  render() {
-    return (
-      <header>
-        <h1> {this.props.siteName} </h1>
-      </header>
-    );
-  }
-}
-
-export default PageHeader;
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Components_props_hooks_in_React.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Components_props_hooks_in_React.html deleted file mode 100644 index 40e8519..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Components_props_hooks_in_React.html +++ /dev/null @@ -1,60 +0,0 @@ -Components and props with hooks - My Zettelkasten - - - - -

Components and props with hooks

As of React 16.8 a class component can be expressed using a function-based hook.

A class component:

class Welcome extends React.Component {
-  render() {
-    return <h1>Hello, {this.props.name}</h1>;
-  }
-}

The same component expressed as a hook:

function Welcome(props) {
-  return <h1>Hello, {props.name}</h1>;
-}

To output this component we use the same standard JSX syntax and pass the prop as an attribute of the JSX element:

<Welcome name="Thomas" />

How hooks are rendered

  1. We call ReactDOM.render() with the <Welcome name="Thomas" /> element. (This would typically be nested within a root App component; it wouldn’t be directly passed to the parent render function.)
  2. React calls the Welcome component with {name: 'Thomas'} as the props.
  3. Our Welcome component returns a <h1>Hello, Thomas</h1> element as the result.
  4. React DOM efficiently updates the DOM to match <h1>Hello, Thomas</h1>.

Function components must be pure functions

All React components must act like pure functions with respect to their props

This means that functions should not attempt to change the inputs they receive as parameters. They must always return the same result for the same inputs:

function sum(a, b) {
-  return a + b;
-}
function withdraw(account, amount) {
-  account.total -= amount;
-}

The reason for this is that props are read-only and we pass props to function components.

We change components by using state, not by mutating props. This is consistent with React’s Elements-992594b9cd2e483c85cddddffeb16f11.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Concise_subfield_mapping_JS.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Concise_subfield_mapping_JS.html deleted file mode 100644 index a9d3c72..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Concise_subfield_mapping_JS.html +++ /dev/null @@ -1,59 +0,0 @@ -Concise mapping of object subfileds in JS - My Zettelkasten - - - - -

Concise mapping of object subfileds in JS

Scenario

You have an array of objects and you want to return the objects with only a subset of the fields.

Implementation

Standard approach with a map:

const arrayOfObjs = [
-  { id: 12, name: "Thomas" },
-  { id: 3, name: "Gerald" },
-];
-
-// We just want the `name` property
-
-const subset = arrayOfObjs.map((obj) => {
-  name: obj.name;
-});

More concise approach with destructuring:

const subset = arrayOfObjs.map(({ name }) => ({ name }));
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Conditional_Elimination.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Conditional_Elimination.html deleted file mode 100644 index 1707d50..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Conditional_Elimination.html +++ /dev/null @@ -1,50 +0,0 @@ -Conditional elimination - My Zettelkasten - - - - -

Conditional elimination

If we have a conditional and we have independently derived its antecedent, we may invoke its consequent. This is often referred to as Modus ponens (affirming the antecedent).

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Conditional_Introduction.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Conditional_Introduction.html deleted file mode 100644 index 6521030..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Conditional_Introduction.html +++ /dev/null @@ -1,50 +0,0 @@ -Conditional Introduction - My Zettelkasten - - - - -

Conditional Introduction

If we can show that \(Q\) follows from \(P\) (typically via a sub-proof) than we can assert that P implies Q. This is also sometimes known as Conditional Proof

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Conditional_statements_in_Python.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Conditional_statements_in_Python.html deleted file mode 100644 index 1b2a38b..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Conditional_statements_in_Python.html +++ /dev/null @@ -1,91 +0,0 @@ -Conditional statements in Python - My Zettelkasten - - - - -

Conditional statements in Python

Basic example

input_string = input('Please input a number: ')
-
-if input_string.isnumeric():
-    print('The number is accepted')
-else:
-    print('The input is invalid')
-
-# 5
-# The number is accepted
-
-# Using an and in the condition
-print('-' * 25)
-age = 15
-status = None
-if age > 12 and age < 20:
-    status = 'teenager'
-else:
-    status = 'not teenager'
-print(status)

Else if

savings = float(input("Enter how much you have in savings: "))
-
-if savings == 0:
-    print("Sorry no savings")
-elif savings < 500:
-    print('Well done')
-elif savings < 1000:
-    print('That is a tidy sum')
-elif savings < 10000:
-    print('Welcome Sir!')
-else:
-    print('Thank you')

Nested conditions

snowing = True
-temp = -1
-if temp < 0:
-    print('It is freezing')
-    if snowing:
-        print('Put on boots')
-    print('Time for Hot Chocolate')
-print('Bye')

Ternaries/ shorthand conditionals

status = 'teenager' if age > 12 and age < 20 else 'not teenager'
-print(status)
-
-num = int(input('Enter a simple number: '))
-result = -1 if num < 0 else 1
-print('Result is ', result)
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Conditionals_in_Bash.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Conditionals_in_Bash.html deleted file mode 100644 index 9b4d3d3..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Conditionals_in_Bash.html +++ /dev/null @@ -1,70 +0,0 @@ -Conditionals in Bash - My Zettelkasten - - - - -

Conditionals in Bash

If statements

  • Conditional blocks start with if and end with the inversion fi (this is a common syntactic pattern in bash)
  • The conditional expression must be placed in square brackets with spaces either side. The spaces matter: if you omit them, the code will not run
  • We designate the code to run when the conditional is met with then
  • We can incorporate else if logic with elif

Basic example

if [ -e $var ]; then
-  # Do something
-else
-  # Do something else
-fi

If, else

if [ "$myMove" -eq "$opponentMove" ]; then
-    (( totalScore+=myMove+3 ))
-  elif [ $absDiff -eq 2 ] && [ "$myMove" -gt "$opponentMove" ]; then
-    (( totalScore+=myMove))
-  elif [ $absDiff -eq 2 ] && [ "$opponentMove" -gt "$myMove" ]; then
-    (( totalScore+=myMove+6))
-  elif [ $absDiff -eq 1 ] && [ "$opponentMove" -gt "$myMove" ]; then
-    (( totalScore+=myMove))
-  elif [ $absDiff -eq 1 ] && [ "$myMove" -gt "$opponentMove" ]; then
-    (( totalScore+=myMove+6))
-  fi

Nested conditionals

if [[ "$line" =~ ^$ ]]; then
-  if [[ "$runningTotal" -gt "$highest" ]]; then
-    (( highest=runningTotal ))
-  fi
-  # Reset running sum
-  (( runningTotal=0 ))
-fi
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Conjunction_Elimination.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Conjunction_Elimination.html deleted file mode 100644 index 19ad45b..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Conjunction_Elimination.html +++ /dev/null @@ -1,50 +0,0 @@ -Conditional Elimination - My Zettelkasten - - - - -

Conditional Elimination

If a conjunction exists, it means that both conjuncts are the case; therefore we can legitimately extract either one of them. Also known as Simplification.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Conjunction_Introduction.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Conjunction_Introduction.html deleted file mode 100644 index 46cd81e..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Conjunction_Introduction.html +++ /dev/null @@ -1,50 +0,0 @@ -Conjunction Introduction - My Zettelkasten - - - - -

Conjunction Introduction

If two conjuncts have each been independently derived then they can be conjoined. Also known more simply as Conjunction

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Connect_to_Mongo_database.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Connect_to_Mongo_database.html deleted file mode 100644 index ea793fa..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Connect_to_Mongo_database.html +++ /dev/null @@ -1,53 +0,0 @@ -Connect to a database with Mongoose - My Zettelkasten - - - - -

Connect to a database with Mongoose

Now that we have installed and configured MongoDB, we need to connect to it via Node.js. Mongoose is a simple API for interacting with a Mongo database via Node.

With Mongoose installed we can connect to a database. We don’t have any Mongo databases yet beyond the defaults but the following Mongoose connection logic will create and connect to a new database called playground:

Providing the Mongo server is running (execture mongod), we will see the confirmation message in the console.

mongoose
-  .connect("mongodb://127.0.0.1/playground")
-  .then(() => console.log("Connected to MongoDB"))
-  .catch((err) => console.error(err));
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Connecting_a_frontend_to_a_Docker_backend.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Connecting_a_frontend_to_a_Docker_backend.html deleted file mode 100644 index 6a32b16..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Connecting_a_frontend_to_a_Docker_backend.html +++ /dev/null @@ -1,64 +0,0 @@ -Connecting a frontend to a Docker backend - My Zettelkasten - - - - -

Connecting a frontend to a Docker backend

Building on from NodeJS backend with MySQL database we can add a frontend by adapting the existing Docker Compose files (one for each environment) to accept an additional dependency.

We won’t create a container for the frontend as this is not necessary.

We would add the following to the services section of the compose file:

services:
-  ...
-  frontend:
-    build: ./frontend
-    container_name: frontend_app
-    ports:
-      - "3000:3000"
-    environment:
-      - REACT_APP_API_URL=http://localhost:3001
-    depends_on:
-      - app

The REACT_APP_API_URL environment variable tells the frontend application where to find the backend API. This will then be accessbile via process.env and can be used directly in the frontend, e.g:

fetch(`${process.env.REACT_APP_API_URL}/api/data`)
-  .then((response) => response.json())
-  .then((data) => {
-    // Process the data from the backend API
-  });
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Containerization.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Containerization.html deleted file mode 100644 index 0140162..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Containerization.html +++ /dev/null @@ -1,50 +0,0 @@ -Containerizaton - My Zettelkasten - - - - -

Containerizaton

In this entry we look at containerization as a general technology that is distinct from its particular implementation by Docker.

We can understand the role and significance of containers and containerization by analogy with shipping containers. Before the invention of shipping containers as a standardised modular unit for transporting goods, shipping and supply chains were chaotic: inefficient, complex, frictional. With the advent of the shipping container, the same artefact could be used for transportation via ships, trains, lorries etc.

With containers we can share and transport software via a single standardised unit that works regardless of the host operating system or server. We can also iterate different software environments easily: local, production, test etc. As with the shipping of goods, standardisation has driven down running costs and increased the speed of transport.

Containers and software

  • Containers are a technology that allow you to package and isolate applications with their entire runtime environment. This makes it easy to move the contained application between various environments whilst retaining full functionality.

  • The technology of containerization is distinct from Docker. Docker is a particular implementation of containerization that simplifies the process and bases it on a standardised specification.

  • Containers are native to the Linux kernal and are key part of how it works. Thus when you run containers on Linux, you are using native capability. When you use containers on Windows or Mac you have to run a virtual version of Linux in order to exploit the capabilities of that kernel. (Docker provides this)

How containers work

A key feature of the Linux kernal is the existence of cgroups (control groups).

Containerization = resource control + process isolation

  • A cgroup groups a series of processes together and contrains their access to system resources (CPU, memory, disk)
  • Cgroups use namespaces to provide process isolation: groups of processes are isolated so that they cannot access other processes on the system. For example a container is ignorant of the underlying operating system and network, by default.

In ordinary user space applications share the same processor, memory and file system resources. This increases the likelihood of resourcing challenges, dependency conflicts and security threats. Without modularisation and the titration of resources, you are opened up to much greater possibility of failure.

For example one application could fill up the harddrive preventing other applications from writing to it. One application can “bring down” another applicaton.

Prior to containerization, in an enterprise environment most of the system administration consisted in managing resouces to avoid excessive resource expenditure and security challenges.

Standard userspace

Userspace with containerization

Differences with virtual machines

Containers are similar in many regards to VMs. They both offer a virtualized environment in which to run software and they both provide isolation of resources. (When you start up a VM you specify the available RAM and disk space.)

The central difference is that VMs require the existence of a full operating system. Containers can run without an OS although it is often convenient to run them with stripped-down Linux distributions.

A VM contains a complete installation of a guest OS and requires a hypervisor on the host OS to manage the different operating environments. This makes them slower and consume more resources.

A containerized system radically reduces this overhead. It just starts up the container and after that it’s job is done since the Linux kernel handles the rest as it would any other process on the OS.

Virtual MachineContainer
Isolation of resources and operating systemIsolation of resources only
Require a hypervisor to runRequire a container runtime to run
Slower due to additional abstractionFaster due to less overhead
Less portableMore portable
Slower and more difficult to runScale rapidly due to lightweight nature

Why use containers?

  • portability
  • scalability
  • efficiency
  • isolation
  • DevOps agility
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Controlled_components_in_React.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Controlled_components_in_React.html deleted file mode 100644 index 0661f68..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Controlled_components_in_React.html +++ /dev/null @@ -1,50 +0,0 @@ -Controlled components - My Zettelkasten - - - - -

Controlled components

Controlled components relate to how you use forms in React.

You can use standard form HTML within a React component but applying React state to the form via controlled components gives you greater power over what you do with the inputs and how you handle the data that is received.

Standard HTML forms have a separate state from the rest of the document object and this is highly mutable. It can send requests to a server and reload the page. This mutability can obviously interfere with the state you maintain in your React components; this is why it is best to manage form state along with React state.

We can combine the two [native HTML form state and React state] by making the React state be the “single source of truth”. Then the React component that renders a form also controls what happens in that form on subsequent user input. An input form element whose value is controlled by React in this way is called a “controlled component”.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Corresponding_material_and_biconditional.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Corresponding_material_and_biconditional.html deleted file mode 100644 index 5bee951..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Corresponding_material_and_biconditional.html +++ /dev/null @@ -1,50 +0,0 @@ -Corresponding material conditional to show validity - My Zettelkasten - - - - -

Corresponding material conditional to show validity

To demonstrate truth-functional validity we have to construct a truth-table which contains each of the premises and the conclusion and then review each row to see if there is an assignment where both the premises and the conclusion are true.

A simpler way to get the same result is to invoke the corresponding material conditional. Here we concatenate the premises using conjunction and then join them to the conclusion using the material conditional, which then becomes the main connective. We then populate the truth table for this compound proposition. If it is logically true, the argument is valid.

Demonstration

We will demonstrate with the following set:

$$ \{ P \leftrightarrow Q, P \lor Q, P \land Q \} $$

\(P\)\(Q\)\(P \leftrightarrow Q\)\(P \lor Q\)
TTTT
TFFT
FTFT
FFTF
\(P\)\(Q\)\((P \leftrightarrow Q) \land (P \lor Q)) \leftrightarrow (P \land Q)\)
TTT
TFT
FTT
FFT

We see above that the main connective, the material conditional returns true for every truth-functional assignment. In other words it is logically true. Consequently the argument is valid

Corresponding material biconditional

We can use the corresponding material biconditional as a shorthand for demonstrating logical equivalence between two propositions.

For two putatively equivalent propositions \(P\) and \(Q\), \(P\) and \(Q\) are logically equivalent if the compound proposition \(P \leftrightarrow Q\) is logically true.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Coulombs_Laws.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Coulombs_Laws.html deleted file mode 100644 index e95956f..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Coulombs_Laws.html +++ /dev/null @@ -1,50 +0,0 @@ -Coulombs Laws - My Zettelkasten - - - - -

Coulombs Laws

Coulomb’s Laws express the fundamental relationship between electric charge, force and attraction. They are also known as the Electrostatic Laws and define the electic force.

First Law

Like charges of electricity repel each other. Unlike charges attract each other.

Within the atom we see this at work in the way that negatively charged electrons are attracted to the positively charged nucleus. This attractive force is balanced by the centrifugal force caused by the electron’s rotation around the nucleus. This keeps the electrons in orbit. Without it, they would spiral into the nucleus.

Within circuits, the first law dictates the movement of charge from negatively charged atoms to positively charged atoms through the conductor.

Second Law

The attraction or repulsion between charges acts along the line between the two charges.

Third Law

The size of the electric force varies inversely as the square of the distance between the two charges. Thus if the distance between the two charges is doubled, the attraction or repulsion becomes weaker, decreasing to a quarter of the original value.

Fourth Law

The size of the electric force is proportional to the value of each charge measured in coulombs.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Create_Mongo_database.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Create_Mongo_database.html deleted file mode 100644 index c43abf2..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Create_Mongo_database.html +++ /dev/null @@ -1,51 +0,0 @@ -Creating a MongoDB database - My Zettelkasten - - - - -

Creating a MongoDB database

First create a directory for the database and set permissions:

$ mkdir /data/db
-$ sudo chown -R `id -un` /data/db

Then start the Mongo daemon

mongod

This will run continuously in the terminal and should say somewhere that it is waiting for connections on port 27017. This command must be executed before you run any backend that interacts with the Mongo database.

MongoDB Compass

Compass is a graphical interface for viewing and interacting with the data in your Mongo database. It will automatically load to the default Mongo port: 27017.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Create_an_SQL_table.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Create_an_SQL_table.html deleted file mode 100644 index bb86e5c..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Create_an_SQL_table.html +++ /dev/null @@ -1,62 +0,0 @@ -Create an SQL table - My Zettelkasten - - - - -

Create an SQL table

We create tables in an SQL database with the CREATE command.

Below is an example of this in practice. Each field corresponds to a column. We specify the name of the field and its corresponding data type. Every table must have a primary key. In the example, employee_id is the primary key.

CREATE TABLE employee (
-    employee_id text PRIMARY KEY,
-    first_name text,
-    surname text,
-    address_number integer,
-    address_1 text,
-    address_2 text,
-    locality text,
-    region text,
-    postal_code text,
-    phone_number text,
-    days_per_week real
-    );

Check table metadata

We can use DESCRIBE [table_name] any time we want to list out the data types and other metadata about the table.

We can use SHOW TABLE STATUS/

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Create_timed_systemd_job.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Create_timed_systemd_job.html deleted file mode 100644 index d13a407..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Create_timed_systemd_job.html +++ /dev/null @@ -1,66 +0,0 @@ -Create timed systemd job - My Zettelkasten - - - - -

Create timed systemd job

To use systemd to run a bash script at 11am each day, you can create a new systemd service file. Here is an example of what the service file might look like:

[Unit]
-Description=Run My Script
-
-[Service]
-Type=simple
-ExecStart=/bin/bash /path/to/my_script.sh
-
-[Install]
-WantedBy=default.target

Save this file to /etc/systemd/system/my_script.service.

Then you can use systemd to schedule the script to run at 11am each day by creating a new systemd timer file. Here is an example of what the timer file might look like:

[Unit]
-Description=Run My Script Daily at 11am
-
-[Timer]
-OnCalendar=*-*-* 11:00:00
-
-[Install]
-WantedBy=timers.target

Save this file to /etc/systemd/system/my_script.timer

Then you can enable and start the timer with the following commands:

sudo systemctl enable my_script.timer
-sudo systemctl start my_script.timer

This will run the script at 11am everyday You can check the status of the timer with the following command:

sudo systemctl status my_script.timer
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Creating_a_Docker_image.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Creating_a_Docker_image.html deleted file mode 100644 index 0a2a1cb..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Creating_a_Docker_image.html +++ /dev/null @@ -1,112 +0,0 @@ -Creating a Docker image - My Zettelkasten - - - - -

Creating a Docker image

We create a new image with docker build...

The key components of a build:

  • A Dockerfile
  • An asset directory (the build context) containing the Dockerfile and all resources needed for the build.

Syntax

Here is an example of a Dockerfile that builds a container for running a Python app:

# Use an official Python runtime as a parent image
-FROM python:3.8-slim
-
-# Set the working directory to /app
-WORKDIR /app
-
-# Copy the current directory contents into the container at /app
-COPY . /app
-
-# Install any needed packages specified in requirements.txt
-RUN pip install --trusted-host pypi.python.org -r requirements.txt
-
-# Make port 80 available to the world outside this container
-EXPOSE 80
-
-# Define environment variable
-ENV NAME World
-
-# Run app.py when the container launches
-CMD ["python", "app.py"]
-

Main syntax explained

KeywordRole
#Lines starting with ’#' are comments, providing explanations or context for the Dockerfile.
FROMSpecifies the base image used to build the new image. In this case, it’s using the official Python 3.8 slim image.
WORKDIRSets the working directory for any subsequent instructions in the Dockerfile. Here, it’s set to ‘/app’. Everything after a WORKDIR line, all instructions will be executed in this directory. If it doesn’t exist, Docker will create it. Can have multiple.
COPYCopies files or directories from the source (in this case, the current directory) to the destination (in this case, ‘/app’) within the Docker image. The source is the build context. We are copying from the build context to the container when we use this keyword.
ADDSame as COPY but can be passed a tarball or a URL
RUNExecutes a command and commits the result as a new layer in the image. In this example, it installs packages specified in the ‘requirements.txt’ file using pip.
EXPOSEInforms Docker that the container listens on the specified network ports at runtime. In this case, port 80.
ENVSets an environment variable in the image. In this example, the variable ‘NAME’ is set to ‘World’.
CMDSpecifies the command to run when the container starts. Here, it runs ‘app.py’ using Python. Note that there can only be one CMD instruction in a Dockerfile.
USERThe default user will be root. This is not good for security. Have to choose a distribution image that allows you to change user. For example: USER: nobody:nogroup. Ubuntu allows for this.
LABELMetadata that you want to add to the image to be viewable when image is inspected, e.g. LABEL maintainer=tactonbishop@gmail.com

Another example

The following Dockerfile creates a frontend React application:

# Use the official Node.js image as the base image
-FROM node:14-alpine
-
-# Set the working directory to /app
-WORKDIR /app
-
-# Copy the package.json and package-lock.json files
-COPY package*.json ./
-
-# Install dependencies
-RUN npm ci
-
-# Copy the rest of the application code
-COPY . .
-
-# Expose the port the app will run on
-EXPOSE 3000
-
-# Start the React development server
-CMD ["npm", "start"]

Two modes of RUN: shell and exec

The RUN command in a Dockerfile has two forms: the “exec” form and the “shell” form. Both forms are used to execute commands during the build process, but they have different syntax and behavior.

Exec form is written as RUN ["executable", "param1", "param2", ...]. This form executes the command directly without invoking a shell. As a result, shell processing features like environment variable substitution, pipes, and redirects are not available. It is the preferred form when you need to run a command without relying on shell behavior or when you want to avoid shell-related issues, such as variable substitution or command injection.

Shell form is written as RUN command param1 param2 .... This form executes the command within a shell, which is /bin/sh -c on Linux and cmd /S /C on Windows. It allows for shell processing, enabling environment variable substitution, pipes, redirects, and other shell features. This form is preferred when you need to use shell features or when you want to chain multiple commands together.

Environmental variables

ENV instructions in a Dockerfile are used to define environment variables that can be accessed by the processes running inside the container. These variables can be used to configure the behavior of the application, pass parameters, or store sensitive information like API keys.

# Use an official Node.js runtime as a parent image
-FROM node:14-alpine
-
-# Set the working directory to /app
-WORKDIR /app
-
-# Copy package.json and package-lock.json into the container
-COPY package*.json ./
-
-# Install any needed packages specified in package.json
-RUN npm ci
-
-# Copy the rest of the application code
-COPY . .
-
-# Set environment variables
-ENV PORT=8000
-ENV API_KEY=my_secret_key
-
-# Expose the port the app will run on
-EXPOSE 8000
-
-# Run the app
-CMD ["npm", "start"]

In this example, two environment variables are defined: PORT and API_KEY. These variables can be accessed in the application code using process.env.PORT and process.env.API_KEY in Node.js, for example.

To override the environment variables defined in the Dockerfile when running the container, you can use the -e flag followed by the variable name and its new value in the docker run command:

docker run -e PORT=8080 -e API_KEY=new_secret_key -p 8080:8000 <image_name>
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Creating_a_Linux_partition_table.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Creating_a_Linux_partition_table.html deleted file mode 100644 index b84f69d..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Creating_a_Linux_partition_table.html +++ /dev/null @@ -1,131 +0,0 @@ -Creating a Linux partition table - My Zettelkasten - - - - -

Creating a Linux partition table

Creating a partition table

To demonstrate the process of partitioning a harddrive I am going to repartition an external SATA drive as if it were being primed for a fresh Linux install.

Let’s take a look at the disk in its current form:

$ fdisk -l
-
-  Disk /dev/sda: 465.74 GiB, 500079525888 bytes, 976717824 sectors
-  Disk model: My Passport 071Aumount /dev/sda2
-  Disklabel type: gpt
-  Disk identifier: 9993F1BB-626C-485F-8542-3CC73BB40953
-
-  Device      Start       End   Sectors   Size Type
-  /dev/sda1      40    409639    409600   200M EFI System
-  /dev/sda2  409640 976455639 976046000 465.4G Apple HFS/HFS+

(This disk was previously used as a backup disk for MacOS so in addition to the extended partition which has a proprietary file system type (Apple HFS) it has a primary partition which would load the recovery OS. In contrast to my main harddrive this uses the standard SCSI prototcol and thus the partitions are prepended with sda.)

1. Unmount existing partitions

umount /dev/sda1
-umount /dev/sda2

2. Deleting the existing partitions

# Load the disk into fdisk
-$ sudo fdisk /dev/sda
-Command (m for help): d
-Partition number (1,2, default 2): 1
-Partition 1 has been deleted.
-Command (m for help): d
-Selected partition 2
-Partition 2 has been deleted.
-
-# Verify deletion with p(rint) command
-Command (m for help): p
-Disk /dev/sda: 465.74 GiB, 500079525888 bytes, 976717824 sectors
-Disk model: My Passport 071A
-Units: sectors of 1 * 512 = 512 bytes
-Sector size (logical/physical): 512 bytes / 512 bytes
-I/O size (minimum/optimal): 512 bytes / 512 bytes
-Disklabel type: gpt
-Disk identifier: 9993F1BB-626C-485F-8542-3CC73BB40953
-
-# Write the changes to disk with w(rite)
-w
-
-# Check execution:
-$ lsblk
-
-NAME        MAJ:MIN RM   SIZE RO TYPE MOUNTPOINTS
-sda           8:0    0 465.7G  0 disk

So now the disk has no partitions, just the physical disk space and no mountpoints. We are ready to re-partition.

3. Re-partition the disk

We are going to create a GPT partition table

$ sudo fdisk /dev/sda
-Command (m for help): g
-Created a new GPT disklabel (GUID: E316B1A9-6F73-FB41-8CBB-FA4E3C448F2B).
-
-Command (m for help): n
-Partition number (1-128, default 1):
-First sector (2048-976717790, default 2048):
-
-# Just press enter here
-
-# The last sector is where we put the actual size we want for the partition
-Last sector, +/-sectors or +/-size{K,M,G,T,P} (2048-976717790, default 976715775): +100G
-Created a new partition 1 of type 'Linux filesystem' and of size 100 GiB.
-
-# For the second and final partition, we follow the same steps but don't add a partition size, since it will default to what is left.
-
-Command (m for help): n
-Partition number (2-128, default 2):
-First sector (209717248-976717790, default 209717248):
-Last sector, +/-sectors or +/-size{K,M,G,T,P} (209717248-976717790, default 976715775):
-
-Created a new partition 2 of type 'Linux filesystem' and of size 365.7 GiB.
-
-# Check the partitions with p(rint)
-Command (m for help): p
-Disk /dev/sda: 465.74 GiB, 500079525888 bytes, 976717824 sectors
-Disk model: My Passport 071A
-Units: sectors of 1 * 512 = 512 bytes
-Sector size (logical/physical): 512 bytes / 512 bytes
-I/O size (minimum/optimal): 512 bytes / 512 bytes
-Disklabel type: gpt
-Disk identifier: 92739978-F7D2-5042-9758-C1429B5C8E11
-
-Device         Start       End   Sectors   Size Type
-/dev/sda1       2048 209717247 209715200   100G Linux filesystem
-/dev/sda2  209717248 976715775 766998528 365.7G Linux filesystem
-
-# Then write with w
-Command (m for help): w
-The partition table has been altered.
-Calling ioctl() to re-read partition table.
-Syncing disks.

We can now confirm our new partitions:

$ lsblk
-NAME        MAJ:MIN RM   SIZE RO TYPE MOUNTPOINTS
-sda           8:0    0 465.7G  0 disk
-├─sda1        8:1    0   100G  0 part
-└─sda2        8:2    0 365.7G  0 part

Naming a partition

By default each partition will have its GUID as its name, but you can add a human friendly name with:

sudo e2label /dev/sda1 my_human_name

Whilst we have created our partitions we cannot yet mount them. This is because we have not yet set up a filesystem on the partitions. This is the next step.

Linux disk partitions

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Creating_a_Mongo_schema_and_model.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Creating_a_Mongo_schema_and_model.html deleted file mode 100644 index d3ca146..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Creating_a_Mongo_schema_and_model.html +++ /dev/null @@ -1,61 +0,0 @@ -Creating a schema and model - My Zettelkasten - - - - -

Creating a schema and model

Schema

In order start adding collections and documents to our database, we use Mongoose’s schema structure. (This is specific to Mongoose and is not a structure that is a part of Mongo in general.)

We use a schema to define the shape of documents in a MongoDB collection. To do this we instantiate an instance of the Mongoose Schema class and set our properties:

Creating a schema

const courseSchema = new mongoose.Schema({
-  name: { type: String, required: true, minlength: 5, maxlength: 255 },
-  author: String,
-  tags: [String],
-  data: { type: Date, default: Date.now }, // if unspecified, entry will default to current date
-  isPublished: Boolean,
-});

This is similar to declaring a type or interface in TypeScript

Available data types

The following data types are available:

  • String
  • Number
  • Boolean
  • Array
  • Date
  • Buffer
  • ObjectID (for UUIDs)

Note that we set our validation criteria as the second property for each schema value. There is more info info on validation in a separate entry;

Models

Once we have established our schema we can then create a model of it. A model is basically a class representation of the interface we define in the schema:

const Course = mongoose.model("Course", courseSchema);

Now we can start adding specific courses as documents to our collection. We do this by referring to the model, i.e.

const course = new Course({
-  name: "Node.js Course",
-  author: "Ozzy Osbourne",
-  tags: ["node", "backend"],
-  isPublished: true,
-});

Outcome

Having created a database, connected to it with Mongoose, and created a model we will see our collection reflected in Compass:

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Creating_memory_with_NAND.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Creating_memory_with_NAND.html deleted file mode 100644 index 03414ae..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Creating_memory_with_NAND.html +++ /dev/null @@ -1,51 +0,0 @@ -Creating memory with NAND gates - My Zettelkasten - - - - -

Creating memory with NAND gates

The Digital_circuits below demonstrates how memory can be created using NAND gates. A single bit is stored in memory.

Interactive version of circuit:

-

Components

  • I is where we input the bit that we want to remember.
  • O is the output of the remembered bit
  • S is an input that tells these gates when to set the memory.
  • A, B, C are internal wires that represent the individual bit values which channel into each gate

State changes

First state: S ON, I OFF

  • Start with S ON and I OFF.
  • Given the logic of NAND, A will be on.
  • This means Gate 2 is receiving ON from A and ON from S therefore B is OFF
  • Moving to Gate 4 it is receiving OFF from B and it’s other input is not activated so is therefore also OFF. Consequently C is ON
  • C is fed as the second input into Gate 3, thus we have both inputs (A and C) as ON, therefore the output will make O OFF

Upshot: With S ON, output is the same as input

Second state: both S and I ON

  • With S and I both on, Gate A will be OFF
  • Gate 2 is receiving OFF from A and ON from S therefore B is ON
  • A feeds into Gate 2 which is receiving ON from S, therefore the output (B) will be ON
  • A feeds into Gate 3 and the other input is OFF, therefore Gate 3 is outputting ON. Thus O is ON
  • O feeds back to Gate 4 which is receiving ON from B thus we have two ON inputs going into Gate 4, turning C off
  • This means the two inputs going into Gate 3 are both OFF, keeping O ON

Upshot: With S on, the output is again the same as the input

So far we have seen that when S is ON you can change I on and off and O will change with it.

Memory

When S is ON, O will mirror whatever state I is in. However if you turn S OFF, O will remain in whatever state it was when S was turned OFF. You can toggle I as much as you like, O will remain in its previous state. Hence creating a memory store of the past value of I.

The specific reason for this is that, if S is OFF, both A and B are ON since at Gate 1: ON (I) + OFF (S) = ON and OFF (I) + OFF (S) = OFF and at Gate 2: OFF (Gate 1) + OFF (S) = OFF

This is illustrated in the diagram below. The space occupied by A and B remains on (note it is illuminated) regardless of the state of I.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Cron.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Cron.html deleted file mode 100644 index 5f1b17b..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Cron.html +++ /dev/null @@ -1,57 +0,0 @@ -Cron - My Zettelkasten - - - - -

Cron

cronie

In Arch Linux I use cronie for cron jobs. (There is no cron service installed by default). Install cronie and then enable it in systemd with:

systemctrl enable --now cronie.service

commands

List cron jobs

crontab -l

Open cron file

crontab -e

Check cron log


-journalctl | grep CRON
-# Different distros have different loggers

Syntax

m h d mon dow command
-# minute, hour, day of month, day of week, bash script/args
-# 0-59, 0-23, 1-31, 1-12, 0-6

Examples

Run on the hour every hour

0 * * * * mysqlcheck --all-databases --check-only-changed --silent

At 01:42 every day:

42 1 * * * mysqlcheck --all-databases --check-only-changed --silent

Every half hour:

0,30 * * * * ${HOME}/bash_scripts/automate_commit.sh
-

Shorthands

  • @reboot – Run once, at startup
  • @yearly – Run once a year, “0 0 1 1 *”.</>
  • @annually – same as @yearly
  • @monthly – Run once a month, “0 0 1 * *”
  • @weekly – Run once a week, “0 0 * * 0”
  • @daily – Run once a day, “0 0 * * *”
  • @midnight – same as @daily
  • @hourly – Run once an hour, “0 * * * *”

Examples

@hourly mysqlcheck --all-databases --check-only-changed --silent
-

View the logs

sudo grep crontab syslog
-
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Current.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Current.html deleted file mode 100644 index 75fee4c..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Current.html +++ /dev/null @@ -1,55 +0,0 @@ -Current - My Zettelkasten - - - - -

Current

Electrical current is the movement of electrons from negatively charged atoms to positively charged atoms when an appropriate external force is applied.

Current is the flow of electrons. Charge is the quantity that flows.

The amount of current is the sum of the charges of the moving electrons past a given point.

Why current exists

Current exists because of the first law of electrostatics.

When there is an excess of electrons at one terminal (i.e. negatively charged atoms) and a deficiency of electrons at the other terminal (i.e. positively charged atoms), a difference of potential exists between the two terminals.

When the terminals are connected to each other via a conductor (e.g. copper wire) electrons will flow along the conductor. This is provided that there is a source to supply electrons at one end and remove them at the other. We call this force the voltage source.

The diagram below illustrates the flow of current where the circles are electrons knocking into each other and passing current:

Electrons travel very slowly through a conductor. This is in contrast to their intrinsic motion which of course equal to the speed of light (186, 000 miles per second).

Formal expression

We measure charge in Coulombs (\(C\)). A Coulomb is an aggregate of the charge of thousands of electrons because their individual charge is so small. One Coulomb is equal to the charge of \(6.24 \times 10 ^{18}\) electrons.

We measure current in amps. When one coulomb of charge moves past a point in one second it is called an ampere (amp) represented as \(A\).

This relationship is captured in the following equation:

$$ -I = \frac{Q}{t} -$$

  • \(I\) = current measured in amps
  • \(Q\) = quantity of electrical charge measured in coulombs
  • \(t\) = time

Application

Calculate the current in amps if 9 coulombs of charge flow past a point in an electric circuit in 3 seconds.

$$ -I = \frac{9}{3} \\ -I = 3 A -$$

Direction of current

In terms of the physics, current flows due to the movement of charged particles from atoms which are negatively charged to atoms which are positively charged. However when it comes to the representation of current in electrical circuits the convention is to view current as flowing from the positive to the negative terminal.

This is obviously physically inaccurate however it became the convention before electrons were properly understood when charge was thought to be a property of protons. So we are stuck with this convention in electronics.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Custom_React_hook_examples.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Custom_React_hook_examples.html deleted file mode 100644 index f162e2d..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Custom_React_hook_examples.html +++ /dev/null @@ -1,105 +0,0 @@ -Custom hook examples - My Zettelkasten - - - - -

Custom hook examples

Determine viewport width

Hook

// useViewportWidth.js
-import { useEffect, useState } from "react";
-
-export default function (viewportWidth) {
-  const [matchesViewportWidth, setMatchesViewportWidth] = useState(false);
-
-  useEffect(() => {
-    const handleResize = () =>
-      window.innerWidth < viewportWidth
-        ? setMatchesViewportWidth(true)
-        : setMatchesViewportWidth(false);
-
-    window.addEventListener("resize", handleResize);
-
-    // Call on initialization to determine initial width
-    handleResize();
-
-    // Clean-up listener to prevent memory leaks
-    return () => window.removeEventListener("resize", handleResize);
-  }, [viewportWidth]);
-
-  return matchesViewportWidth;
-}

Unit test

import useViewportWidth from "./useViewportWidth";
-import { fireEvent } from "@testing-library/react";
-import { act } from "react-dom/test-utils";
-import { renderHook } from "@testing-library/react-hooks";
-
-describe("useViewportWidth", () => {
-  it("returns `true` when window resized to mobile viewport width", () => {
-    // Arrange
-    const { result } = renderHook(() => useViewportWidth(768));
-
-    // Act
-    act(() => {
-      window.innerWidth = 500;
-      fireEvent(window, new Event("resize"));
-    });
-
-    // Assert
-    expect(result.current).toBe(true);
-  });
-
-  it("returns `false` when window resized to width greater than mobile viewport", () => {
-    // Arrange
-    const { result } = renderHook(() => useViewportWidth(768));
-
-    // Act
-    act(() => {
-      window.innerWidth = 1058;
-      fireEvent(window, new Event("resize"));
-    });
-
-    // Assert
-    expect(result.current).toBe(false);
-  });
-})``;
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Custom_types_in_TypeScript.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Custom_types_in_TypeScript.html deleted file mode 100644 index e5ff5a4..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Custom_types_in_TypeScript.html +++ /dev/null @@ -1,110 +0,0 @@ -Custom types - My Zettelkasten - - - - -

Custom types

Objects and classes are where TypeScript becomes most useful and powerful. In TypeScript, objects and classes are by definition custom types.

When typing objects, you do not write the types alongside the actual data as you would with primitive types, classes and functions. Instead you write a custom type which is a type-annotated object. This is then applied to the object or class, where you create instances that match the shape of the custom declaration.

So say we have this object:

const age = {
-  name: "Thomas",
-  yearOfBirth: 1988,
-  currentYear: 2021,
-  ageNow: function () {
-    return this.currentYear - this.yearOfBirth;
-  },
-};

We could write this as type with the following:

let Age: {
-  name: string;
-  yearOfBirth: number;
-  currentYear: number;
-  ageNow: () => number;
-};

(We use : because we are declaring a type not intialising a value of the type.)

We could now re-write the first age object as an object of type Age :

let thomas: typeof Age;
-
-thomas = {
-  name: "Thomas",
-  yearOfBirth: 1988,
-  currentYear: 2021,
-  ageNow: function () {
-    return this.currentYear - this.yearOfBirth;
-  },
-};

In practice, defining the type and then asserting that a new variable is of this type and then initialising it is rather long-winded. It is better practice to simplify the process by creating a type alias.

type Age = {
-  name: string;
-  yearOfBirth: number;
-  currentYear: number;
-  ageNow(): number; // we type the method on the basis of the value it returns
-};

We could then create objects based on this:

const thomas: Age = {
-  name: "Thomas",
-  yearOfBirth: 1988,
-  currentYear: 2021,
-  ageNow: function () {
-    return this.currentYear - this.yearOfBirth;
-  },
-};

Note that we pass in :Age as our type declaration, using the custom type in the same way as we would use :string or number[] . We can now use this custom type as a type annotation anywhere we use type annotations; it can be used exactly the same way as a primitive type in our code.

Age is an alias for the type that thomas conforms to.

The benefit is that TS will correct you if:

  • attempt to assign a type to a value that does not match the custom type declaration (for instance: assigning a string value to a property you have typed as number)
  • attempt to add a property that is not specified in the custom type declaration

Although you can subsequently extend the custom type (detailed below).

Duck typing

Types are defined by the collection of their properties not their name.

Typescript’s implementation of types is as a structural type system, which contrasts with a nominal type system. This is often referred to colloquially as ‘duck typing’: if it looks like a duck, walks like a duck, and sounds like a duck, it probably is a duck.

With custom (object types) this means that the following expression of an object of type Age doesn’t generate an error, TS is satisfied that the shapes of each match.

const martha = {
-  name: "Martha",
-  yearOfBirth: 1997,
-  currentYear: 2021,
-  gender: "female",
-};
-
-const addition: Age = martha;

But if we tried to add this extra property whilst defining martha as an instance of the custom type Age , we would get an error:

const martha: Age = {
-  name: "Martha",
-  yearOfBirth: 1997,
-  currentYear: 2021,
-  gender: "female",
-};
Type '{ name: string; yearOfBirth: number; currentYear: number; ageNow: () => number; gender: string; }' is not assignable to type 'Age'. **Object literal may only specify known properties, and 'gender' does not exist in type 'Age'.**

It means that even though in the following, the variable point is never declared to be of the type Point , it matches the shape of the custom type. As the structural integrity is maintained, it can be passed to the function without error.

interface Point {
-  x: number;
-  y: number;
-}
-
-function logPoint(p: Point) {
-  console.log(`${p.x}, ${p.y}`);
-}
-
-// logs "12, 26"
-const point = { x: 12, y: 26 };
-logPoint(point);

Shape matching only requires a subset of the object’s fields to match:

const point3 = { x: 12, y: 26, z: 89 };
-logPoint(point3); // logs "12, 26"
-
-const rect = { x: 33, y: 3, width: 30, height: 80 };
-logPoint(rect);

Interfaces

For most purposes the keywords type and interface are interchangeable in TypeScript.

(The main difference that I have encountered is that Angular specifies that interfaces should be used over types, but this is because it is class-based and object oriented).

For me, the main decider is that Angular favours interface over type. The TS handbook recommends using the type keyword over interface.

An interface is concept that crosses over from strict OOP and it doesn’t quite apply to interfaces in TS because an interface is a declaration of a class’s functions alone, not its data (i.e properties).

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/DRAM_and_SRAM_memory.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/DRAM_and_SRAM_memory.html deleted file mode 100644 index 61e9d7c..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/DRAM_and_SRAM_memory.html +++ /dev/null @@ -1,50 +0,0 @@ -DRAM and SRAM memory - My Zettelkasten - - - - -

DRAM and SRAM memory

There are two types of RAM memory: SRAM and DRAM.

DRAM

DRAM uses capacitors to create the memory cell:

a capacitor is an electronic component that stores electrical energy in an electrical field. A device which can accumulate and release electrical charge.

In a DRAM cell, each bit of data is stored as a charge in a capacitor. The presence of charge represents a ‘1’ bit and the absence of charge represents a ‘0’ bit. Each of these cells is paired with a transistor that controls the reading and writing of data.

However capacitors lose charge over time due to leaks. As a result DRAM is memory that needs to be refreshed (recharged) frequently. For this reason and because it only uses one transistor and capacitor per bit, DRAM is the less expensive form of volatile memory.

SRAM

SRAM (Static Random Access Memory) is also volatile memory but its electronical implementation is different. Unlike DRAM it doesn’t use capacitors. Consequently the transistors do not leak or need to be refreshed, hence why SRAM is static and DRAM is dynamic.

SRAM uses flip flops to store the bits. It also uses multiple transistors per bit. This makes it faster than DRAM but more expensive. DRAM is at least ten times slower than SRAM.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Daemons.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Daemons.html deleted file mode 100644 index 47e7364..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Daemons.html +++ /dev/null @@ -1,50 +0,0 @@ -Daemons - My Zettelkasten - - - - -

Daemons

A programme that runs in the background, performing a system function. A daemon typically starts at boot or login without having to be specifically launched and keeps running permanently or until manually stopped.

The custom is for the process name of daemons to end in the letter d.

In the original Greek daemon is translated as ‘helper’, it doesn’t have the medieval connotation of a dark spirit but was used to denote the actions of a god rather than the god itself. A person could have a personal daemon which determines their fate.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Data_types_in_Bash.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Data_types_in_Bash.html deleted file mode 100644 index d3f7ae8..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Data_types_in_Bash.html +++ /dev/null @@ -1,50 +0,0 @@ -Data types in Bash - My Zettelkasten - - - - -

Data types in Bash

There is no typing in Bash

  • Bash variables do not have types thus bash is neither loosely or strictly typed. Anything you apply the identity operator against becomes a character string variable.
  • Bash is however able to distinguish numerical strings which is why arithmetic operations and comparisons work.
  • Consequently there is no null type either. The closest thing is an empty string, i.e. APPROX_NULL="" .

Declarations

You can achieve a sort of typing through the declare keyword, although bear in mind this is not enforced and you do not have to use it.

-r : readonly

declare -r var1="I'm read only"

Roughly equivalent to a const : if you attempt to change the value of var1 it will fail with an error message.

i : integer

declare -i var2="43"

The script will treat all subsequent occurrences of var2 as an integer

a : array

declare -a anArray
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Data_types_in_MySQL.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Data_types_in_MySQL.html deleted file mode 100644 index 88b2ee3..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Data_types_in_MySQL.html +++ /dev/null @@ -1,50 +0,0 @@ -Data types in MySQL - My Zettelkasten - - - - -

Data types in MySQL

An understanding of the differences between data types is important because it obviously affects the amount of memory the database uses.

Numeric

Integer (INT)

  • No fractional part, fixed number of digits
  • TINYINT, BIGINT etc are all instances of INT, the difference is the size of the number stored.

Fixed point (DECIMAL)

Contains decimal point. Use when accuracy is more important that representing very large or very small values. Hence you would use this for monetary amounts.

Floating point (FLOAT)

Contains decimal point. Use when the ability to represent very large and very small values is more important than precision. Hence you would not use this for monetary amounts.

String

Fixed-length character strings ()

Spaces are stripped in storage but represented with a character set.

An example would be CHAR(10) or CHAR(3). Here we set the upper limit but it must be the case that no string exceeds it. For either of these, if you add a value that is, e.g, two characters in length, it will add spaces to pad it out and make up the upper limit.

Variable-length character strings

As above but allowing for variable-length strings.

A common example is VARCHAR(255). The 255 refers to the maximal character length, not the byte length. It is the largest number of characters that can be accommodated by an 8-bit number (byte). We must put 255 as the parameter even if our character lengths will be below this but where we don’t know the minimum and maximum length.

Large object storage

Blob

For storing images, audio and other binary media. Variants: TINYBLOB, BLOB, MEDIUMBLOB LONGBLOB

Text

Like blob but has character set Variants: TINYTEXT, TEXT, MEDIUMTEXT, LONGTEXT

Date and time

  • DATE
  • DATETIME
  • TIMESTAMP

Speciality

Enumerations

  • ENUM: a single value from a list
  • SET: several values from a list

Storage limits

Each row can have a maximum of 65,535 bytes.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Database_indices.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Database_indices.html deleted file mode 100644 index 2e74f8e..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Database_indices.html +++ /dev/null @@ -1,50 +0,0 @@ -database indices - My Zettelkasten - - - - -

database indices

A database index is best understood by analogy with physical data. Imagine needing to find information about a specific topic in a very long book. Without being able to turn to the back and consult the index we would need to scan every page of the book looking for information on the topic we are seeking.

Similarly with a database if we are looking for a specific value in a very long table it can be computationally costly and slow to iterate through every row looking for a specific value (this is known as a “full table scan”).

For this reason we use indexes. In a database an index is like a shortcut or quick reference guide. However instead of page numbers as in the book analogy, the database index has pointers to the actual location of the rows in the table. If an index is applied to a given column, when an element in that column is requested, the database will not scan every row, instead it will go straight to the element using the index.

Say we are looking for the surname “Bishop” in a table that consists of lastName and phoneNumber . If we apply an index to the lastName column, the database will have a direct reference to the row that “Bishop” is in and thus can return the phoneNumber value more quickly.

Although the programmer can explicitly create indexes, the way the database utilises it is largely abstracted from view. Most RDMSs will automatically decide which index to use for query optimisation however the programmer can also use hints to force the use of a specific index.

The main thing is to think about data points that would benefit from an index, for instance for the most heavily used queries or those that run against the longest tables.

While indices make lookups more performant, they should be used judiciously as they increase the storage space the database requires and can incresae the execution time of queries that insert or update records. (This makes sense, as any update to a row, requires a reindexation of the table.)

The best use case for an index is for data retrieval that utilises WHERE clauses.

SQL syntax

CREATE INDEX index_name ON table_name(column_name)
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Database_options_on_AWS.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Database_options_on_AWS.html deleted file mode 100644 index 36dec50..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Database_options_on_AWS.html +++ /dev/null @@ -1,50 +0,0 @@ -Database options - My Zettelkasten - - - - -

Database options

Amazon offers numerous database options however they are often named differently or are Amazon’s own implementation of a certain database type:

  • Relational databases

    • Amazon offers two core RDSs: Amazon Aurora and Amazon RDS. Both allow you to use MySQL and PostgreSQL as the management implementation. The differences come down to which management implmentations are supported, number of backups and throughput. For instance Aurora has higher performance, more logging and fail-safes.
  • NoSQL

    • Document-based databases
      • The obvious candidate for this kind of database is MongoDB. Amazon doesn’t offer MongoDB it offers its own implementation which is almost identical and compatible with Mongo: Amazon DocumentDB. (There is some bitching about this from Mongo but they are competitors.)
    • Key-value database
      • A key-value database is basically a hash-table or a map
      • The Amazon implementation of this is DynamoDB
      • Confusingly, for NoSQL, a DynamoDB instance comprises “tables” which are groupings of keys and values. I guess “table” here is meant in terms of “hash table”
      • A cool feature is that you can subscribe to a DynamoDB table and run a lambda when a value changes.
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Dates_in_Python.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Dates_in_Python.html deleted file mode 100644 index a950fb7..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Dates_in_Python.html +++ /dev/null @@ -1,75 +0,0 @@ -Dates in Python - My Zettelkasten - - - - -

Dates in Python

Python’s built-in datetime module provides various classes for manipulating dates and times.

Importing datetime

import datetime

Getting Current Date and Time

Get the current date and time using datetime.datetime.now().

current_datetime = datetime.datetime.now()
-print("Current datetime:", current_datetime)

Creating Date Objects

To create a date object, use datetime.date, specifying the year, month, and day.

some_date = datetime.date(2021, 9, 30)
-print("Some date:", some_date)

Creating Time Objects

To create a time object, use datetime.time, specifying the hour, minute, second, and optionally microsecond.

some_time = datetime.time(13, 24, 56)
-print("Some time:", some_time)

Creating Datetime Objects

To create a datetime object, use datetime.datetime.

some_datetime = datetime.datetime(2021, 9, 30, 13, 24, 56)
-print("Some datetime:", some_datetime)

Extracting components

Extract components from a datetime object:

print("Year:", some_datetime.year)
-print("Month:", some_datetime.month)
-print("Day:", some_datetime.day)
-print("Hour:", some_datetime.hour)
-print("Minute:", some_datetime.minute)
-print("Second:", some_datetime.second)

Formatting datetime objects: strftime

The strftime method (string format time) converts a datetime object to a string according to the specified format.

This would typically be used when we have been working with a computer-friendly format of a date such as unix seconds which we then want to output in a more readable format.

Use strftime to express the current date as YYYY-MM:

now = datetime.now()
-formatted = now.strftime('%Y-%m')
-print(formatted)
-# 2024-06

Express the current date as YYYY-MM-DD H:M:S:

formatted_datetime = some_datetime.strftime('%Y-%m-%d %H:%M:%S')
-print("Formatted datetime:", formatted_datetime)

Express a unix timestamp as DD-MM-YYYY:

def convert_timestamp(timestamp):
-    date_object = datetime.datetime.fromtimestamp(timestamp)
-    formatted_date = date_object.strftime("%d-%m-%Y")
-    return formatted_date
-
-converted = convert_timestamp(1689023491)
-print(converted)
-# 10-07-2023

Parsing datetime strings: strptime.

The strptime (string_parse_time) method parses a string representing a date and/or a time according to a specified format and returns a datetime object.

Typically be used when want to carry out some sort of transformation on time data that we are sourcing in a particular format.

Receive a date in the format DD-MM-YYYY and convert to datetime object:

date_string = "18-06-2024"
-datetime_object = datetime.strptime(date_string, '%d-%m-%Y')
-print(date_object) # 2024-06-18 00:00:00

Extract the year from a UTC date format:

datetime_obj = datetime.strptime("2024-03-27T10:44:28Z", "%Y%m%dT%H%M%SZ")
-print(datetime_obj.strftime('%Y'))
-# 2024
-
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/DeMorgan's_Laws.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/DeMorgan's_Laws.html deleted file mode 100644 index a2680c4..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/DeMorgan's_Laws.html +++ /dev/null @@ -1,54 +0,0 @@ -DeMorgan’s Laws - My Zettelkasten - - - - -

DeMorgan’s Laws

DeMorgan’s laws express some fundamental equivalences that obtain between the Boolean Truth-functional_connectives.

First Law

The negation of a conjunction is logically equivalent to the disjunction of the negations of the original conjuncts.

$$ -\lnot (P \land Q) \leftrightarrow \lnot P \lor \lnot Q -$$

The equivalence is demonstrated with the following truth-table

\(P\)\(Q\)$ \lnot (P \land Q)$$ \lnot P \lor \lnot Q$
TTFF
TFTT
FTTT
FFTT ### Truth conditions

The negation of a disjunction is equivalent to the conjunction of the negation of the original disjuncts.

$$ -\lnot (P \lor Q) \leftrightarrow \lnot P \land \lnot Q -$$

\(P\)\(Q\)$ \lnot (P \lor Q)$$ \lnot P \land \lnot Q$
TTFF
TFFF
FTFF
FFTT
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Defining_a_computer.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Defining_a_computer.html deleted file mode 100644 index 6b6d469..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Defining_a_computer.html +++ /dev/null @@ -1,50 +0,0 @@ -Defining a computer - My Zettelkasten - - - - -

Defining a computer

A general-purpose computer is one that, given the appropriate instructions and required time, should be able to perform most common computing tasks.

This sets a general purpose computer aside from a special-purpose computer, like the one you might find in your dishwasher which may have its instructions hardwired or coded into the machine. Special purpose computers only perform a single set of tasks according to prewritten instructions. We’ll take the term computer to mean general purpose computer.

Simplified model of what a computer is: 1.4-Input-Process-Output.png

Although the input, output and storage parts of a computer are very important, they will not be the focus of this course. Instead we are going to learn all about the process part, which will focus on how the computer is able to follow instructions to make calculations.

Supplementary Resources

Early computing (Crash Course Computer Science)

Early Computing: Crash Course Computer Science #1

  • The abacus was created because the scale of society had become greater than what a single person could create and manipulate in their mind.
    • Eg thousands of people in a village and tens of thousands of cattle
  • In a basic abacus each row of beads (say its coloured) represents a different power of ten
  • As well as aiding calculation, the abacus acts as a primitive storage device
  • Similar early computing devices: astrolabe, slide rule, sunrise clocks, tide clocks

As each increase in knowledge, as well as on the contrivance of every new tool, human labour becomes abridged. Charles Babbage

  • One of the first computers of the modern era was the Step Reckoner built by Leibniz in 1694.
    • In addition to adding, this machine was able to multiply and divide basically through hacks because from a mechanical point of view, multiplications and divisions are just many additions and subtractions
    • For example, to divide 17/5, we just subtract 5, then 5, then 5 again until we can’t do anymore hence two left over
  • But as these machines were expensive and slow, people used pre-computed tables in book form generated by human computers. Useful particularly for things like square roots.
  • Similarly range tables were created that aided the military in calculating distances for gunboat artillery which factored in contextual factors like wind, drift, slope and elevation. These were used well into WW2 but they were limited to the particular type of cannon or shell

Screenshot_2020-08-09_at_21.32.54 1.png

Screenshot_2020-08-09_at_21.34.48.png

Before the invention of actual computers, ‘computer’ was a job-title denoting people who were employed to conduct complex calculations, sometimes with the aid of machinery, but most often not. This persisted until the late 18th century when the word changed to include devices like adding machines.

  • Babbage sought to overcome this by designing the Difference Engine which was able to compute polynomials. Complex mathematical expressions that have constants, variables and exponent. He failed to complete it in his lifetime because of the complexity and number of intricate parts required. His model was eventually successfully created in the 90s using his designs and it worked.
    • But while he was coming up with this he also conceived of a better and general purpose computing device that wasn’t limited to polynomial calculations → the Analytical Engine.
    • It could run operations in sequence and had memory and a primitive printer. It was way ahead of its time and was never completed.
    • Ada #Lovelace wrote hypothetical programs for the Analytical Engine, hence she is considered the world’s first computer programmer.
  • At this point then, computing was limited to scientific and engineering disciplines but in 1890, the US govt needed a computer in order to comply with the constitutional stipulation to have a census every ten years. This was getting increasingly difficult with the growing population - it would take more than 13 years to complete. This led to punch cards designed by Herman Hollereth. From this IBM was born
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Delay_line_memory.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Delay_line_memory.html deleted file mode 100644 index 1cb37f1..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Delay_line_memory.html +++ /dev/null @@ -1,50 +0,0 @@ -Delay line memory - My Zettelkasten - - - - -

Delay line memory

  • First described in the First Draft by #vonNeumann based on work by Eckert and Mauchley.

  • Information is stored as acoustic waves travelling through a medium, typically mercury. As sound travels more slowly than electric charge (light), if electric signals are converted to sound, the delay time involved can be used as a type of store.

  • It worked as follows:

    • Imagine we have an 8-bit number. The number is input as a sequence of pulses where a pulse is 1 and the absence of a pulse is 0.
    • The pulses are converted into sound waves (using a transducer, as with a speaker) and sent through a mercury-filled tube.
    • The length of the tube is calculated so that it takes exactly the time of one machine cycle for a pulse to travel from one end to the other
    • At the other end of the tube, another transducer converts the sound waves back to electrical pulses
    • This operates in a loop: the pulses go back into the input end of the tube and the cycle runs again.

To read the data, the computer would “listen” to the pulses coming out of the receiving end. To write new data, the computer would inject new pulses at the precise moment when it wants to change a ‘0’ to a ‘1’ or vice versa.

For an 8-bit number there would be 8 pulses for each bit and it would be necessary to keep track of 8 specific positions in the delay line where each bit would be stored.

The limitations were timing - difficult to keep track of each precise bit and when it would arrive at the output. Also it was sequential rather than random access. Not every bit could be accessed at once, you had to wait for its time slot to come around to access it.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Delete_a_branch.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Delete_a_branch.html deleted file mode 100644 index 8713513..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Delete_a_branch.html +++ /dev/null @@ -1,50 +0,0 @@ -Delete a branch - My Zettelkasten - - - - -

Delete a branch

Locally

git branch -d <local_branch_name>

Remote

git push origin --delete <remote_branch_name>
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Delete_records_in_an_SQL_table.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Delete_records_in_an_SQL_table.html deleted file mode 100644 index ad39eda..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Delete_records_in_an_SQL_table.html +++ /dev/null @@ -1,50 +0,0 @@ -Deleting data in SQL - My Zettelkasten - - - - -

Deleting data in SQL

Deleting records

We use DELETE to delete existing records in a table. Once this is applied, the records are permanently deleted.

To delete all records whilst maintaining the table:

DELETE FROM sales

We can also use TRUNCATE to achieve this. It is faster but it doesn’t keep a log of each deletion:

TRUNCATE TABLE sales

To delete a specifc entry by field:

DELETE FROM sales WHERE sale_id = 1;

Deleting tables

We use DROP to remove an entire table. This will delete the table definition, and all the data, indexes, triggers, constraints and permission specifications for that table.

DROP TABLE sales
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Deleting_Mongo_documents.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Deleting_Mongo_documents.html deleted file mode 100644 index 2a24ce7..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Deleting_Mongo_documents.html +++ /dev/null @@ -1,53 +0,0 @@ -MongoDB: deleting a document from a collection - My Zettelkasten - - - - -

MongoDB: deleting a document from a collection

async function deleteCourse(id) {
-  const result = await Course.deleteOne({ id: id });
-  console.log(result);
-}

Use findByIdAndRemove([id]) if you want to return the value that is deleted.

If we were to pass a query object that matches multiple documents in the database to deleteOne it would only delete the first document returned. To delete all use deleteMany.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Dependency_injection.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Dependency_injection.html deleted file mode 100644 index a9683fd..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Dependency_injection.html +++ /dev/null @@ -1,72 +0,0 @@ -Dependency injection - My Zettelkasten - - - - -

Dependency injection

Dependency injection is an object-oriented design pattern that allows for the decoupling of dependencies between objects making code more maintainable, testable and modular.

The basic idea is to resist having any class (C) depend on the specific implementation details of any other class to which it sustains a dependency (D). If we can abstract the implementation of D, this makes it easier to swap-out and change C’s dependencies later on without having to re-write C as a result of changes to D.

This is where interfaces become very helpful because they are schematic representations of the main methods in a given class (basically their names, params and return value). As long as this is kept consistent in D when changes are made, you avoid conflicts when changes or refactorings are made to D.

Example

In the example to follow we will have two classes:

  • ConsoleLogger
    • This will simply log something and be a dependency for the class below
  • UserService
    • This will depend on ConsoleLogger

First we define an interface for the dependency:

interface ILogger {
-  log(message: string): void;
-}

So this is a class that has a single method log which receives a message string as an argument and returns a side-effect.

Now we’ll implement this class:

class ConsoleLogger implements ILogger {
-  log(message: string): void {
-    console.log(message);
-  }
-}

Now we create a class that depends on it:

class UserService {
-  private logger: ILogger;
-
-  constructor(logger: ILogger) {
-    this.logger = logger;
-  }
-
-  createUser(username: string): void {
-    // ... (some logic to create a user)
-    this.logger.log(`User created: ${username}`);
-  }
-}

We can see that the constructor references the Logger interface. Thus we inject the dependency when instantiating UserService:

// First implement our earlier class that matches the `Logger` in its shape:
-const logger: ILogger = new ConsoleLogger();
-
-// Then pass it as a dependency:
-const userService: UserService = new UserService(logger);
-userService.createUser("John Doe");
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Devices.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Devices.html deleted file mode 100644 index 5b6890a..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Devices.html +++ /dev/null @@ -1,62 +0,0 @@ -Devices - My Zettelkasten - - - - -

Devices

Devices are hardware that require access to the CPU in order to function. Devices can either be external and plugged-in or internal to the motherboard. The most common type of device that you will work with are Disks.

Devices are files but they have some different capabilities than ordinaryq files. There are two types: block and stream. Device files reside in the /dev/ directory.

Some of the most important device files are:

  • hda : a harddisk on a port
  • sda : a harddisk on another port

Device files are an interface to a driver which accesses the hardware. A driver is therefore part of the Linux kernel.

So when you see sda listed for example, this isn’t the harddisk itself, it is a file that communicates with a driver that controls how the kernel can interact with it. This is why when you add a new piece of hardware (such as a mouse for example) you have to install drivers (typically provided by the manufacturer) so that your kernel is able to interact with it and provide it with access to the CPU.

Listing devices

The following ls within the /dev/ directory shows my main harddrive partitions:

brw-rw----   1 root   disk   259,     1 Jun  4 11:00 nvme0n1p1
-brw-rw----   1 root   disk   259,     2 Jun  4 11:00 nvme0n1p2
-brw-rw----   1 root   disk   259,     3 Jun  4 11:00 nvme0n1p3

Since device files are files we can interact with them using standard file programs like ls and cat.

The mode is different from ordinary files. Each device file is prepended with b, p, c, s before the standard permissions. These stand for the major types of devices: block, character, pipe and socket.

-
block
-
Block devices transfer data as large fixed-size blocks. These are the most common device type and include harddrives and filesystems. As the data can be split up into discrete blocks of data, this facilitates quick random access from the kernel.
-
character
-
Character devices transfer data one character at a time.The data is not in discrete chunks, it is a continuous stream of characters. An example of a stream device file is a printer however many character devices (such as `/dev/null`) are not physically connected to the machine.
-
pipe
-
Pipe devices allow two or more processes to communicate with each other. They work in the same way as character devices (transferring data as a stream) but instead of the output being sent to a device, it is sent to another process.
-
socket
-
The same as pipe devices, facilitating communication between processes however they can communicate with many processes at once, not just a single process.
-
-

/dev/null

/dev/null is a virtual device: it doesn’t actually exist as a piece of hardware on the system. It can be useful when bash scripting as a place to direct output that you don’t care about, for example errors or verbose program read-outs.

I like to think of /dev/null as being like earth in a circuit. It’s an outlet to safely dispose of things you are not interested in.

! Make notes on this. Base on : https://linuxhint.com/what_is_dev_null/

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Dictionaries_in_Python.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Dictionaries_in_Python.html deleted file mode 100644 index 5c14f48..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Dictionaries_in_Python.html +++ /dev/null @@ -1,116 +0,0 @@ -Dictionaries in Python - My Zettelkasten - - - - -

Dictionaries in Python

Dictionaries are basically the Python equivalent of objects in JS.

Dictionaries:

  • Are ordered (in contrast to JS)
  • Are mutable
  • Are indexed by a key which references a value
  • Can be increased/decreased in length by adding/removing new members.

Basic usage

Dictionaries are declared with {...}:

cities = {
-  'Wales': 'Cardiff',
-  'England': 'London',
-  'Scotland': 'Edinburgh',
-  'Northern Ireland': 'Belfast',
-  'Ireland': 'Dublin'
-}
-
-print(type(citites))
-# <class 'dict'>

Accessing entries

print(cities['Wales'])
-# Cardiff
-
-print(cities.get('Ireland'))
-# Dublin
-
-print(cities.values())
-# ['Cardiff', 'London', 'Edinburgh', 'Belfast', 'Dublin']
-
-print(cities.keys())
-# ['Wales', 'England', 'Scotland', 'Northern Ireland', 'Ireland']
-
-print(cities.items())
-# [('Wales', 'Cardiff'), ('England', 'London'), ('Scotland', 'Edinburgh'), ('Northern Ireland', 'Belfast'), ('Ireland', 'Dublin')]

Predicates

print('Wales' in cities)
-# True
-
-print('France' not in cities)
-# True

Looping

for country in cities:
-    print(country, end=', ')
-    print(cities[country])
-
-"""
-Wales, Cardiff
-England, London
-Scotland, Edinburgh
-Northern Ireland, Belfast
-Ireland, Dublin
-"""
-
-for e in country.values():
-    print(e)

Updating values

cities['Wales'] = 'Swansea'
-print(cities)

Removing values

# Remove last item
-cities.popitem()
-print(cities)
-# {'Wales': 'Cardiff', 'England': 'London', 'Scotland': 'Edinburgh', 'Northern Ireland': 'Belfast'}
-
-# Remove specific entry by key
-
-cities.pop('Northern Ireland')
-print(cities)
-# {'Wales': 'Cardiff', 'England': 'London', 'Scotland': 'Edinburgh'}
-
-del cities['Scotland']
-print(cities)
-{'Wales': 'Cardiff', 'England': 'London'}

Containers as values

seasons = {
-'Spring': ('Mar', 'Apr', 'May'),
-'Summer': ('June', 'July', 'August'),
-'Autumn': ('September', 'October', 'November'),
-'Winter': ('December', 'January', 'February')}
-
-print(seasons['Spring'])
-print(seasons['Spring'][1])
-
-"""
-('Mar', 'Apr', 'May')
-Apr
-"""
-
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Difference_between_remote_origin_and_head.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Difference_between_remote_origin_and_head.html deleted file mode 100644 index cd7ae93..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Difference_between_remote_origin_and_head.html +++ /dev/null @@ -1,65 +0,0 @@ -Difference between remote, origin, HEAD - My Zettelkasten - - - - -

Difference between remote, origin, HEAD

-
remote -
-
-A remote is a git repository that is hosted on a server which you can interact with over a network. You can have more than one remote for a local repository. -
-
-origin -
-
-The default name given to the remote repository that was cloned. When you clone a repository, git automatically creates a default remote called `origin`. This is essentially an alias for the URL of this repository. -
-
HEAD
-
A reference to the most recent commit on the currently checked-out branch. It points to the tip of the branch which is the commit that was most recently added. If you have changes in your working directory that have yet to be committed, the HEAD will be behind them. Once you commit them, the HEAD will update to reflect the new commit.
-
-
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Disjunction_Elimination.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Disjunction_Elimination.html deleted file mode 100644 index 1c1b622..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Disjunction_Elimination.html +++ /dev/null @@ -1,50 +0,0 @@ -Disjunction Elimination - My Zettelkasten - - - - -

Disjunction Elimination

This rule is sometimes also referred to as Constructive Dilemma. This can be a bit tricky to understand because the goal is to derive or introduce a new proposition separate from the disjunction you start out with. This may be disjunction, a single proposition or a proposition containing any other logical connective. You do this by constructing two sub-proofs, one for each of the disjuncts comprising the disjunction you start out with. If you can derive your target proposition as the conclusion of each subproof then you may invoke the conclusion in the main proof and take it to be derived.

Here is an example where Disjunction Elimination is used to derive a new disjunction.

Here are two further examples that use Disjunction Elimination to derive singular propositions

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Disjunction_Introduction.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Disjunction_Introduction.html deleted file mode 100644 index 19bbc7d..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Disjunction_Introduction.html +++ /dev/null @@ -1,50 +0,0 @@ -Disjunction Introduction - My Zettelkasten - - - - -

Disjunction Introduction

This rule can seem a little odd: like we are randomly introducing an additional proposition without giving any justification. However this is just a consequence of the fact if \(P\) is true, so is \(P \lor Q\) since disjunction is not the same as conjunction: only one disjunct needs to be true for the compound disjunction to be true. This is represented in the context of truth-trees by the fact that truth can pass up via either branch of a disjunction pattern. This rule is sometimes also referred to (confusingly) as Addition.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Disk_info.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Disk_info.html deleted file mode 100644 index 3569bb3..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Disk_info.html +++ /dev/null @@ -1,50 +0,0 @@ -Disk info routines - My Zettelkasten - - - - -

Disk info routines

Current disk capacity

df -h

Disk last modified

stat [disk_name]
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Distributivity.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Distributivity.html deleted file mode 100644 index 1d2ae07..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Distributivity.html +++ /dev/null @@ -1,52 +0,0 @@ -The Distributive Property of Multiplication - My Zettelkasten - - - - -

The Distributive Property of Multiplication

Let \(a\), \(b\) represent members of \(\mathbb{W}\) or \(\mathbb{Z}\) then:

$$ a \cdot (b + c) = a \cdot b + a \cdot c $$

Demonstration

When faced with \(4(2\cdot3)\) we may proceed with the official order of operations in algebra, namely:

4 x (2 + 3) = 4 x (5)
-= 20

In other words we find the sum of the values in parentheses and then multiply this by the value outside of the brackets.

When we use distributive property we distribute each value in the parentheses against the value outside of the parentheses:

4 x (2 + 3) = (4 x 2) + (4 x 3)
-8 + 12 = 20
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Dividing_fractions.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Dividing_fractions.html deleted file mode 100644 index f55797e..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Dividing_fractions.html +++ /dev/null @@ -1,59 +0,0 @@ -Dividing fractions - My Zettelkasten - - - - -

Dividing fractions

Suppose you have the following shape:

draw.io-Page-9.drawio 1.png

One part is shaded. This represents one-eighth of the original shape.

one-eighth-a.png

Now imagine there are four instances of the shape and one-eighth remains shaded. How man one-eighths are there in four?

draw.io-Page-9.drawio 2.png

The shaded proportion represents \(\frac{1}{8}\) of the shape. Imagine four of these shapes, how many eighths are there?

This is a division statement: to find how many one-eighths there are we would calculate:

$$ -4 \div \frac{1}{8} -$$

But actually it makes more sense to think of this as a multiplication. There are four shapes of eight parts meaning there are \(4 \cdot 8\) parts in total, 32. One of these parts is shaded making it equal to \(\frac{1}{32}\).

From this we realise that when we divide fractions by an amount, we can express the calculation in terms of multiplication and arrive at the correct answer:

$$ -4 \div \frac{1}{8} = 4 \cdot 8 = 32 -$$

Note that we omit the numerator but that technically the answer would be \(\frac{1}{32}\).

Formal specification of how to divide fractions

We combine the foregoing (that it is easier to divide by fractional amounts using multiplication) with the concept of a reciprocol to arrive at a definitive method for dividing two fractions. It boils down to: invert and multiply:

If \(\frac{a}{b}\) and \(\frac{c}{d}\) are fractions then: $$\frac{a}{b} \div \frac{c}{d} = \frac{a}{b} \cdot \frac{d}{c}$$

We invert the divisor (the second factor) and change the operator from division to multiplication.

Demonstration

Divide \(\frac{1}{2}\) by \(\frac{3}{5}\)

$$ -\begin{split} -\frac{1}{2} \div \frac{3}{5} = \frac{1}{2} \cdot \frac{5}{3} \\ -= \frac{5}{5} -\end{split} -$$

Divide \(\frac{-6}{x}\) by \(\frac{-12}{x^2}\)

$$ \begin{split} \frac{-6}{x} \div \frac{12}{x^2} = \frac{-6}{x} \cdot \frac{x^2}{-12} \ = \frac{(\cancel{3} \cdot \cancel{2} )}{\cancel{x}} \cdot \frac{(\cancel{x} \cdot \cancel{x} )}{\cancel{3} \cdot \cancel{2} \cdot 2} \ = \frac{x}{2}

\end{split}

$$

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Docker_CLI.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Docker_CLI.html deleted file mode 100644 index 4eee281..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Docker_CLI.html +++ /dev/null @@ -1,62 +0,0 @@ -Docker CLI - My Zettelkasten - - - - -

Docker CLI

# List images
-docker image ls
-
-# List container
-docker container ls
-
-# Remove container
-docker rm container-name
-
-# Remove image
-
-docker rmi image_name:version
-
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Docker_Compose.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Docker_Compose.html deleted file mode 100644 index f686db3..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Docker_Compose.html +++ /dev/null @@ -1,79 +0,0 @@ -Docker Compose - My Zettelkasten - - - - -

Docker Compose

  • Docker Compose (DC) is a tool for defining and running multi-container applications. A typical example would be combining a FE with a BE implementation and database as three related but distinct containers.

  • DC is a prime example of infrastructure as code.

  • A YAML file defines all the required configuration and all services can be started with a single command.

  • It provides a consistent configuration accross environments: development, test, production

Composition

Three step process:

  1. Define your application image in a Dockerfile
  2. Define the services in docker-compose.yaml (backend services, networks, volumes)
  3. Start the entire application with docker compose up

docker-compose.yml

  • Must always begin with version
  • Must have services map
    • This defines the different components that comprise your application
    • Services can be either an image reference (the one that generates the container you want to include) or a build context

Look at the following example. It runs a Python Flask frontend connected to a Redis key-value pair database for backend.

# docker-compose.yml
-
-version: "3.9"
-services:
-  web:
-    build: . # here we are using the current directory as the build context
-    image: myapp:1.0
-    ports:
-      - "5050:5000"
-    depends_on:
-      - redis
-  redis:
-    image: "redis:alpine"

depends_on is important - it means this container must be running first before any others. If this is a DB, it means the data is accessible before the frontend request start.

Main commands

# start the composition:
-docker compose up -d
-
-# start a specific service within the composition:
-docker compose up -d web
-docker compose up -d redis
-
-# view logs for a specific service
-docker compose logs --follow web
-
-# view processes by activity
-docker compose top

Environment variables

You can define them in the compose file or name them and leave them blank. If you do this, Docker will look in the host environment for the variable which is really handy:

...
-services:
-  redis:
-    ...
-    environment:
-      ENV1: 'some value'
-      ENV2:

See also

NodeJS and MySQL Docker backend

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Docker_architecture.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Docker_architecture.html deleted file mode 100644 index 2b7ea7d..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Docker_architecture.html +++ /dev/null @@ -1,51 +0,0 @@ -Docker architecture - My Zettelkasten - - - - -

Docker architecture

Overview

  • The Docker Client is a thin API for making REST API to the Docker Server. Any CLI command beginning docker... is an API request to the server.
  • The internal process name for the server is dockerd.
  • On docker run..., dockerd calls containerd. This process starts the container runtimes and configures container-level storage and networking.
  • This then spawns container-shim procecesses which takes any output from you container and puts it in a logfile. (A redirection of stdout and stderr) One shim is spawned for each container.
  • The shim then launches a container runtime called runc. The runc performs all the complex configuration of cgroups and namespaces to create the container environment.
  • containerd is purely a bootstrapper. Once it has fulfilled its function by initiating runc, the Docker instance is up and running and the kernel takes it from there. It is like a launch scaffold that can be discarded.

If you are running Docker desktop on Mac or Windows, Docker creates a Linux virtual machine, since it cannot run natively on Windows or Mac. In these cases the the Docker Server runs inside this VM adding an additional layer of abstraction.

Docker server also creates an internal virtual network and assigns IP addresses to the containers. (This can be used to get containers to communicate to each other over TCP/IP, since they are isolated by default.)

Images

Containers are created from images stored in a registry (either the public Docker Hub or privately). containerd uses the image to tell runc how to construct and build the image.

docker run [image_name]

The images you have pulled from the registry are stored in a local registry on your machine.

When you run docker run, Docker will look first for the image in your local registry. If it cannot find it there, it will attempt to pull it from the remote registry.

This assumes you are using a third-party image. You can also create your own images by writing a Dockerfile:

docker build [docker_file]
-docker run [resulting_image]
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Docker_compose_and_Dockerfile_difference.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Docker_compose_and_Dockerfile_difference.html deleted file mode 100644 index fdceb7a..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Docker_compose_and_Dockerfile_difference.html +++ /dev/null @@ -1,63 +0,0 @@ -Docker compose and Dockerfile difference - My Zettelkasten - - - - -

Docker compose and Dockerfile difference

Key Differences

  • Scope: A Dockerfile is for building a single Docker image, while docker-compose.yml is for orchestrating multiple containers (that might be built from Dockerfiles) to work together as a unified application.
  • Use Case: A Dockerfile is necessary when you need to create a custom image. In contrast, docker-compose.yml is used when you want to deploy and manage an application that consists of multiple containers.
  • Command: You build an image from a Dockerfile using docker build. You start the application defined by docker-compose.yml using docker-compose up.

Dockerfile

  • Purpose: A Dockerfile is a text document that contains all the commands a user could call on the command line to assemble an image. It automates the process of creating Docker images by specifying a sequence of steps and configurations such as setting environment variables, installing software, and copying files from the local directory into the image.

  • Functionality: It is essentially a blueprint for building Docker images. You define the base image, software packages, scripts, files, environment variables, and other components you need in your Docker image.

  • Usage: You use a Dockerfile when you need to create a custom Docker image based on your application’s specific dependencies and runtime environment. After defining your Dockerfile, you use the docker build command to create an image.

    Example structure of a Dockerfile:

    FROM python:3.8
    -WORKDIR /app
    -COPY . /app
    -RUN pip install -r requirements.txt
    -CMD ["python", "./my_script.py"]

docker-compose.yml

  • Purpose: A docker-compose.yml file is used to define and run multi-container Docker applications. With a single command, you can configure all of your application’s services, networks, and volumes in this YAML file and bring everything up or down.

  • Functionality: It simplifies the deployment and management of application components that are meant to run in separate containers while still needing to communicate or work together. For example, a web application might consist of a web server, a database, and a caching system, each running in its container.

  • Usage: docker-compose is used for defining and running complex applications with Docker. Instead of using lengthy docker run commands with many flags, you write a docker-compose.yml file and use docker-compose up to start the application.

    Example structure of a docker-compose.yml file:

    version: "3"
    -services:
    -  web:
    -    build: .
    -    ports:
    -      - "5000:5000"
    -  db:
    -    image: postgres
    -    volumes:
    -      - ./data:/var/lib/postgresql/data
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Docker_containers.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Docker_containers.html deleted file mode 100644 index 7c42b74..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Docker_containers.html +++ /dev/null @@ -1,69 +0,0 @@ -Docker containers - My Zettelkasten - - - - -

Docker containers

Launch a container

We launch a container by running, e.g

docker run hello-world

Docker looks for the hello-world image in order to start the container. If it cannot find it, it will fetch the image from DockerHub.

(docker run assumes you are saying “run image in container” but you can specify other Docker objects such as networks.)

The docker run command is actually a composite of the following two commands:

docker create --name [my_container_name] hello-world
-docker start [my_container]

Here is an applied example:

docker run --name my-container debian /bin/echo "Hello, world"

This creates and runs a container from the Debian image and executes /bin/echo inside of it. Once you have run the above line, if the process is successful it will exit. The container will stop running but it will remain in memory. Nothing will be output (no “Hello, world”), because when you run it, you are outside of the container.

Launch a container as a daemon

You can also run a container as a daemon. In this mode, the container will run in the background and detach from the console. For example:

docker run -d debian /bin/sh -c /bin/sh -c "while true; do echo 'Hello!'; sleep 1; done"

Inside the container, this will echo “Hello!” every second in an infinite loop whilst the daemon is active.

The above command will not actually output anything. Instead it wil ouput the container ID, e.g:

2749d796cbd64e9cf57307329e792587c39d8244f2377e62d78f3f3f77eecdb4

You can use this to access the log for the container. When you do so, you will then see the output:

docker log 2749
-hello
-hello
-hello
-...

(We could also use the container name to reference the container, if we launched it with the --name param.)

Stopping a container

docker stop 2749

There will be a delay because it shuts down gracefully. It sends a SIGINT to the process in the container with PID 1 (i.e the root or parent process for the container).

stop will keep the container in memory. This means you can still refer bak to the logs and that it can be restarted.

Instead of stop, if you were to use:

docker rm 2749

The container will be stopped and deleted. The logs are deleted and the container cannot be recovered.

We can also tell Docker to immediately remove a container after it exits:

docker run --rm [image]

Interacting with containers

In the examples so far the container is a closed box. You don’t have a terminal through which you can interact with the container as you would with an OS. You can only start the container and view its activities by accessing the logs.

For images that have an OS we can use -i -t to launch a terminal in interactive mode.

docker run -i -t debian /bin/bash
-root@0022da12f2f2:/# ls
-bin  boot  dev	etc  home  lib	media  mnt  opt  proc  root  run  sbin	srv  sys  tmp  usr  var
-root@0022da12f2f2:/# whoami
-root
-root@0022da12f2f2:/# ls usr/
-bin  games  include  lib  libexec  local  sbin	share  src

Note that it defaults to the root user.

Containers are lightweight and should only contain the minium environment needed to run an application. For this reason OSs that are included in an image are often very stripped-back and many programs and processes will not be there by default. (Although you could install a package manager and install the commands you need.)

The previous command launches the container and enters into it with a terminal. If a container is already running, you can enter into it in terminal mode with exec:

docker exec -i -t my_container bash

If a container is running in detached mode we can attach to the main process with docker attach

docker attach my_container

Container lifecycle

All containers have a lifecycle represented by five distinct states. Each state has an associated command:

  • created
    • docker create, docker run
  • running
  • paused
    • docker pause, docker unpause
  • stopped
    • docker stop, docker kill
  • removed
    • docker rm

Main container commands

docker create # create container from image
-docker run # create and start container from image
-docker run --name # add custom name for container
-docker ps # list currently active containers
-docker ps -a # list all containers (inactive and active)
-docker logs # display a container log
-docker stop # stop a running container
-docker start # starts a stopped (exited) container
-docker rm # remove a stopped (exited) container

Container troubleshooting

Lots of diagnostic output:

docker inspect container_name

List processes (from outside):

docker top container_name

View logs

docker logs container_name
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Docker_general_overview.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Docker_general_overview.html deleted file mode 100644 index 7acd683..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Docker_general_overview.html +++ /dev/null @@ -1,50 +0,0 @@ -Docker: general overview - My Zettelkasten - - - - -

Docker: general overview

Docker is an ecosystem of tools for creating, running and transporting containers.

The main product of the Docker company is Docker Desktop - a UI for running containers however the actual docker software is free and open source.

Docker standardised the use of containers set up the open-source Open Container Initiative which is a convention agreed upon by the major tech companies. It codifies the following:

  • Docker runtime specification
  • Docker image specification
  • Docker registry specification

Main components

  • Docker Engine
    • The core component
    • Exposes the Docker API and manages the entire workflow around creating, running and deploying containers
  • Docker Client
    • The Docker CLI
    • The primary means of interacting with the Docker Engine
    • Provides commands for managing images, containers and other Docker objects
  • Docker Compose
    • A tool for defining and running multi-container applications
    • Define the configuration for all of the containers that make up the application in a single YAML file
  • Docker Images
    • See below
  • Docker Containers
    • See below
  • Docker Registry
    • A centralised location where Docker iamges can be stored and shared
    • DockerHub is the registry provided by Docker
    • Organisations can set up their own private registries

Docker images

An image is a blueprint that contains the instructions to build a container. It’s an immutable snapshot of the file system and configuration of an application. Images can be easily shared between developers.

They are runnable packages that contain everything needed to run an application including the binaries, libraries, resources and other dependencies.

It does not contain an operating sytem but may include a particular Linux distribution.

Docker containers

A container is a runnign instance of a Docker image. Multiple, identical containers can be launched from the same, single image.

Docker architectural overview

See Docker architecture.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Docker_images.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Docker_images.html deleted file mode 100644 index 9dd2502..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Docker_images.html +++ /dev/null @@ -1,57 +0,0 @@ -Docker images - My Zettelkasten - - - - -

Docker images

Docker needs an image to run a container. Images are stored in the local registry. If it can’t find it, it will try and pull it from Docker Hub.

View your local images

docker images
REPOSITORY                     TAG       IMAGE ID       CREATED         SIZE
-debian                         latest    e6d9c9c3e100   12 days ago     118MB
-ubuntu                         latest    bab8ce5c00ca   6 weeks ago     69.2MB
-cda/mysql-5.7                  latest    312ce2a6cea5   3 months ago    495MB
-cda/node-16                    latest    b26e54c8fa11   3 months ago    1.44GB
-bitnami/minio                  latest    ef6d14df2158   3 months ago    229MB
-opensearchproject/opensearch   1.3.7     0f8ef57c3629   4 months ago    831MB
-hello-world                    latest    46331d942d63   13 months ago   9.14kB

Repository, registry, tag

When you specify the name of an image, you are referring to the image’s repository. The registry is the list of repositories available on the Docker Hub. Each repository has a tag, indicating the current production branch.

For example:

docker run -it ubuntu:18:04 /bin/bash
  • ubuntu is the image repository
  • 18.04 is the image tag

The Image ID distinguishes the image globally and is not local to you.

To get detailed info on an image:

docker image inspect debian

“Dangling” images

A “dangling” image is an unused image - one that is not associated with a container. Re move dangling images with

docker image prune

Anatomy of a Docker image: layering

The process of constructing a Docker image involves creating a series of intermediate layers, each representing a change or addition to the filesystem. These layers are stacked on top of one another, forming the final image. This approach is called layering.

Layering in Docker images offers several benefits:

  1. Reusability: Common layers can be shared between multiple images, reducing disk space usage and build time. For example, if multiple images use the same base operating system, they can all share the same base layer.

  2. Caching: During the build process, Docker caches layers that have already been built. If a layer hasn’t changed, Docker will reuse it in subsequent builds, speeding up the build process.

  3. Incremental updates: When updating an image, only the layers that have changed need to be updated and redistributed. This reduces the size of updates and makes the process more efficient.

Each instruction in the Dockerfile creates a new layer in the image. Some common instructions include:

  • FROM: Specifies the base image to start with (e.g., an operating system or an existing image).

  • RUN: Executes a command, often used for installing packages or configuring the system.

  • COPY: Copies files or directories from the host machine to the image.

  • ADD: Similar to COPY but can also handle URLs and automatic extraction of archives.

  • ENV: Sets environment variables that will be available inside the container.

  • CMD: Specifies the default command to run when a container is started from the image.

  • ENTRYPOINT : Similar to CMD, but allows the container to be run as an executable, with additional arguments.

When building an image, Docker starts with the base image specified in the FROM instruction and applies each subsequent instruction, creating a new layer for each step. The final result is a layered image that contains the application and its dependencies, ready to be run as a container.

The read-write layer

The final layer at the “top” of the image is a thin read-write layer. In contrast to the intermediate layers it can execute read-write functionality and is not read-only.

Files in the intermediate layer cannot be modified, only the read-write layer can be modified. Files are copied over from intermediate layers when requested by the read-write layer, rather being modified themselves.

Tip for writing build files:

Things that change less should be higher up (earlier). Things that change more should be twoardds the end. This allows for better layer caching. Particularly bear this in mind with the commands: RUN, COPY, ADD.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Docker_storage.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Docker_storage.html deleted file mode 100644 index 1d9b087..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Docker_storage.html +++ /dev/null @@ -1,53 +0,0 @@ -Docker storage - My Zettelkasten - - - - -

Docker storage

The following problems related to storage face containerized environments:

  • Container storage is ephemeral. When the container is removed the read-write layer is removed. How can we persist data?

  • Container storage is isolated: containers cannot access each other’s file systems. If they need to share data, this could be a problem

Docker volumes

Docker volumes are the solution to this. Volumes:

  • store data on the host file system (i.e. outside the container)
  • persist data beyond the lifecycle of the container

A Docker volume is a logical volume that exists outside the container file system. It maps to a directory on the host and this location is managed by Docker - not much control over this.

Can be named or anonymous. Anonymous vols are created by Docker as needed. Named come from the user.

Volumes can be named or anonymous. Anonymous volumes are created by Docker as needed. Named volumes are named by the user. In both cases Docker decides where to create the volume.

Creating a volume

docker run -d -rm -v /usr/share/nginx/html nginx:latest

The -v flag indicates volume. The file reference is the mount point within the container. This is how the persistent storage it will appear. The actual volume exists outside of the container anonymously in a place decided by Docker.

To create a named volume you first have to create:

docker volume create volume_name

Then you can designate it:

docker run -d -rm -v volume_name:/usr/share/nginx/html nginx:latest

The actual location is still hidden and decided by Docker.

As these are anonymous they will show ups as GUIDs in the volume viewer in Docker Desktop:

// Add: screenshot

Commands

docker volume ls
-docker volume rm
-docker volume inspect
-docker volume prune // remove all unused volumes

Inspect is only really informative if you are on Linux because it will show you the actual physical path. With Windows and Mac the referernce is to a virtual machine.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/DynamoDB_CLI_commands.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/DynamoDB_CLI_commands.html deleted file mode 100644 index 45af7e4..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/DynamoDB_CLI_commands.html +++ /dev/null @@ -1,63 +0,0 @@ -DynamoDB CLI commands - My Zettelkasten - - - - -

DynamoDB CLI commands

Connecting to a local (Docker)/prod (AWS) DynamoDB instance

In order to distinguish between local and production accounts you should keep seperate profiles for each (via .aws/config and .aws/credentials).

When connecting to a local DB use the local profile and the local URL. Without the --profile flag, AWS will default to the default profile which will typically be your credentials for accessing AWS on the remote.

It also sometimes required to add the endpoint-url when working locally:

--endpoint-url http://localhost:800
-
-> When using the commans below locally, assume `--endpoint-url` and `--profile`
-> have been appended
-

For example:

aws dynamodb list-tables \
---profile timetracking_dev \
---endpoint-url http://localhost:800

Delete a table

aws dynamodb delete-table \
---table-name TableName

Create table from JSON schema

aws dynamodb create-table \
---cli-input-json file://create-timeentries-table.json \
-

Describe the table

View the table schema:


-aws dynamodb describe-table \
---table-name TimeEntries

Scan the table

aws dynamodb scan \
---table-name TimeEntries \
---output table
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/DynamoDB_SDK_commands.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/DynamoDB_SDK_commands.html deleted file mode 100644 index f9c920f..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/DynamoDB_SDK_commands.html +++ /dev/null @@ -1,83 +0,0 @@ -DynamoDB SDK commands - My Zettelkasten - - - - -

DynamoDB SDK commands

The following commands are for using @aws-sdk/client-dynamodb (the JS SDK).

Create client

import DynamoDBClient from "@aws-sdk/client-dynamodb";
-
-const client = new DynamoDBClient({
-  region: "eu-west-2",
-  accessKeyId: process.env.ACCESS_KEY_ID,
-  secretAccessKey: process.env.ACCESS_KEY_ID,
-});

DynamoDB Document Client

The Document Client returns the data as a standard JSON document in the manner of a document-based NoSQL database. Without it, DynamoDB will return the data with type data which is unwieldy and hard to parse.

To transform into a document structure:

import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
-import { DynamoDBDocumentClient } from "@aws-sdk/lib-dynamodb";
-
-const client = new DynamoDBClient({
-  region: "eu-west-2",
-  accessKeyId: process.env.ACCESS_KEY_ID,
-  secretAccessKey: process.env.ACCESS_KEY_ID,
-});
-
-const dynamoDbDocumentClient = DynamoDBDocumentClient.from(client);

Query a table

Querying is the most performant and cost-effective method since it is an O(1) lookup against a partition key or secondary index.

import { DynamoDBDocumentClient, QueryCommand } from "@aws-sdk/lib-dynamodb";
-
-const params = {
-  TableName: "YourTableName",
-  KeyConditionExpression: "#pk = :pk",
-  ExpressionAttributeNames: { "#pk": "PrimaryKeyAttributeName" },
-  ExpressionAttributeValues: { ":pk": "PrimaryKeyValue" },
-};
-
-const dynamoDbDocumentClient = DynamoDBDocumentClient.from(client);
-const data = await dynamoDbDocumentClient.send(new QueryCommand(params));
-console.log(data);

Scan a table

Scanning is less performant (O(n)) and most expensive since it requires checking every item in the database.

import { DynamoDBDocumentClient, ScanCommand } from "@aws-sdk/lib-dynamodb";
-
-const params = {
-  TableName: "YourTableName",
-};
-
-const dynamoDbDocumentClient = DynamoDBDocumentClient.from(client);
-const data = await dynamoDbDocumentClient.send(new ScanCommand(params));
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/DynamoDB_data_structure.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/DynamoDB_data_structure.html deleted file mode 100644 index 67839f7..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/DynamoDB_data_structure.html +++ /dev/null @@ -1,102 +0,0 @@ -DynamoDB - My Zettelkasten - - - - -

DynamoDB

Data structure

Non-relational tables

DynamoDB is “NoSQL” because it does not support #SQL queries and is non-relational meaning there cannot be JOIN operations via foreign_keys

Primary key

Although the data is stored as a table, one of the attributes is a primary key and the rest of the attributes are effectively the “value” associated with it.

Because DynamoDB is schemaless, other than the primary key, neither the attributes or their data types need to be defined beforehand and each item can have its own distinct attributes.

Each item in the table is uniquely identifiable by its primary key.

There are two types of primary key available:

  • partition key: a simple primary key composed of one attribute only. Because the primary key is hash-mapped items can be retrieved very rapidly using the primary key. This would be the personId alone.

  • composite key: this comprises a partition key and a sort key both of which are attributes. In a table that has a partition key and a sort key, it’s possible for multiple items to have the same partition key value. However, those items must have different sort key values. You could then query by either key or both. For instance using the PersonId along with LastName

Secondary index

As well as the index provided by the primary key, you can set one or more secondary indices. A secondary index lets you query the data in the table using an alternate key.

A global secondary index is useful for querying data that needs to be accessed using non-primary key attributes. For example, if you have a Users table with UserID as the primary key but often need to fetch users by their Email, a GSI on Email would be appropriate.

There are also local secondary indices but I don’t understand the difference.

Real example

Below is a specification of the DynamoDB table I am using for my time-entries project:

{
-  "TableName": "TimeEntries",
-  "KeyAttributes": {
-    "PartitionKey": {
-      "AttributeName": "activity_start_end",
-      "AttributeType": "S"
-    }
-  },
-  "NonKeyAttributes": [
-    {
-      "AttributeName": "activity_type",
-      "AttributeType": "S"
-    },
-    {
-      "AttributeName": "start",
-      "AttributeType": "S"
-    },
-    {
-      "AttributeName": "end",
-      "AttributeType": "S"
-    },
-    {
-      "AttributeName": "duration",
-      "AttributeType": "N"
-    },
-    {
-      "AttributeName": "description",
-      "AttributeType": "S"
-    },
-    {
-      "AttributeName": "year",
-      "AttributeType": "S"
-    }
-  ],
-  "GlobalSecondaryIndexes": [
-    {
-      "IndexName": "YearIndex",
-      "KeyAttributes": {
-        "PartitionKey": {
-          "AttributeName": "year",
-          "AttributeType": "S"
-        },
-        "SortKey": {
-          "AttributeName": "start",
-          "AttributeType": "S"
-        }
-      },
-      "Projection": {
-        "ProjectionType": "ALL"
-      }
-    }
-  ]
-}

This defines the attribute activity_start_end as the primary key. This string (S) value is a concatenation of three attributes, which is a way of ensuring each entry for the attribute will be unique.

The NonKeyAttributes are all the other attributes in addition to the primary key. As mentioned these do not actually need to be defined when setting up the table but they are listed here for clarity.

I have also defined a GSI. This is derived from the Year attribute. This will group all the items by their Year, allowing me to query directly by year but also helping to chunk the entries which will make look-ups quicker and less expensive.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Effective_logging_in_Git.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Effective_logging_in_Git.html deleted file mode 100644 index eb08360..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Effective_logging_in_Git.html +++ /dev/null @@ -1,50 +0,0 @@ -Effective logging in Git - My Zettelkasten - - - - -

Effective logging in Git

Root commandVariantOutput
git logfilename.txtList the commits that changed the given file
git log --patchfilename.txtShow the diff changes for each commit for the given file
git log --patchnullShow the diff changes for each commit for all files
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Elastic_Compute_Cloud.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Elastic_Compute_Cloud.html deleted file mode 100644 index 3025851..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Elastic_Compute_Cloud.html +++ /dev/null @@ -1,50 +0,0 @@ -Elastic Compute Cloud (EC2) - My Zettelkasten - - - - -

Elastic Compute Cloud (EC2)

  • Cloud-based or virtual server (virtual machine), basically a hypervisor (compare zk/Docker_architecture)
  • It is virtual because you are not responsible for its physical implementation
  • Still needs considerable configuration compared to a serverless zk/Lambda_programming_model
  • Like lambdas has the benefit of easy scaling: you can add compute capacity on demand (elasticity)

The following needs to be considered:

  • Naming
  • Application and OS image (known as “Amazon Machine Image”):
    • Which OS you want to use (Linux distribution, Windows, etc)
    • Applications you want pre-installed
    • Block device mapping
  • Instance type an size (basically the type of processor and how powerful you want it to be)
  • An encrypted key-pair for login
  • Your network (typically managed via Amazon VPC (Virtual Private Cloud)) and network security
  • Storage: size and type (eg. GP3)
  • Location and latency

EC2 is more expensive copared to serverless options. Accordingly it is better to run smaller servers (in terms of processor and memory) at higher capacity than larger servers under-capacity.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Electromagnetism.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Electromagnetism.html deleted file mode 100644 index 8126655..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Electromagnetism.html +++ /dev/null @@ -1,51 +0,0 @@ -Electromagnetism - My Zettelkasten - - - - -

Electromagnetism

Electromagnetism is the physical interaction among electric charges, magnetic moments and the electromagnetic field.

For a long time electricity and magnetism were thought to be separate forces. In the 19th century Maxwell demonstrated that they were interrelated phenomena then Einstein proved with the Special Theory of Relativity that they are aspects of one unified phenomenon.

The core of the relationship is that a changing magnetic field produces an electric field and conversely, a changing electric field produces a magnetic field.

Electric charge

We know that charge is an innate property of all charged fundamental particles. If a particle is charged it has a positive or negative charge. The most common charged particles in the universe are negatively charged electrons or positively charged protons. When charged particles are moving, they are known as electric currents.

Magnetism

Magnetism is a physical property produced by the motion of electric charge, which of course, is the same thing as electric current

A magnet is a material or object that produces a magnetic field. This field is invisible but visible by its effects: pulling on other magnetic materials such as iron, steel, nickel, cobalt etc and attracting or repelling other magnets.

All magnets have two ends where their magnetic effects are strongest. These regions are called the poles of the magnet. Materials can be magnetic but they are not magnetized until another magnetic material has entered into their field. At this point, the attraction and repulsion behaviour can be observed.

This behaviour is a function of the magnetic force which is transmitted via the magnetic field.

Relation to electrons

Magnetism, understood as the effect of a magnetic field, arises from the properties of the electrons in an atom. We know that atoms ‘orbit’ the nucleus of the atom but as they circle the nucleus they also spin or rotate on their own axis.

As they spin they produce a magnetic dipole: the two poles noted above. We call this propensity of electrons the intrinsic magnetic moment of the electron. It is aggregates of these miniature magnetic behaviours that produce the overall magnetic property of the material.

In most materials, equal numbers of electrons spin in opposite directions. As a result, their magentic effects are cancelled out. However in strongly magnetic materials an overall majority of electrons spin in one particular direction. This breaks the equilibrium and produces the magnetic field.

If you have material A where the electrons all spin in one direction and material B where the electrons all spin in a direction opposite to A, then B will be attracted to A and you can observe the effects of the magnetic force in action.

Fields and forces

What is a force in physics?

At its most abstract, divorced from the specific types of force, a force is an influence that can change the motion of an object. It is an external agent capable of changing the velocity of a body with mass. A force has both a magnitude and a direction.

What is a field

A field is a property of space. It means that a physical quantity is assigned to every point in space. This quantity has a numerical value and may vary over time.

The electric field

There are different types of field. The electric field is an instance of a vector field. With vector fields there is more than one number for each point in space:

  • a magnitude: a size value, i.e. being larger or greater than something else
  • a direction

The value of the electric field at a point in space equals the force that would be exerted on a unit of charge at that position in space.

Every charged object sets up an electric field in the surrounding space. A second charge “feels” the presence of this field. The second charge is either attracted toward the initial charge or repelled from it, depending on the signs of the charges. Of course, since the second charge also has an electric field, the first charge feels its presence and is either attracted or repelled by the second charge too. The electric field from a charge is directed away from the charge when the charge is positive and toward the charge when it is negative.

The magnetic field

As already noted, the magnetic field is the field created by a magnetic material: a material where the spin of the electrons is in disequillibrium. As with the electric field, a magnetic field exerts an attraction or repulsion on other spinning electrons. This is the magnetic force; the force is transmitted by the field. Attraction occurs when the two sets of electrons spin in opposite directions to each other. Repulsion occurs when the two sets of electrons spin in the same direction.

Crucially the magnetic force influences only those charges that are already in motion.

The magnetic field and force is more complex than the electric field/force. Whereas the electric field and force point either towards or away from the charge, the magnetic field is different:

  • The magnetic field points perpendicular to its source
  • The magentic force points perpendicular to the magnentic field

This is illustrated below which shows the magnetic field operating at right angles to the flow of charge within a wire.

-

The electromagnetic field

Although we have described the electric and magnetic fields separately, they are in fact a single unified and inseparable field created by charged particles and particles with a magentic moment. In describing electricity and magnetism we have focusing on different attributes of the same phenomenon.

The electromagnetic field does not carry charge or magnetic moment, it carries energy and momentum. This energy and momentum can be transferred to charged particles and particles with magnetic moment.

Maxwell’s Equations

The equations express four laws that offer a complete account of the electromagnetic field. The equations integrate separate discoveries and laws identified by other scientists with a common mathematical representation. This is why they are not called ‘Maxwell’s Laws’ since he didn’t originate the laws, he unified them into a common expression. These collective laws capture everything we have discussed so far in relation to electric and magnetic fields.

  1. An electrically charged particle creates an electric field. (Gauss’ Law for Electricity)
  2. Magnetically charged particles do not exist. (Gauss’ Law for Magentism)
  3. A changing magnetic field creates an electric field. (Faraday’s Law of Induction)
  4. A changing electric field creates a magnetic field. (Ampere’s Law)

The electromagnetic force

Maxwell’s Equations describe how electromagnetic fields are generated and behave but they don’t specify how the fields interact with charged particles. An account of this is provided by Lorentz’s force law which specifies what we have already described above:

An electric field exerts a forward or backward force on a charged particle and a magnetic field exerts a sideways/perpendicular force on a moving charged particle.

Electromagnetic radiation / waves

Electromagnetic radiation consists in waves of the electromagnetic field propagating through space carrying electromagnetic radiant energy.

Electromagnetic waves consist of rapidly changing electric and magnetic fields. They are emitted any time an electrically charged particle accelerates. These waves are generally referred to as light. However, more accurately, ‘light’ refers to the types of electromagnetic wave that we can see. Electromagnetic waves form a spectrum based on their frequency and wavelength. For example, ‘radio waves’ are low-frequency / long wavelength electromagnetic waves and gamma rays are high-frequency / short wavelength waves:

The image below shows the propagation of an electromagnetic wave through space. We can identify the core components as follows

  • The vector of the magnetic field \(B\) propagates outwards along the \(z\) axis
  • The magenetic field is perpendicular to the vector of the electric field \(E\) which propagates upward along the \(y\) axis
  • The directionality of both waves is forward along the \(x\) axis

Using magnetism to generate electricity

Understand better:

  • How do EM waves relate to simple electrical circuits.
  • Link discussion here to discussion of Hertz

https://www.britannica.com/science/electromagnetism/Coulombs-law

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Electrons.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Electrons.html deleted file mode 100644 index 32370ff..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Electrons.html +++ /dev/null @@ -1,50 +0,0 @@ -Electrons - My Zettelkasten - - - - -

Electrons

Shells

Electrons orbit in concentric circuits around the nucleus of the atom. Each orbit is called a shell.

Each shell can accommodate a maximum number of electrons. The shells are designated by letters and filled in sequence moving out from the shell nearest to the nucleus.

The diagram below demonstrates shell naming conventions and the maximum number of electrons per shell.

Valence

The outer shell called the valence shell and the number of electrons it contains, the valence. This part of the atom is the most important from the point of view of electricity because it is from here that electrons can escape the atom and where electrons from other atoms may join.

The farther the valence shell is from the nucleus, the less attraction the nucleus has on each valence electron. Thus the potential for the atom to gain or lose elections increases if the valence shell is not full and is located far enough away from the nucleus.

Conductivity and insularity

The conductivity of a material is an expression of its capacity to channel electrical charge. Where electrical charge is the flow of free electrons from one atom to another. The insularity of a material is the opposite: its capacity to resist the flow of electrical charge.

Electrons in the valence shell can gain energy from external forces. If these electrons gain enough energy, they can leave the atom and become free electrons, moving randomly from atom to atom.

We call materials that contain a large number of free electrons conductors. In contrast insulators are atoms that stabilize themselves by absorbing valence electrons from other atoms to fill their valence shells, eliminating the free electrons.

The propensity for the electrons within a conductor to move about and jump between atoms, swapping charge, is not something that is only activated when a voltage is applied. In fact, the electrons are always doing this, even in a piece of inert copper. The difference is they are doing it randomly and in all kinds of directions. It is only when a voltage is applied that the motion and exchange of electrons is forced in one consistent direction.

Semiconductors

Semiconductive materials are midway between conductors and insulators: they are neither good conductors or insulators but can be altered to function in the manner of either.

Ionization

Ionization is the process of atoms gaining and losing electrons.

When an atom has an equal number of protons and electrons it is said to be electrically balanced.

A balanced atom that receives one or more extra electrons gives way to an overall negative charge. An atom in this state is a negative ion. Conversely if a balanced atom loses one or more electrons it becomes positively charged and is thus called a positive ion.

The process of ionization is a constitutive part of the flow of current but not the only part. We also must factor the force that triggers ionization and the resistance that impedes it.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Enums.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Enums.html deleted file mode 100644 index 710bafa..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Enums.html +++ /dev/null @@ -1,100 +0,0 @@ -Enums - My Zettelkasten - - - - -

Enums

In essence an enum in TypeScript is an incremented store of immutable variables. The only way I can understand them is just to think of them as a bag of constants.

Below is an example of an enum:

enum Continents {
-  NorthAmerica,
-  SouthAmerica,
-  Africa,
-  Asia,
-  Europe,
-  Antartica,
-  Australia,
-}
-
-// usage
-var region = Continents.Africa;

Here is an example of a string-based enum from the Studio codebase:

export enum HelpLinksEnum {
-  composerView = "composerView",
-  conditionalHelp = "conditionalHelp",
-  configView = "configView",
-  dashboard = "dashboard",
-  dataView = "dataView",
-  functionHelp = "functionHelp",
-  previewMode = "previewMode",
-}

Main properties

  • Auto-incrementation (numeric enums only):

    • Enums are auto-incrementing.
    • If we wanted to change the automatic sequence we could do something like the below and TS would automatically update the index to reflect our change
    enum NewProjectMenuItems {
    -    Row = 5
    -    Table // would automatically become `6` in the index
    -}
  • Enums are types

    • Enums are interpreted as types by TS. Consequently we can an enum as a type annotation. This can be particularly useful when typing function parameters. For example:
    enum UserResponse {
    -  No = 0,
    -  Yes = 1,
    -}
    -
    -function respond(recipient: string, message: UserResponse): void {
    -  // ...
    -}
  • Enums accept computed values

    • As is the case with objects generally, we are not limited to primitive data types when setting values on enums, we can also assign functions.
  • Reverse mapping

    • Reverse mapping is the ability to access a key via its value in addition to the more standard practice of accessing a value via its key.

    • Demonstration:

      enum PrintMedia {
      -  Newspaper = 1,
      -  Newsletter,
      -  Magazine,
      -  Book,
      -}
      -
      -PrintMedia.Magazine; // returns  3
      -PrintMedia["Magazine"]; // returns  3
      -PrintMedia[3]; // returns  Magazine
  • Useful in switch statements

    • Enums come in handy when you want to reduce the verbosity and repetition of a large switch statement.
    • The following is an example from the codebase:
      public projectMenuItemClickHandler(e: IUserProjectMenuItemClick): void {
      -    switch (e.menuItem) {
      -      case UserProjectMenuItems.Rename:
      -        e.item.rename = true;
      -        break;
      -      case UserProjectMenuItems.Export:
      -        this.exportProject(e.item);
      -        break;
      -      case UserProjectMenuItems.Clone:
      -        this.cloneProject(e.item);
      -        break;
      -    }
      -  }

Main benefits

More generally, by using enums we ensure that a given data structure is preserved unaltered and intact throughout the codebase which is very useful when multiple developers are working with the same classes and components. This creates a high-level canonical form of a given data structure that may be used in multiple contexts. This reduces the likelihood of different developers ‘reinventing the wheel’ and duplicating common data structures, helping to promote modularity and minimise technical debt.

Constraints and best practices

There are some important constraints that should be borne in mind when using enums:

  • Initialise string enums!
    • String enums must be initialised with a string or a reference to another enum. They cannot be tacitly defined as is the case with numeric enums
  • Don’t mix data types!
    • It is technically possible to construct an enum that contains both numbers and strings but this should be avoided as it can lead to unintended side-effects in the incrementation process. It also kind of undermines the purpose of enums. In this scenario, a custom type would probably be more appropriate.
  • Strings only as keys
    • In contrast to a Map or object an enum cannot have a numeric key. It must always be a string.
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Environmental_and_shell_variables.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Environmental_and_shell_variables.html deleted file mode 100644 index 44eacc5..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Environmental_and_shell_variables.html +++ /dev/null @@ -1,70 +0,0 @@ -Environmental and shell variables - My Zettelkasten - - - - -

Environmental and shell variables

Important!

To understand the difference between environmental and shell variables know that:

  • You can spawn child shells from the parent shell that is initiated when you first open the terminal. To do this just run bash or zsh .
  • This is a self-contained new instance of the shell. This means:
    • It will have access to environmental variables (since they belong to the parent / are global)
    • It will not have access to any shell variables that are defined in the parent.
  • How do you get back to the ‘upper’ parent shell? Type exit .
  • Note that:
    • Custom (user-created) shell variables do not pass down to spawned shell instances, nor do they pass up to the parent
    • Custom (user-created) environment variables do pass down to spawned shell instances but do not pass up to the parent. They are lost on exit .

Q. What methods are there for keeping track of, preserving, and jumping between spawned instances? Is this even possible or do they die on exit .

Questions, research

  1. If you create a variable manually I guess it won’t make it to any config file. How would you create a persistent var that is added to the .bashrc and thus which would be initialised on every session? Is this where the path comes in?
  2. What methods are there for keeping track of, preserving, and jumping between spawned instances? Is this even possible or do they die on exit ?

What is the shell environment and what are environment variables?

  • Every time that you interact with the shell you do so within an environment. This is the context within which you are working and it determines your access to resources and the behaviour that is permitted.

  • The environment is an area that the shell builds every time that it starts a session. It contains variables that define system properties.

  • Every time a Shell-sessions-e6dd743dec1d4fe3b1ee672c8f9731f6 spawns, a process takes place to gather and compile information that should be available to the shell process and its child processes. It obtains the data for these settings from a variety of different files and settings on the system.

  • The environment is represented by strings comprising key-value pairs. For example:

    KEY=value1:value2
    -KEY="value with spaces":"another value with spaces"

    As the above shows, a key can have multiple related values. Each one is demarcated with a : . If the value is longer than a single word, quotation marks are used.

  • The keys are variables. They come in two types: environmental variables and shell variables:

    • Environmental variables are much more permanent and pertain to things like the user and his path (the overall session)
    • Shell variables are more changeable for instance the current working directory (the current program instance)

Variables can be created via config files that run on the initialisation of the session or manually created via the command line in the current session

What are shell variables useful for?

Some deployment mechanisms rely on environmental variables to configure authentication information. This is useful because it does not require keeping these in files that may be seen by outside parties.

More generally they are used for when you will need to read or alter the environment of your system.

Viewing shell and environmental variables

To view the settings of your current environment you can execute the env command which returns a list of the key-value pairs introduced above. Here are some of the more intelligible variables that are returned when I run this command:

SHELL=/usr/bin/zsh
-DESKTOP_SESSION=plasma
-HOME=/home/thomas
-USER=thomas
-PWD=/home/thomas/repos/bash-scripting
-PATH=/home/thomas/.nvm/versions/node/v16.8.0/bin:/home/thomas/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl:/var/lib/snapd/snap/bin

However if you want to target a specific viable you need to invoke printenv with the relevant key, for example:

printenv SHELL
-# SHELL=/usr/bin/zsh

Note that env and printenv do not show all the shell variables, only a selection. To view all the shell variables along with the environmental variables use set .

Creating, exporting and deleting variable shell and environment variables

  • You set shell variables using the same syntax you would within a script file:

    TEST_SHELL_VAR="This is a test"
    -set | grep TEST_SH
    -TEST_SHELL_VAR='This is a test'
    -
    -# We can also print it with an echo, again exactly as we would with a shell script
    -echo S{TEST_SHELL_VAR}
  • We can verify that it is not an environmental variable based on the fact that following does not return anything:

    printenv | grep TEST-SH
  • We can verify that this is a shell variable by spawning a new shell and calling it. Nothing will be returned from the child shell.

  • You can upgrade a shell variable to an environment variable with export :

    export TEST_SHELL_VAR
    -# And confirm:
    -printenv | grep TEST_SH
    -TEST_SHELL_VAR='This is a test'
  • We can use the same syntax to create new environment variables from scratch:

    export NEW_ENV_VAR="A new var"

Using config files to create variables

You can also add variables to config files that run on login such as your user .bashrc / .zshrc . This is obviously best for when you want the variables to persist and be accessible within every Shell-sessions-e6dd743dec1d4fe3b1ee672c8f9731f6.

Important environmental and shell variables

PATH

A list of directories that the system will check when looking for commands. When a user types in a command, the system will check directories in this order for the executable.

echo ${PATH}
-# /home/thomas/.nvm/versions/node/v16.8.0/bin:/home/thomas/.local/bin:/usr/local/sbin:/usr/local/bin:
-# /usr/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl:/var/lib/snapd/snap/bin

For example, if you wish to use npm commands globally (in any directory) you will need to have the requisite Node executable in your path, which you can see above.

SHELL

This describes the shell that will be interpreting any commands you type in. In most cases, this will be bash by default, but other values can be set if you prefer other options.

echo ${SHELL}
-# /usr/bin/zsh

USER

The current logged in user.

echo ${USER}
-# thomas

PWD

The current working directory.

echo ${PWD}
-# /home/thomas
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Equivalent_equations.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Equivalent_equations.html deleted file mode 100644 index fdc163a..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Equivalent_equations.html +++ /dev/null @@ -1,66 +0,0 @@ -Equivalent equations - My Zettelkasten - - - - -

Equivalent equations

Two equations are equivalent if they have the same solution set.

We know from the distributive property of multiplication that the equation \(a \cdot (b + c )\) is equivalent to \(a \cdot b + a \cdot c\). If we assign values to the variables such that \(b\) is \(5\) and \(c\) is \(2\) we can demonstrate the equivalence that obtains in the case of the distributive property by showing that both \(a \cdot (b + c )\) and \(a \cdot b + a \cdot c\) have the same solution:

$$ 2 \cdot (5 + 2) = 14 $$

$$ 2 \cdot 5 + 2 \cdot 2 =14 $$

When we substitute \(a\) with \(2\) (the solution) we arrive at a true statement (the assertion that arrangement of values results in \(14\)). Since both expressions have the same solution they are equivalent.

Creating equivalent equations

We can create equivalent equations by adding, subtracting, multiplying and dividing the same quantity from both sides of the equation (i.e. either side of the \(=\) symbol). Adding or subtracting the same quantity from both sides (either side of the \(=\) ) of the equation results in an equivalent equation.

Demonstration with addition

$$ -x - 4 = 3 -$$

The solution to this equation is $7$

$$ -x - -4 (+4) = 3 (+ 4) -$$

Here we have added \(4\) to each side of the equation. If \(x = 7\) then:

$$ 7 - 4 (+ 4) = 7 $$

and:

$$ 3 + 4 = 7 $$

Demonstration with subtraction

$$ -x + 4 = 9 -$$

The solution to this equation is $5$.

$$ -x + -4 (-4) = 9(-4) -$$

Here we have subtracted \(4\) from each side of the equation. If \(x = 5\) then:

$$ 5 + 4 (-4) = 5 $$

and

$$ 9 - 4 = 5 $$

Demonstration with multiplication

$$x \cdot 2 = 10 $$ The solution to this equation is $5$.

$$ -(x \cdot 2) \cdot 3 = 10 \cdot 3 $$ Here we have multiplied each side of the equation by \(3\). If \(x =5\) then

$$ (5 \cdot 2) \cdot 3 = 30$$ $$ 10 \cdot 3 = 30$$

Demonstration with division

$$x \cdot 3 = 18 $$ The solution to this equation is $6$. $$\frac{x -\cdot 3}{3} = \frac{18}{3} -$$

Here we have divided each side of the equation by \(3\). If \(x\) is 6, then

$$ -\frac{6 -\cdot 3}{3} = 6 -$$

$$\frac{18}{3} = 6 $$

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Equivalent_fractions.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Equivalent_fractions.html deleted file mode 100644 index d4bbebc..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Equivalent_fractions.html +++ /dev/null @@ -1,58 +0,0 @@ -Equivalent fractions - My Zettelkasten - - - - -

Equivalent fractions

Two fractions are equivalent if they represent the same value. To begin with we can represent this visually:

equiv-fractions.png

Each shaded area is taking up the same proportion of the whole.

The same properties can be represented arithmetically by multiplying the numerator and denominator at each step by 2. Thus:

$$ -\\frac{1 (\cdot 2)}{3 (\cdot 2)} = \frac{2}{6} -$$

Therefore the following rule obtains:

If you start with a fraction and multiply both its numerator and denominator by the same value, the resulting fraction is equivalent to the original fraction.

$$ -\\frac{a}{b} = \frac{a \cdot x}{b \cdot x} -$$

This process works in reverse when we invert the operator and use division:

$$ -\\frac{2 (/ 2)}{6 (/ 2)} = \frac{1}{3} -$$

Thus:

If you start with a fraction and divide both its numerator and denominator by the same value, the resulting fraction is equivalent to the original fraction.

$$ -\\frac{a}{b} = \frac{a / x}{b / x} -$$

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Error_handling_in_Python.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Error_handling_in_Python.html deleted file mode 100644 index 5aaebeb..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Error_handling_in_Python.html +++ /dev/null @@ -1,75 +0,0 @@ -Error handling and exceptions in Python - My Zettelkasten - - - - -

Error handling and exceptions in Python

Errors can typically occur in the following scenarios:

  • A file or resource that is referred to does not exist
  • A network connection fails
  • A module import error occurs

In these scenarios you would want to allow for error handling, so that you can detect errors and respond appropriately.

Difference between errors and exceptions.

Python distinguises between errors and exceptions.

  • An error typically indicates a situration where something goes wrong before the execution of the program begins.
  • An exception arises during the execution of the program

In contrast to a error, when an exception occurs, the program doesn’t necessarily stop immediately. Instead, Python provides a way to handle the exception, allowing you to potentially recover from it, or at least, to handle it gracefully before the program stops.

However if you do not implement exception handling, the program will stop immediately when an exception occurs, similar to a error.

The Exception hierarchy

Errors and Exceptions are objects in Python and there is no real syntactic distinction between the two since all errors and exceptions in herit from a base exception class.

The root class is BaseException which all errors and exeptions extend as subclasses as demonstrated by this diagram:

Exception syntax

Difference between raise and except:

  • raise is used to explicitly trigger an exception - it means that you are signalling that an exception condition has occured in your program.
  • except is used in conjunction with tryblocks to catch and handle exceptions. Here you are saying “I think this might cause an exception, so let’s be prepared to handle it”.

Exaple of raise:

x = -10
-if x < 0:
-    raise ValueError("The value should not be negative!")

Example of except:

try:
-    result = 10 / 0
-except ZeroDivisionError:
-    print("You can't divide by zero!")
-

Scaffolding exception handling

There is a general procedure for handling exceptions denoted by certain keywords:

  • try
    • The process you want to run
  • except
    • The errors that could occur. You can have multiple except clauses for different exceptions
  • else
    • Some code you want to run after each of the except clauses have run
    • It must be written after the except clauses
    • It runs if and only if no exceptions were raised
    • If try succeeds or an exception is thrown, else will not run
  • finally
    • What you want to run at the end of the try, except, else sequence
try
-    run_calculation(7)
-except ZeroDivisionError:
-    print('something')
-except IndexError:
-    print('something')
-except FileNotFoundError:
-    print('something')
-except Exception:
-    print('something')
-else
-    # Do something after the exception blocks
-finally
-    # Do concluding action

Custom exceptions

You can create your own custom exceptions by creating a class that inherits from the Exception class.

class CustomError(Exception):
-    pass
-
-try:
-    raise CustomError("This is a custom exception!")
-except CustomError as e:
-    print(f"Caught an exception: {e}")
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Event_loop.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Event_loop.html deleted file mode 100644 index e72b03a..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Event_loop.html +++ /dev/null @@ -1,50 +0,0 @@ -The Event Loop - My Zettelkasten - - - - -

The Event Loop

Node.js provides a single-threaded asynchronous architecture which is achieved via means of the Event Loop.

Multi-threaded synchronous architectures

In the context of backend, a thread as an instance of a request-response transaction.

For example a request is made from the client for a resource contained in a database. The back-end language is an intermediary between the client machine and the server. It receives the request and returns the resource as a response.

Many backend frameworks are synchronous but multithreaded. This means that a thread can only process one request-response cycle at a time. The thread cannot initiate a new cycle until it has finished with its current cycle.

If there was only one thread, this would be inefficient and unworkable. Therefore the framework will be multi-threaded: multiple request-response cycles can be executed at once by different threads.

sync-thread.svg

To accomodate the ability to increase the scale of synchronous applications you need to be able to spawn more threads commensurate to increased demand. This increases the resource consumption of the framework (more cores, more memory etc). Moreover it is possible to reach a point where all threads are active and no more can be spawned. In this case there will simply be delays in the return of data.

Node as a single-threaded asynchronous architecture

In contrast, Node only has a single thread but it works asynchronously, not synchronously. Thus it has a single-threaded asynchronous architecture. This means whilst there is only a single thread it can juggle responses by dispatching them asynchronously. When a request is made it sends it off and continues with its execution and handling new requests. Once these resolve, the data is returned to the main thread.

async.svg

The Event Loop

Node implements its single-threaded asynchronous architecture through the Event Loop.

This is the mechanism by which Node keeps track of incoming requests and their fulfillment status: whether the data has been returned successfully or if there has been error.

Node is continually monitoring the Event Loop in the background.

A running Node application is a single running process. Like everything that happens within the OS, a process is managed by the kernel that dispatches operations to the CPU in a clock cycle. A thread is a sequence of code that resides within the process and utilises its memory pool (the amount of memory assigned by the kernel to the Node process). The Event Loop runs on CPU ticks: a tick is a single run of the Event Loop.

Phases of the Event Loop

The Event Loop comprises six phases. The Event Loop starts at the moment Node begins to execute your index.js file or any other application entry point. These six phases create one cycle, or loop, equal to one tick. A Node.js process exits when there is no more pending work in the Event Loop, or when process.exit() is called manually. A program only runs for as long as there are tasks queued in the Event Loop, or present on the call stack.

The phases are as follows:

  1. Timers
    • These are functions that execute callbacks after a set period of time. As in standard JavaScript there are two global timer functions: setTimeout and setInterval. Interestingly these are not core parts of the JavaScript language, they are something that are made available to JS by the particular browser. As Node does not run in the browser, Node has to provide this functionality. It does so through the core timers module.
    • At the beginning of this phase the Event Loop updates its own time. Then it checks a queue, or pool, of timers. This queue consists of all timers that are currently set. The Event Loop takes the timer with the shortest wait time and compares it with the Event Loop’s current time. If the wait time has elapsed, then the timer’s callback is queued to be called once the call stack is empty.
  2. I/O Callbacks
    • Once timers have been checked and scheduled, Node jumps to I/O operations.
    • Node implements a non-blocking input/output interface. This is to say, writing and reading to disk (files in the Node application directory) is implemented asynchronously. The asynchronous I/O request is recorded into the queue and then the call stack continues.
  3. Idle / waiting / preparation
    • This phase is internal to Node and is not accessible to the programmer.
    • It is primarily used for gathering informtion, and planning what needs to be executed during the next tick of the Event Loop
  4. I/O polling
    • This is the phase at which the main block of code is read and executed by Node.
    • During this phase the Event Loop is managing the I/O workload, calling the functions in the queue until the queue is empty, and calculating how long it should wait until moving to the next phase. All callbacks in this phase are called synchronously (although they return asynchronously) in the order that they were added to the queue, from oldest to newest.
    • This is the phase that can potentially block our application if any of these callbacks are slow or do not return asynchronously.
  5. setImmediate callbacks
    • This phase runs as soon as the poll phase becomes idle. If setImmediate() is scheduled within the I/O cycle it will always be executed before other timers regardless of how many timers are present.
    • This is your opportunity to grant precedence to certain threads within the Node process
  6. Close events
    • This phase occurs when the Event Loop is wrapping up one cycle and is ready to move to the next one.
    • It is an opportunity for clean-up and to guard against memory leaks.
    • This phase can be targetted via the process.exit() function or the close event of a web-socket.

Event loop and event queue

The terms event loop and event queue are often used interchangeably in the literature but in fact they are distinct.

The Event Loop is the Node runtime’s method of execution, the queue is the stack of tasks that are lined up and executed by the loop. We can think of the queue as being the input and the loop as what acts on the input. The queue obviously emerges from the program we write but it is scheduled, organised and sequenced by the loop.

https://blog.appsignal.com/2022/07/20/an-introduction-to-multithreading-in-nodejs.html https://school.geekwall.in/p/Bk2xFs1DV

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Example_scenario_internet_data_transfer.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Example_scenario_internet_data_transfer.html deleted file mode 100644 index 6f4ea07..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Example_scenario_internet_data_transfer.html +++ /dev/null @@ -1,50 +0,0 @@ -Example scenario of data transfer accross the internet - My Zettelkasten - - - - -

Example scenario of data transfer accross the internet

Path of a network request accross the internet

All layers of the IP

  • A client device is connected to a wireless WiFi network.
  • This network is connected to the internet via a router.
  • Elsewhere on the internet is a server also connected to the internet via router.
  • A user of the client device opens a web browser and requests a web page hosted on the server (we will assume it already knows the IP address)
  • The web browser knows HTTP - a protocol of the Application Layer - and forms an HTTP request intended for the destination server.
  • The browser hands off the HTTP request to the TCP/IP software stack of the device’s operating system, asking that the data be delivered to the server on its IP address and at port 80.
  • The TCP/IP software stack on the client OS encapsulates the HTTP payload in a TCP segment (at the Transport Layer), setting the destination port to 80 in the segment header.
  • The Internet Layer software on the client then wraps the TCP segment in an IP packet, which includes the destination IP address of the server in the packet header.
  • At the Link Layer of the client device, the IP packet is encapsulated in a frame with the MAC_address of the local router in its header. The frame is wirelessly transmitted by the client device’s WiFi hardware.
  • The wireless access point receives the frame and passes to the router. The router examines the internet layer packet to determine the destination IP address.
  • To reach the server, the request needs to travel through multiple routers on the internet and the process is replicated (looking up MAC address of the device and determining IP target). Eventually, the request reaches the router on the network where the server is connected.
  • The last router puts the packet in a frame suitable for the server’s local network and in the frame’s header is the MAC address of the server.
  • The server receives the frame and the packet is passed to the TCP/IP software stack. This passes the HTTP data to the process listening on TCP port 80.
  • Web server software, listening on port 80 handles the request and replies to the client, start ing the process again in reverse order.
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Expansions_and_substitutions.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Expansions_and_substitutions.html deleted file mode 100644 index 286ddd5..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Expansions_and_substitutions.html +++ /dev/null @@ -1,70 +0,0 @@ -Expansions and substitutions - My Zettelkasten - - - - -

Expansions and substitutions

Bash is weird in that parentheses, braces and brackets are used not just as markers for different code blocks but as the designators of commands in their own right. The type of bracket you use effects how your input is interpreted.

Below are the main forms of expansion and substitution:

RepresentationName
~ .Tilde expansion
{..}Brace expansion
${...}Parameter expansion
$(...)Command substitution
$((...))Arithmetic expansion

Brace expansion: {..}

Brace expansion is for changing a smaller part of a greater whole programmatically. This is best understood by looking at examples:

echo c{a,o,u}t
-cat cot cut
echo /tmp/{1..3}/file.txt
-/tmp/1/file.txt  /tmp/2/file.txt /tmp/3/file.txt
echo {1..5}
-1 2 3 4 5
-
-echo {5..1}
-5 4 3 2 1
-
-echo {a...c}
-a b c

We can also set sequences. If we wanted to count to twenty in intervals of two

echo {1..20..2}
-1 3 5 7 9 11 13 15 17 19

Note that we type two dots not an elipsis

Example use case

We might use brace expansion to generate sequential file names using a pre-defined naming scheme, eg.

touch file_{01..12}{a..d}
-ls
-
-file_01a
-file_01b
-file_01c
-file_01d
-file_02a
-file_02b
-...
-file_12d

The syntax here basically means: for each of the elements in the first list, run the second list against them.

Parameter expansion: ${...}

We use most frequently for returning the value of stored variables. Techically we do not have to use the braces, we can retrieve with just $var however it’s better to use them to minimise interpretation fuck-ups which happen a lot.

When the braces are used, this allows us to transform the values before they are returned such as only returning from the 6th character: ${var:6}.

Command substition: $(...)

Command substitution (circle-brackets) allows us to put the output of one command inside another. Bash runs the bracketed command in a sub-shell and then returns it to the main user shell.

For example:

echo "The current directory is $(pwd)."

Arithemtic expansion: $((...))

We use arithmetic expansion when we want to calculate numerical values

See Working with numbers in Bash for more.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Exponents.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Exponents.html deleted file mode 100644 index 147e4b2..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Exponents.html +++ /dev/null @@ -1,50 +0,0 @@ -Exponents - My Zettelkasten - - - - -

Exponents

Equivalent equations

Two equations are equivalent if they have the same solution set.

We know from the distributive property of multiplication that the equation \(a \cdot (b + c )\) is equivalent to \(a \cdot b + a \cdot c\). If we assign values to the variables such that \(b\) is equal to \(5\) and \(c\) is equal to \(2\) we can demonstrate the equivalence that obtains in the case of the distributive property by showing that both \(a \cdot (b + c )\) and \(a \cdot b + a \cdot c\) have the same solution:

$$ 2 \cdot (5 + 2) = 14 $$

$$ 2 \cdot 5 + 2 \cdot 2 =14 $$

When we substitute \(a\) with \(2\) (the solution) we arrive at a true statement (the assertion that arrangement of values results in \(14\)). Since both expressions have the same solution they are equivalent.

Creating equivalent equations

Adding or subtracting the same quantity from both sides (either side of the \(=\) ) of the equation results in an equivalent equation.

Demonstration with addition

$$ x - 4 = 3 \\ x -4 (+ 4) = 3 (+ 4) $$

Here we have added \(4\) to each side of the equation. If \(x = 7\) then:

$$ 7 - 4 (+ 4) = 7 $$

and:

$$ 3 + 4 = 7 $$

Demonstration with subtraction

$$ x + 4 = 9 \\ x + 4 (-4) = 9 (-4) $$

Here we have subtracted \(4\) from each side of the equation. If \(x = 5\) then:

$$ 5 + 4 (-4) = 5 $$

and

$$ 9 - 4 = 5 $$

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Expressing_whole_numbers_as_fractions.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Expressing_whole_numbers_as_fractions.html deleted file mode 100644 index bd2120a..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Expressing_whole_numbers_as_fractions.html +++ /dev/null @@ -1,52 +0,0 @@ -Expressing whole numbers as fractions - My Zettelkasten - - - - -

Expressing whole numbers as fractions

Being asked to express a natural number as a fraction seems confusing at first but you need to just know that for any whole number \(n\), you express it as a fraction with \(\frac{n}{1}\).

Express 8 as an equivalent fraction having the denominator 5

$$ -8 = \frac{8}{1} = \frac{8 \cdot 5}{1 \cdot 5} = \frac{40}{5} -$$

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Factors_and_divisors.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Factors_and_divisors.html deleted file mode 100644 index 128e0e8..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Factors_and_divisors.html +++ /dev/null @@ -1,54 +0,0 @@ -Factors and divisors - My Zettelkasten - - - - -

Factors and divisors

The terms factor and divisor are used interchangeably. They are different ways of expressing the same mathematical truth and this is because of the inverse relationship between division and multiplication.

Divisors

For a number \(n\), its divisor is any number that divides \(n\) evenly without remainder: $$ \frac{a}{b} = 0 $$

In this operation, \(a\) is the divisor, \(b\) is the dividend and \(0\) is the quotient.

Factors

For a given number \(n\), its factors are any pair of numbers that when multiplied together return \(n\) as the product: $$ a \cdot b = n $$

We can see the relationship consists in the fact that factors are associated with multiplication and divisors are associated with division: two different perspectives on the same number relationships.

For example, 6 is both a factor and divisor of 18 and 24. To be precise, it is the greatest common divisor of these two numbers.

As a divisor:

$$ -\\frac{18/6}{24/6} = \frac{3}{4} -$$

As a factor:

$$ -\\frac{3 \cdot 6}{4 \cdot 6} = \frac{18}{24} -$$

When we divide by the common divisor is acts as a divisor. When we multiply by the common divisor it acts as a factor. The fact that the fractions are equivalent in both cases indicates that the properties are equivalent.

Greatest common divisor

For two two integers \(a, b\), \(D\) is a common divisor of \(a\) and \(b\) if it is a divisor of both. The greatest common divisor is the largest value that \(D\) can be whilst remaining a divisor to both \(a\) and \(b\).

Demonstration

Find the greatest common divisor of \(18\) and \(24\)

The divisors of 18: $$1, 2, 3, 6, 9, 18$$

The divisors of 24: $$ 1, 2, 3, 4, 6, 8, 12, 24$$

Thus the common divisors are: $$ 1, 2, 3, 6 $$

The largest value in the above set is 6, thus 6 is the greatest common divisor.

Heuristics for finding divisors

  1. For dividend \(n\) , if \(n\) ends in an even number or zero, \(n\) is divisible by 2.
    1. \(\frac{12}{2} = 6\)
    2. \(\frac{84}{2} = 42\)
  2. For dividend \(n\) if the sum of the digits is divisible by 3 then \(n\) is divisible by 3.
    1. \(\frac{72}{3} = 24\)
    2. \(\frac{21}{3} = 7\)
  3. For a dividend \(n\) if the number represented of the last two digits of \(n\) divides by 4 then \(n\) is divisible by 4
    1. \(\frac{324}{4} = 81\)
    2. \(\frac{532}{4} = 133\)
  4. For a dividend \(n\), if the last digit of \(n\) is divisible by 0 or 5, then \(n\) is divisible by 5.
    1. \(\frac{25}{5} = 5\)
  5. For a dividend \(n\), if \(n\) is divisible by 2 and 3, then \(n\) is divisible by 6.
    1. \(\frac{12}{6} = 2\)
    2. \(\frac{18}{6} = 3\)
  6. For a dividend \(n\), if the last three digits of \(n\) are divisible by 8, then \(n\) is divisible by 8.
    1. \(\frac{73024}{8} = 9128\)
  7. For a dividend \(n\), if the sum of the digits of \(n\) is divisible by 9 then \(n\) is divisible by 9.
    1. \(\frac{117}{9} = 13\)
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Factory_pattern.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Factory_pattern.html deleted file mode 100644 index 546d381..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Factory_pattern.html +++ /dev/null @@ -1,111 +0,0 @@ -Factory pattern - My Zettelkasten - - - - -

Factory pattern

The factory pattern pertains to how objects are created in the course of the code. It is class based.

In this pattern we create a class interface that delegates the responsibility of object instantiation to its subclasses.

You have a high level class that sits on top of two or more lower level classes that are semantically related but different in function. Depending on the input the higher level class receives upon instantiation, it will generate one of the lower level classes.

Advantages

  • allows for dynamic creation
    • we may not know what objects are required until runtime: the factory allows us to cover several eventualities
  • decoupling
    • in cases where the lower level classes combine to create something greater than their individual parts (see the Alligator example below), they do not have to know about each other.
  • maintenance
    • allows us to add/remove new object classes easily without changing a lot of code.

Examples

We have two types of notification: email and push. The creation of these two is handled by a factory class called NotificationFactory :

class PushNotification {
-  constructor(sendTo, message) {
-    this.sendTo = sendTo;
-    this.message = message;
-  }
-}
-
-class EmailNotification {
-  constructor(sendTo, cc, emailContent) {
-    this.sendTo = sendTo;
-    this.cc = cc;
-    this.emailContent = emailContent;
-  }
-}
class NotificationFactory {
-  createNotification(type, props) {
-    switch (type) {
-      case "email":
-        return new EmailNotification(
-          props.sendTo,
-          props.cc,
-          props.emailContent
-        );
-      case "push":
-        return new PushNotification(props.sendTo, props.message);
-    }
-  }
-}

We first instantiate an instance of the factory and then pass into it the parameters for either of the two lower level classes.

const factory = new NotificationFactory();
-
-// create email notification
-const emailNotification = factory.createNotification("email", {
-  sendTo: "receiver@domain.com",
-  cc: "test@domain.com",
-  emailContent: "This is the email content to be delivered.!",
-});
-
-// create push notification
-const pushNotification = factory.createNotification("push", {
-  sendTo: "receiver-device-id",
-  message: "The push notification message",
-});

This example doesn’t use a constructor on the factory class, but we could easily do so. This would remove the need to call a method on the factory class when we want to instantiate one of the subclasses. Here is another example that does this with an alligator factory:

class ReptilePartFactory {
-  constructor(type, props) {
-    if (type === "tail") return new TailFactory(props);
-    if (type === "torso") return new TorsoFactory(props);
-    if (type === "head") return new HeadFactory(props);
-  }
-}
-
-let alligator = {};
-let alligatorProps = {
-  tailLength: 2.5,
-  color: "green",
-  snoutLenth: 1,
-};
-
-//gets a tail from the tail factory
-alligator.tail = new ReptilePartFactory("tail", alligatorProps);
-
-//gets a torso from the torso factory
-alligator.torso = new ReptilePartFactory("torso", alligatorProps);
-
-//gets a head from the head factory
-alligator.head = new ReptilePartFactory("head", alligatorProps);
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Fetch_decode_execute.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Fetch_decode_execute.html deleted file mode 100644 index dbf7c41..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Fetch_decode_execute.html +++ /dev/null @@ -1,50 +0,0 @@ -Fetch, decode, execute, store - My Zettelkasten - - - - -

Fetch, decode, execute, store

Fetch, decode, execute is the operating cycle of the CPU. We will run through how this works with reference to the CPU architecture.

Fetch

Overview

First, instructions and data are fetched from outside of the CPU chip (usually from the DRAM). In some cases, the data used by an instruction will be included with it. In other instance the instruction will reference the location where the data are held as an address.

Specifics

  • The Program Counter register needs to keep track and sequence the different instructions that the CPU will work on. The first place it will look for an instruction is at the DRAM address 0000, equivalent to 0 in the Program Counter register: the starting point. This is address therefore copied to the Memory Address Register for future reference.
  • This memory-storing event constitutes an instruction so it is copied to the Instruction Register.
  • As the first instruction has been fetched, the system reaches the end of the first cycle. Thus the Program counter increments by 1 to log this.
  • The next fetch cycle begins.

Decode

Overview

Once the CPU has received the instruction, the CPU controller chip analyses it to determine which of its circuits should be used for processing.

Specifics

  • Now that the instruction is fetched and stored in the RAM it needs to be decoded. It is therefore sent from the RAM to the Control Unit of the CPU. There are two parts to the instruction:
    1. The operation code (“op code”): the command that the computer will carry out.
    2. The operand: an address in RAM where the data will be read and written to as part of the execution
  • The Control Unit converts the operation code and operand into an instruction that is fed to the next stage in the cycle: execution. For example, for an add function, add would be the op code and address x and address y would be the operands, thus the instruction would be: add the value in address x to the value in address y.

Execute

Now the command will be executed. The operand is copied to the Memory Address Register and then passed to the Memory Data Register and the command is carried out by the ALU. The activities of ALU are covered in CPU Architecture and the notes on Logic Gates.

Store

Overview

As well as telling the CPU what operation to perform, the instructions must specify where to store the result.

Specifics

  • Data is stored differently depending on the instruction.
  • If the instruction is iterative (e.g. adding two numbers and then multiplying by another number), the instruction will tell the CPU to store the interim first value in the CPU’s registers. As these are part of the CPU, the data can be retrieved more readily. If the value is not expected to be used again immediately, it goes to the DRAM or harddisk.
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Fetch_from_Secrets_Manager.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Fetch_from_Secrets_Manager.html deleted file mode 100644 index 9d80ab5..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Fetch_from_Secrets_Manager.html +++ /dev/null @@ -1,80 +0,0 @@ -Fetch from Secrets Manager - My Zettelkasten - - - - -

Fetch from Secrets Manager

TypeScript

const getSecret = async (): Promise<SomeCredentials> => {
-  const secretsManager = new AWS.SecretsManager();
-  const response = await secretsManager
-    .getSecretValue({ SecretId: process.env.SECRET_ARN as string })
-    .promise();
-  const secretValues = JSON.parse(response.SecretString as string);
-
-  if (secretValues) {
-    return {
-      accessToken: secretValues.POCKET_ACCESS_TOKEN,
-      consumerKey: secretValues.POCKET_CONSUMER_KEY,
-    };
-  } else {
-    throw new Error("Failed to return Pocket credentials");
-  }
-};
-
-type SomeCredentials = {
-  accessToken: string;
-  consumerKey: string;
-};

Python

import json
-import boto3
-
-def get_secret():
-    python_env = os.environ.get("PYTHON_ENV", "local")
-    """In production, source creds from SecretsManager"""
-    if python_env == "production":
-        secrets_manager = boto3.client("secretsmanager")
-        response = secrets_manager.get_secret_value(SecretId=os.environ["SECRET_ARN"])
-        secret_values = json.loads(response["SecretString"])
-        return secret_values["GOOGLE_CREDS"]
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/File_descriptors.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/File_descriptors.html deleted file mode 100644 index d385546..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/File_descriptors.html +++ /dev/null @@ -1,50 +0,0 @@ -File descriptors - My Zettelkasten - - - - -

File descriptors

File descriptors are shorthand for stdin, stdout and stderr:

File descriptorNameCommon abbreviation
0Standard inputstdin
1Standard outputstdout
2Standard errorstderr

They are typically used when you want to redirect the output of the standard/input /output/error somewhere, e.g a file or as input to another program. A classic case is [some_command] > /dev/null 2>&1

They are all technically “files” which are open and which append themselves to every process that can run in the shell. For any command or program that you run, you will be able to access 0, 1 and 2 for them. In this way they are similar to variables like $0 and $@. They have a universal meaning within the context of the shell runtime.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/File_permissions_and_execution_in_Bash.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/File_permissions_and_execution_in_Bash.html deleted file mode 100644 index 3bc0d71..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/File_permissions_and_execution_in_Bash.html +++ /dev/null @@ -1,66 +0,0 @@ -File permissions and executables - My Zettelkasten - - - - -

File permissions and executables

Every Unix file has a set of permissions that determine whether you can read, write or run (execute) the file.

Viewing file permissions

In order to see file permissions within the terminal, use the -l or -rfl with the ls command. Remember this command can be applied at both the directory and single-file level. For example:

drwxr-xr-x  7 thomas thomas 4096 Oct  2 19:22 angular-learning-lab
-drwxr-xr-x  5 thomas thomas 4096 Oct 17 18:05 code-exercises
-drwxr-xr-x  5 thomas thomas 4096 Sep  4 16:15 js-kata
-drwxr-xr-x  9 thomas thomas 4096 Sep 26 18:10 sinequanon
-drwxr-xr-x 12 thomas thomas 4096 Sep 19 17:41 thomas-bishop
-drwxr-xr-x  5 thomas thomas 4096 Sep  4 19:24 ts-kata

What the output means

The first column of the permissions output is known as the file’s mode. The sequence from left to right is as follows:

-       - - -                 - - -                 - - -
-type    user permissions      group permissions     other permissions
-
type
-
The file type. A dash just means an ordinary file. `d` means directory
-
user permissions
-
read, write or execute. A dash means 'nothing': the permissions for that slot in the set have not be assigned
-
group and other
-
group is obviously what anyone belonging to the current file's user group can do. Everyone else (outside of the user and the group) is covered by the other permissions, sometimes known as 'world' permissions
-
-

Modifying permissions: chmod

We use chmod for transferring ownership and file permissions quickly from the command-line.

Octal notation

chmod uses octal notation. Each numeral refers to a permission set. There are three numerals. The placement denotes the user group. From left to right this is:

  • user
  • group
  • everyone else.

If you are working solo and not with group access to files, you can disregard assigning the other numerals, by putting zeros in as placeholders.

685254916b2642f189e6316b876e09c9

Example

$ chmod -v 700 dummy.txt
-$ ls -l dummy.txt
-$ -rwx------  1 thomasbishop  staff  27 13 May 15:42 dummy.txtExample

Useful options

-v → verbose: tell the user what chmod is doing

-r → work recursively, i.e apply the action to directories as well as files

-f →silent: suppress most error messages

Running bash files

In most cases, especially when you are working alone, the most frequent codes you are going to need are 700 and 600. When shell scripting, you need to make your scripts executable for them to work, therefore you should always chmod 700 when creating a .sh file.

Then to invoke the script from the shell you simply enter:

./your-bash-script.sh
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Filesystems.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Filesystems.html deleted file mode 100644 index 4939311..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Filesystems.html +++ /dev/null @@ -1,65 +0,0 @@ -Filesystems - My Zettelkasten - - - - -

Filesystems

We cannot yet mount or interact with the partitions we have created. This is because we have not added a filesystem to each partition.

A filesytem is a form of Basic_database_concepts; it supplies the structure to transform a simple block device into the sophisticated hierarchy of files and subdirectories that users can understand.

Linux recognises many types of filesystems. The native Linux filesystem is the ext4 (Fourth Extended Filesystem). Another common filesystem is FAT (File Allocation Table). Instances of this include MSDOS,EXFAT,FAT-32. They originate from Microsoft systems

Creating a filesystem

Remember we have two partitions on our external drive: sda1 and sda2. We are going to use the mkfs utility to create an EXT4 system on both.

mkfs -t ext4 /dev/sda1
-mkfs -t ext4 /dev/sda2

Mounting a filesystem

We can now mount our filesystems. When we mount, we must specify the following criteria with the request:

  • The name of the device we want to mount.
    • This will be the name or the partition. However the names (sda etc) assigned by the OS can change. In these cases and with GPT-based partitions you can use the UUID.
    • To see a list of devices and the corresponding filesystems and UUIDs on your system, you can use the blkid (‘block id’) program.
      /dev/nvme0n1p3: UUID="c53577b5-92ef-4a0a-9a19-e488bfdfa39c" BLOCK_SIZE="4096" TYPE="ext4" PARTUUID="e152b9f4-7ce8-e74b-94db-2731c6fce53d"
      -/dev/nvme0n1p1: UUID="9920-636A" BLOCK_SIZE="512" TYPE="vfat" PARTUUID="50592521-d386-194a-a362-bc8562ed6c82"
      -/dev/nvme0n1p2: UUID="2ee6b834-0857-49dc-b8ba-a24d46d228ae" BLOCK_SIZE="4096" TYPE="ext4" PARTUUID="e08cc442-ef51-7b4f-9d55-e236c55c933c"
      -/dev/sda2: UUID="abac6e2e-e3bf-40d3-a5ba-317c53eb27ce" BLOCK_SIZE="4096" TYPE="ext4" PARTUUID="4ef1b0e8-3d5b-c940-a3b1-0f85cddeca42"
      -/dev/sda1: UUID="ba1e40c5-9b29-4309-a559-99bf8f68116f" BLOCK_SIZE="4096" TYPE="ext4" PARTUUID="b4983358-6036-df40-a1f8-793976f3dfb1"
  • The filesystem type (optional)
  • The mount point
    • This is the place within the existing filesystem where you want to mount the partition.
    • When you mount to a directory, this directory becomes the disk you have mounted, you will not see it as a subdirectory within the the mount point, you will just see the contents of the disk itself
mkdir mountpoint
-mount -t ext4 /dev/sda1 /mnt
-touch test.txt

Our sda1 partition is now mounted at mountpoint. We can go ahead and create files. If we now look within the graphical file manager when we click on the sda1 volume, we will see the new file we have created in mountpoint.

fstab

In most cases you want your filesystem to mount automatically on boot and always to the same mount point. You can do this via the specialised fstab file on Linux systems within the /etc/ directory.

This is my current fstab:

# <file system> <dir> <type> <options> <dump> <pass>
-# /dev/nvme0n1p2
-UUID=2ee6b834-0857-49dc-b8ba-a24d46d228ae	/         	ext4      	rw,relatime	0 1
-
-# /dev/nvme0n1p3
-UUID=c53577b5-92ef-4a0a-9a19-e488bfdfa39c	/home     	ext4      	rw,relatime	0 2
-
-/swapfile none swap sw 0 0
-

It shows my root and home filesystems and my swap file. Note that we use the UUID to name the partition rather than its name in /dev/. The order of the parameters is as follows:

  • Device name or UUID
  • The mount point
  • The filesystem type (in the example there are two types (ext4 and swap))
  • Options
  • Now largely irrelevant backup information, set to )
  • Filesystem integrity test order
    • Runs the fsck (‘filesystem check’) command against each filesystem
    • Put 1 against the root partition for this to be checked first
    • Put 0 for no checks to take place
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Find_Bash_command.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Find_Bash_command.html deleted file mode 100644 index 9048a7c..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Find_Bash_command.html +++ /dev/null @@ -1,61 +0,0 @@ -find - My Zettelkasten - - - - -

find

find can be used both to locate files and run operations on the files it finds.

Main syntax

No options

Without options specified, find alone will return a recursive index of all the files in the directory from which it is run.

Sub-directory

If we pass a directory to find it will repeat the above process but specifically for that directory.

$ find i3
-i3
-i3/config

Filters

We can specify flags as filters (known as ‘tests’ within the program).

Type

Filter by type: file or directory

$ find -type d # return dirs only
-$ find -type f # return files only

Within a specified directory:

$ find i3 -type f

Filename

This is the most frequent use case: filter files by name with globbing.

$ find -name "config"
-./.git/config
-./i3/config
$ find -name "*.js"

The same, but case insensitive: iname

$ find -iname "*.JS"

Path

As above but this time includes directory names in the match. ipath is the case-insensitive version.

$ find -path "utils*"
-utils.js
-utils/do-something.js

Operators

We can combine find commands by using logical operators: -and, -or, -not. For example:

$ find -not -name "*.js" -type f
-./app/index.html
-./app/style.css
-./dist/index.html
-./dist/style.c

Applied to a directory:

find . -type -f -not -path "./.git/"

Run programs against results

Using the exec keyword we can run a program against the files that are returned from find.

In this syntax we use {} as a placeholder for the path of the file that is matched. We use ; (escaped) to indicate the end of the operation.

Examples

This script deletes the files that match the filter criteria:

$ find -name "*.js" -exec rm {} \;

This script finds all the files with the substring ‘config’ in their name and writes their file size to a file.

find -name '*config*' -exec wc -c {} \; > config-sizes
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Flip_flops.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Flip_flops.html deleted file mode 100644 index 4ac83f0..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Flip_flops.html +++ /dev/null @@ -1,50 +0,0 @@ -Flip-Flops - My Zettelkasten - - - - -

Flip-Flops

A flip-flop is a type of latch that is connected to a clock signal and which executes in time with the clock’s pulse. (Sometimes “latch” and “flip-flop” are used interchangeably but technically a latch is flip-flop without a clock connection.)

JK Flip-Flop

The JK Flip-Flop (the letters are meaningless) is basically an SR latch in functionality. It has a “set” input (J) and a “reset” input (K) and Q and inverted-Q outputs.

Where it differs from the SR is that it the SR will change state just if the voltage is high (this, afterall, is all that a bit is) whereas for the JK to set it must receive a clock pulse and it will only set on the pulse. Hence in addition to J and K inputs it has a CLK input for “clock”.

In addition the JK Flip-Flop has a toggle function. When this is executed, whatever Q currently is will be flipped to its opposite value: \(1 \rightarrow 0\), \(0 \rightarrow 1\). The toggle executes when both J and K are set to high.

The possible state changes for the JK Flip-Flop are detailed below:

JKClockQ stateOperation
00PulseMaintain previous valueHold
01Pulse0Reset
10Pulse1Set
11PulseInverse of previous valueToggle

A JK Flip-Flop can execute on either the positive or negative pulse. Below are the diagrams for a rising and falling pulse respectively:

T Flip-Flops

Another type of Flip-Flop can be created by connecting the J and K inputs of a JK Flip-Flop to each other. This reduces the possible states to two: toggle current state or maintain current state. Its overall logic is therefore reduced to just two lines of the previous state table: the state that obtains when J and K are \(0 0\) or \(1 1\).

Thus the state table for the T Flip-Flop is:

TClockQ stateOperation
0PulseMaintain previous valueHold
0PulseInverse of previous valueToggle

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Foreign_keys_in_SQL.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Foreign_keys_in_SQL.html deleted file mode 100644 index 6527d7a..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Foreign_keys_in_SQL.html +++ /dev/null @@ -1,62 +0,0 @@ -Creating views with foreign keys - My Zettelkasten - - - - -

Creating views with foreign keys

We utilise foreign and Primary_key to create relationships between tables in SQL. Foreign keys link data in one table to the data in another table and are how we cross-reference data in SQL.

In essence you use the primary key of one table to access data in another table. When one table A contains the primary key of another table B as a field, that key is “foreign” to A hence the name.

Let’s say we have a sales table:

saleIdmodelIdsaleDateemployeeIdprice
1442020-07-27tbishop399.99
2222021-02-05tbishop200.99

In SQL this would be set up as follows:

CREATE TABLE sales (
-  saleId integer PRIMARY KEY,
-  modelId integer,
-  saleDate date,
-  employeeId text,
-  price float
-)

For every model that is sold it is possible for the customer to return it. This data will be kept in another table returns. Every model sold will have an entry in sales but may or may not have an entry in returns (not every customer will return an item).

We want to establish a relationship between the two tables so that if an item is returned we can trace it back to its original sale.

As the saleId is the primary key in sales this means it is a unique identifier for each model sold. We will therefore use this in our returns table to track the sale data.

Here’s our returns table:

returnIdsaleIdreturnDatereason
789912020-11-218New device issued under warranty due to defect
671122022-09-02Returned gift

In this table saleId is identical to saleId in sales. It is the primary key in sales but a foreign key in returns. If a device has been returned it must have an entry in returns and the salesId of the entry in returns must match the salesId in sales.

This is the primary benefit of utilising foreign keys: they add a restriction. Entries to the table with a foreign key must have a value that corresponds with the foreign key column.

We call this a foreign key contraint. More explicitly, our contraint is as follows:

Any value entered into returns.saleId must already exist in sales.salesId

A secondary benefit is that they save us the trouble of repeating data. Without foreign keys we would have to input saleId twice in two different tables.

We establish the foreign key reference with ther following SQL:

CREATE TABLE returns (
-	returnId integer PRIMARY KEY,
-	saleId integer NOT NULL,
-	returnDate date,
-	reason text,
-	FOREIGN KEY (sale_id) REFERENCES sales(sale_id)
-	);

A table can have more than one foreign key.

If you delete the source of the foreign key, you also delete its references in tables for which it is a foreign key. This is important to remember. So if a row was deleted from sales the row in returns with the corresponding saleId would also be deleted.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Formal_conventions.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Formal_conventions.html deleted file mode 100644 index facd957..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Formal_conventions.html +++ /dev/null @@ -1,53 +0,0 @@ -Formal conventions - My Zettelkasten - - - - -

Formal conventions

Grouping symbols

We use parentheses to delimit the part of an expression we want evaluated first. If grouping symbols are nested, evaluate the expression in the innermost pair of grouping symbols first,

Writing mathematical statements: placement of \(=\)

We only write one equals sign per line. For example, if we are resolving parentheses:

$$ -\begin{equation} \begin{split} 2 + \[3 + (4+5)\] = 2 + \[3 +9\] \\ = 2 + 12 -\\ = 14 \end{split} \end{equation} -$$

We call parentheses (()), brackets ([]) and braces {}) grouping symbols. When groupings (say parentheses) are used, the expression inside any pair of parentheses must be evaluated first.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Formal_proofs_in_propositional_logic.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Formal_proofs_in_propositional_logic.html deleted file mode 100644 index 0aa6143..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Formal_proofs_in_propositional_logic.html +++ /dev/null @@ -1,52 +0,0 @@ -Formal proofs in propositional logic - My Zettelkasten - - - - -

Formal proofs in propositional logic

When we construct a formal proof in logic we are seeking to show that a certain proposition is derivable from other propositions. We use the words derivation and proof interchangeably.

A sentence \(P\) is derivable in a system of propositional logic from a finite set of sentences if and only if there is a derivation in this system in which all and only the members of the set are primary assumptions and \(P\) is the sentence on the last line.

We express the above symbolically as \(\Gamma \vdash P\) . (Be careful not to confuse derivable (\(\vdash\)) from entails (\(\vDash\)).

Derivability is therefore a property that a proposition can possess relative to a set.

For instance to demonstrate derivability for:

$$ -\{ \lnot F \lor D, F, D \rightarrow (G \land H) \} \vdash G \land H -$$

We would establish \(\lnot F \lor D, F, D \rightarrow (G \land H)\) as primary assumptions and then, using the derivation rules of the system conclude with \(G\land H\). Every sentence in the derivation is either a primary assumption or an auxiliary assumption or justified by the rules of the derivation.

An auxiliary assumption is an assumption belonging to a sub-derivation. Primary assumptions belong to the main derivation. For any given derivation of the form \(\Gamma \vdash P\) there may be a number of ways of demonstrating the derivation (more than one application of the rules governing the system) but one alone is sufficient to establish derivability.

We will tend to use the terms derivation and proof interchangeably but we should note that there is a technical distinction in that a proof is a derivation in which all of the assumptions have been discharged

Constructing proofs

We place assumptions above derivations and mark them A in the right-hand margin. We use a shorthand for the derivation rules and also place these in the right-hand margin.

We divide assumptions from derivations with a horizontal line. We number each line and use this to refer to the line we are applying the derivation to. Sub-proofs follow this structure recursively. This is known as Fitch notation

Schematically:

Applied example:

Sub-proofs

When a sub-proof is terminated, the assumption with which it starts is said to be discharged. It’s conclusion can then be drawn upon and invoked within the main proof by reference to its start and end line number. However statements within the sub-proof cannot be referred to again from within the main proof, only its result.

Derivation rules

Derivation rules are Syntax_of_sentential_logic rather than semantic. They are applied on the basis of their form rather than on the basis of the truth conditions of the sentences they are applied to.

Derivation rules can be applied without having an interpretation of the symbols in mind. A derivation rule tells us that: given a group of symbols with a certain structure, we can write down another group of symbols with a certain structure.

Each of the main logical connectives has an associated derivation rule. The binary connectives have pairs of rules, one for the introduction of the connective and one for its elimination.

The main derivation rules:

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Format_specifiers_in_C.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Format_specifiers_in_C.html deleted file mode 100644 index 4a0bdae..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Format_specifiers_in_C.html +++ /dev/null @@ -1,50 +0,0 @@ -Format specifiers in C - My Zettelkasten - - - - -

Format specifiers in C

Format specifiers define the type of data to be printed on standard output. You need to use format specifiers whenever you are printing-values-in-c.

SpecifierUsage
%csingle character
%sstring
%nnothing
%dinteger (assuming base 10)
%ffloat
%%The percent sign itself
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Formatting_output_text_in_Bash.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Formatting_output_text_in_Bash.html deleted file mode 100644 index 03bd6e2..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Formatting_output_text_in_Bash.html +++ /dev/null @@ -1,61 +0,0 @@ -Formatting output text in Bash - My Zettelkasten - - - - -

Formatting output text in Bash

We can use the -e flag with echo to have greater control over the output of text. -e allows us to use linebreaks, tabs and other formattings within a string.

Output text in columns

echo -e  "Name\t\tNumber"; echo -e "Thomas\t\t123";
-
-Name		Number
-Thomas		123

Break text over several lines

echo -e "This text\nbreaks over\nthree lines"
-
-This text
-breaks over
-three lines

Colour outputs

echo -e "\033[31;40mColoured Text\033[0m"

The coloured section is prepended by \033[ and ended with [0m. The foreground colour is given first, and then the background colour.

We can also change the text style. We do this by adding an extra value after the first square bracket:

echo -e "\033[4;31;40mColoured Text\033[0m"

This underlines the output.

We can create a script that simplifies the construction of colour-formatted text, e.g

ulinered="\033[4;31;40m"
-red="\033[31;40m"
-none="\033[0m"
-
-echo -e $ulinered"ERROR:"$none$red" Something went wrong."$none
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Forms_in_React.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Forms_in_React.html deleted file mode 100644 index f052e11..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Forms_in_React.html +++ /dev/null @@ -1,117 +0,0 @@ -Forms using hooks - My Zettelkasten - - - - -

Forms using hooks

With hooks, form processing is exactly the same as classes in terms of the overall methodology, but the syntax is slightly different as a result of the useState hook.

Basic approach

Instead of using this.state and this.setState . We just have the useState hook. But the controlled component principle is the same. Let’s say we have a simple email input:

const [email, setEmail] = useState("");

As this is a form, the state change is going to be the result of user input. So we need to prep our form to enable this.

<input type="text" value="{email}" onChange="{setEmail}" />

Now we just need to make good on the setEmail method we declared when we initialised the state:

const handleChange = (event) => {
-  setEmail(event.target.value);
-};

Applied example

Here is an applied example of the above approach for a form that has three input fields. This component outputs the inputs as JSON on submit:


-function FormHook() {
-  const [email, setEmail] = useState("");
-  const [phone, setPhone] = useState("");
-  const [age, setAge] = useState("");
-  const [formOutput, setFormOutput] = useState("Form output");
-
-  const handleSubmit = (event) => {
-    event.preventDefault();
-    setFormOutput(
-      JSON.stringify({ email: email, phone: phone, age: age }, null, 2)
-    );
-  };
-	return (
-		<form onSubmit={handleSubmit}>
-			<input type="text" value={email} onChange={(event) => setEmail(event.target.value)}>
-			<input type="text" value={phone} onChange={(event) => setPhone(event.target.value)}>
-			<input type="number" value={age} onChange={(event) => setAge(event.target.value)}>
-			<button type="submit">Submit</button>
-		</form>
-	)
-};

More complex forms

The above is fine if you only have one form with a couple of inputs. But if you are managing multiple forms or forms with a complex array of inputs, you would need to create useState declaration for every single input with a custom onChange event for each one which is repetitious and not very clean.

So instead of this, just like with class-based controlled components, we use the name HTML attribute to distinguish each input and create a generic onChange function that distinguishes each separate input by destructuring a key, value object using the name.

<form onSubmit={handleSubmit}>
-			<input type="text" name="email" value={formValues.email} onChange={handleChange}>
-			<input type="text" name="phone" value={formValues.phone} onChange={handleChange}>
-			<input type="number" name="age" value={formValues.age} onChange={handleChange}>
-			<button type="submit">Submit</button>
-</form>
const initialState = {
-  email: "",
-  phone: "",
-  age: "",
-};
-
-const [formValues, setFormValues] = useState(initialState);
-
-const handleChange = (event) => {
-  const { name, value } = event.target;
-  setFormValues({ ...formValues, [name]: value });
-};

There are three parts:

  1. First we create the initial state.
  2. Next we store this initial state as the variable in the useState initialisation: formValues . We also provide a method setFormValues which will be used by the change handler to log the user’s inputs.
  3. Finally we create the function that will log the user changes. First we use object destructuring on the change event to enable us to retrieve the name and value attributes of the HTML inputs in the component. Then we use spread syntax to say that for each input pair, retrieve its value, using the destructured name variable as the key.

Applied example

Below I have updated the previous context to this time reflect the new, abstracted logic:

function FormHookAbstracted() {
-  const initialState = {
-    email: "",
-    phone: "",
-    age: "",
-  };
-	const [formValues, setFormValues] = useState(initialState);
-	const handleChange = (event) => {
-    const { name, value } = event.target;
-    setFormValues({ ...formValues, [name]: value });
-  };
-  const handleSubmit = (event) => {
-    event.preventDefault();
-    setFormOutput(
-      JSON.stringify({ email: email, phone: phone, age: age }, null, 2)
-    );
-  };
-	return (
-		<form onSubmit={handleSubmit}>
-			<input type="text" name="email" value={formValues.email} onChange={handleChange}>
-			<input type="text" name="phone" value={formValues.phone} onChange={handleChange}>
-			<input type="number" name="age" value={formValues.age} onChange={handleChange}>
-			<button type="submit">Submit</button>
-		</form>
-	)
-};
-export default FormHookAbstracted;

Note that instead of individual variables email , phone, age , this approach returns a single object formValues . We could therefore access the individual values with e.g [formValues.email](formvalues.email) .

As it is an object, it makes resetting to the original state very easy, viz:

const handleReset = () => {
-  Object.values(formValues).map((x) => setFormValues(initialState));
-};
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Four_bit_adder.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Four_bit_adder.html deleted file mode 100644 index 99b4647..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Four_bit_adder.html +++ /dev/null @@ -1,53 +0,0 @@ -Four-bit adder - My Zettelkasten - - - - -

Four-bit adder

A single half adder and full adder allows us to calculate the sum of two 1-bit numbers, but this is not much use in practice. To approximate what is really happening at the circuit level in computers we need to be able to add bigger binary numbers. We will demonstrate how this can be achieved for a four-bit number (nibble) using repeated full adders and half adders.

We want to be able to calculate the following sum:

0010
-0011
-____
-0101

We will achieve this by using three full adders and one half adder, moving from right to left. The half adder will be used at the beginning to calculate the least significant bit as it will have no carry-in. The subsequent three bits will all be added using a full adder.

Let’s walk through the process:

  1. HA receives the bits \(0\) and \(1\) as inputs. It outputs \(1\) as the sum bit and \(0\) as the carry-out.
  2. FA1 receives \(0\) as the carry-in bit plus \(1\) and \(1\) as its input. This means it has the following calculation to execute: \(1 + 1 + 0\). This gives \(0\) as the sum bit and \(1\) as the carry-out bit.
  3. FA2 receives \(1\) as the carry-in (the carry-out from FA1) plus \(0\) and \(0\) as its own inputs. \(0 + 0 + 1\) gives us \(1\) as the sum bit and \(0\) as the carry-out.
  4. Finally FA3 receives \(0\) as its carry-in plus \(0\) and \(0\) as its inputs. \(0 + 0 + 0 = 0\), therefore its sum bit is \(0\) and the overall sum of the four bits is \(0101\). There is no carry out as there are no more bits to add.

Ripple carry adder

We notice that as the calculation proceeds, the carry bits propagate or ripple through the circuit. For this reason, a four-bit adder constructed in the manner of this circuit is called a ripple carry adder.

There are two important consequences to note about this type of circuit:

  • Each carry bit that ripples to the next full adder introduces a small delay. Therefore extending the circuit to handle more bits will make the circuit slower overall.
  • Because the value of the bits changes through the course of the ripple, the output of the circuit will be innacurate until all the carry bits have had time to propagate.
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Frequency_counters.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Frequency_counters.html deleted file mode 100644 index 589b676..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Frequency_counters.html +++ /dev/null @@ -1,64 +0,0 @@ -Frequency counters - My Zettelkasten - - - - -

Frequency counters

Here is a concise method for counting the number instances of each type of array element.

function frequencyCounter(...inputArr) {
-  let counter = {};
-  inputArr.forEach((item) => {
-    // If item doesn't exist as a key in the counter, make 0 the val and add one
-    // If item already exists as key in the counter, increment it by one
-    counter[item] = (counter[item] || 0) + 1;
-  });
-  return counter;
-}

An application of this would be checking for duplicates in an array:

const testArr = [1, 4, 3, 3];
-const arrayFreq = frequencyCounter(testArr);
-let count = Object.values(arrayFreq);
-
-if (count.some((ele) => ele > 1)) {
-  return "There are duplicates";
-} else return "No duplicates";
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Full_Node_API_example.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Full_Node_API_example.html deleted file mode 100644 index 55798f9..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Full_Node_API_example.html +++ /dev/null @@ -1,154 +0,0 @@ -Creating a RESTful API: Full example - My Zettelkasten - - - - -

Creating a RESTful API: Full example

const express = require("express");
-const app = express(); // convention to name Express as the app
-const port = process.env.PORT || 3000;
-const Joi = require("joi");
-const helmet = require("helmet");
-const morgan = require("morgan");
-const courses = require("./routes/courses");
-
-// Routes
-app.use("/api/courses", courses);
-
-// Middlewear
-app.use(express.json());
-app.use(helmet());
-
-const courses = [
-  {
-    id: 1,
-    name: "First course",
-  },
-  {
-    id: 2,
-    name: "Second course",
-  },
-  {
-    id: 3,
-    name: "Third course",
-  },
-];
-
-if (app.get("env") === "development") {
-  app.use(morgan("common"));
-}
-
-app.listen(port, () => console.log(`Listening on ${port}`));
-
-function validateCourse(course) {
-  const schema = Joi.object({
-    name: Joi.string().min(3).required(),
-  });
-
-  const { error } = schema.validate(course);
-  return error;
-}
-
-/**
- *  Note that the following request handlers would not be stored in `index.js` they would be in their dedicated routing file.
- **/
-
-// Return all data from API
-courses.get("/", (req, res) => {
-  res.send(courses);
-});
-
-// Return a specific value
-courses.get("/:id", (req, res) => {
-  const course = courses.find((c) => c.id === parseInt(req.params.id));
-  if (!course) res.status(404).send("A course with the given ID was not found");
-  res.send(course);
-});
-
-// Add a new course
-courses.post("/", (req, res) => {
-  const schema = Joi.object({
-    name: Joi.string().min(3).required(),
-  });
-
-  const { error } = schema.validate(req.body);
-  if (error)
-    return error.details.map((joiErr) => res.status(400).send(joiErr.message));
-
-  const course = {
-    id: courses.length + 1,
-    name: req?.body.name,
-  };
-  courses.push(course);
-  res.send(course);
-});
-
-// Update a course
-courses.put("/:id", (req, res) => {
-  const course = courses.find((c) => c.id === parseInt(req.params.id));
-
-  if (!course)
-    return res.status(404).send("A course with the given ID was not found");
-  const { error } = validateCourse(req.body);
-
-  if (error)
-    return error.details.map((joiErr) => res.status(400).send(joiErr.message));
-
-  course.name = req.body.name;
-  res.send(course);
-});
-
-// Delete a course
-courses.delete("/:id", (req, res) => {
-  const course = courses.find((c) => c.id === parseInt(req.params.id));
-  if (!course)
-    return res.status(404).send("A course with the given ID was not found");
-
-  courses.indexOf(course);
-  courses.splice(index, 1);
-
-  res.send(course);
-});
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Function_overloads.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Function_overloads.html deleted file mode 100644 index 073316e..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Function_overloads.html +++ /dev/null @@ -1,88 +0,0 @@ -Function overloads - My Zettelkasten - - - - -

Function overloads

Function overloading is not a feature of JavaScript but something close to it can be achieved with TypeScript. It proceeds by defining multiple function types (defined above the function) that may serve as the actual function’s parameters. Then with the actual function, you leave the changeable parameters open as optional unions and/or unknown :

// First oveload type:
-function logSearch(term: string, options?: string): void;
-
-// Second overload type:
-function logSearch(term: string, options?: number): void;
-
-// Implementation:
-function logSearch(term: string, p2?: unknown) {
-  let query = `https://searchdatabase/${term}`;
-  if (typeof p2 === "string") {
-    query = `${query}/tag=${p2}`;
-    console.log(query);
-  } else {
-    query = `${query}/page=${p2}`;
-    console.log(query);
-  }
-}
-
-logSearch("apples", "braeburn");
-logSearch("bananas", 3);
// First overload type:
-function logSearchUnion(term: string, options?: string): void;
-
-// Second overload type:
-function logSearchUnion(term: string, options?: number): void;
-
-// Implementation:
-function logSearchUnion(term: string, p2?: string | number) {
-  let query = `https://searchdatabase/${term}`;
-  if (typeof p2 === "string") {
-    query = `${query}/tag=${p2}`;
-    console.log(query);
-  } else {
-    query = `${query}/page=${p2}`;
-    console.log(query);
-  }
-}
-
-logSearchUnion("melon", "honey-dew");
-logSearchUnion("oranges", 4);
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Functions.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Functions.html deleted file mode 100644 index a4c86b4..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Functions.html +++ /dev/null @@ -1,63 +0,0 @@ -Functions - My Zettelkasten - - - - -

Functions

Continuing from the other examples of React Typescript, we could do standard listing function, like:

<ul>
-  {people.map((person) => {
-    return <li>{person.name}</li>;
-  })}
-</ul>

But it’s neater to do it with a function defined within the List component:

const renderList = (): JSX.Element[] => {
-  return people.map((person) => {
-    return (
-      <li>
-        <div>{person.name}</div>
-        <div>{person.age}</div>
-      </li>
-    );
-  });
-};

And then change the eariler list to a function invocation:

    <ul>{renderList()}<ul>
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Functions_in_Bash.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Functions_in_Bash.html deleted file mode 100644 index 322a54f..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Functions_in_Bash.html +++ /dev/null @@ -1,77 +0,0 @@ -Functions in Bash - My Zettelkasten - - - - -

Functions in Bash

We don’t name function parameters in the function declaration. Instead we have an implied index of arguments: $1, $2, $3,.... When the function is called, the first value after the function name becomes $1 by default, then the subsequent arguments.

function expandRange() {
-    declare -a expandedRange=()
-    for (( i=$1; i<=$2; i++ )); do
-        expandedRange+=($i)
-    done
-    echo "${expandedRange[@]}"
-}
expandedRange=$(expandRange 1 4)
-echo $expandedRange
-# 1 2 3 4

Get all arguments as an array

We can access all the arguments passed to a function using the $@ syntax we encountered before when Passing_arguments_to_Bash_scripts. (Here a function is a kind of script in miniature so the process is the same.)

function numberThings() {
-  i=1
-  for f in "$@"; do
-    echo $i: "$f"
-    (( i++ ))
-  done
-}

Local variables

var1="I'm variable 1"
-
-function myfunction() {
-  var2="I'm variable 2"
-  local var3="I'm variable 3"
-}
-
-myfunction
-echo $var1
-echo $var2
-echo $var3
-
-# I'm variable 1
-# I'm variable 2

The convention is to put functions at the top of the script, after the shebang and after the global variables

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Functions_in_Python.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Functions_in_Python.html deleted file mode 100644 index 053805c..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Functions_in_Python.html +++ /dev/null @@ -1,135 +0,0 @@ -Functions in Python - My Zettelkasten - - - - -

Functions in Python

  • Convention is to leave a double line-break after a function definition (but not with nested functions - here, a single linebreak is sufficient)
  • Scope within functions is demarcated by indents, as everything in Python
  • We use a docstring within the function body, to document our function. This text will then show up in Intellisense etc.

Basic examples


-# No params, no return
-def print_msg():
-    """ A function that prints hello world """
-    print('Hello World!')
-
-print_msg()
-# Hello World!
-
-print(type(print_msg))
-# <class 'function'>
-
-# Params, no return
-def print_my_msg(msg):
-    """ A simple function to print a message """
-    print(msg)
-
-print_my_msg('Good day')
-# Good day
-
-# Params and return
-def square(n):
-    return n * n
-
-print(square(2))
-# 4
-
-result = square(4)
-print(result)
-
-# 16
-

Default parameters

def greeter(name, message='Live Long and Prosper'):
-    print('Welcome', name, '-', message)
-
-greeter('Eloise')
-
-# Welcome Eloise - Live Long and Prosper

Optional parameters

def func_with_optional(non_optional, optional_param=None):
-  if optional_param is not None:
-    # Do something with specific value
-  else:
-    # Run standard process
-
-
-## Function with arbitrary parameter list
-
-```python
-def greeter(*args):
-    for name in args:
-        print('Welcome', name)
-
-greeter('John', 'Denise', 'Phoebe', 'Adam', 'Gryff', 'Natalia')
-
-"""
-Welcome John
-Welcome Denise
-Welcome Phoebe
-Welcome Adam
-Welcome Gryff
-Welcome Natalia
-"""

Scoping

Function variables are locally scoped by default.

They can access variables that are outer to them and can redefine them within their own scope and within the global scope using the keywords global and nonlocal.

Below a global variable is accessed and changed but only internally within a function scope

max = 100
-print('initial value of max:', max)
-
-def print_max():
-    global max
-    max = max + 1
-    print('inside function:', max)
-
-
-print_max()
-print('outside function:', max)
-
-"""
-initial value of max: 100
-inside function: 101
-outside function: 101
-"""

Below a higher-scoped variable is redefined from within the lower scope:

def myfunc1():
-  x = "John"
-  def myfunc2():
-    nonlocal x
-    x = "hello"
-  myfunc2()
-  return x
-
-print(myfunc1())
-
-# hello

We cannot however redefine a global variable from a function scope permanently. It will remain whatever it is in global scope, after the function has run.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Fundamental_Theorem_of_Arithmetic.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Fundamental_Theorem_of_Arithmetic.html deleted file mode 100644 index dd45871..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Fundamental_Theorem_of_Arithmetic.html +++ /dev/null @@ -1,50 +0,0 @@ -Fundamental Theorem of Arithmetic - My Zettelkasten - - - - -

Fundamental Theorem of Arithmetic

Every integer greater than one is either a prime number itself or is product of a unique combination of primes.

This is also known as the Unique Factorisation Theorem.

‘Unique’ means that there is not more than one way to derive the whole number. Once you reduce the factorisation to primes, there can only be one set of numbers that results in the target number.

For example, \(24\) has the following factors: \({12, 24}\) and \(6, 4\) but these are composite numbers. The unique factorisation combination for 24 is \(2, 2, 3\).

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Further_examples_of_TS_generics.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Further_examples_of_TS_generics.html deleted file mode 100644 index 92928c8..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Further_examples_of_TS_generics.html +++ /dev/null @@ -1,77 +0,0 @@ -Further examples of generics in TypeScript - My Zettelkasten - - - - -

Further examples of generics in TypeScript

Basic function

In the code below we have a simple JavaScript function that receives a value and an an array as parameters. It returns a new array comprising the original array plus the additional value:

function generateArray(existingArray, newValue) {
-  return [...existingArray, newValue];
-}

Imagine that we want to ensure that each of the parameters share the same data type. In other words: if the function is passed a string array, the second parameter must also be a string. For example, it should not be the case that you can append a string to an array of numbers.

Now imagine that we don’t know in advance what type the value or array will be, we just know that the data types of the parameters must match.

In converting the function to TypeScript, one way of overcoming our lack of foreknowledge would be to deploy any. This way it doesn’t matter which types are passed to the function:

function generateArray(existingArray: any[], newValue: any): any[] {
-  return [...existingArray, newValue];
-}

But this is no solution at all. The problem — as always with any — is that it strips our function of any type checks whatsoever and would therefore invite calls of form: generateArray([1,2,3], 'lorem').

Enter generics:

function generateArray<T>(existingArr: T[], newValue: T): T[] {
-  return [...existingArr, newValue];
-}

Now, whilst we haven’t asserted ahead of time which types will be used, whichever types we do pass in, must match. The function header is saying:

  • both arguments must be of the same type (represented by T)
  • the function will return an array of this same T type.

If I then tried to run the function with unmatched types (for example generateArray([1,2,3,4], true) ) TypeScript would raise the following error:

Argument of type 'boolean' is not assignable to parameter of type 'number'

Note that even though the function in question does not express any preference for number types, given that our first parameter is a number, TypeScript knows that the second parameter must also be a number.

In the generic function we have used T as our placeholder for a generic type as this is the convention. However there is no compunction to do so. We could have used any letter or string, providing that the string is not a reserved term.

More advanced function

This example demonstrates how we can use generics to reduce repetition when writing functions and is also a more realistic use case.

Let’s say we have two types or interfaces:

type VideoFormatUrls = {
-  format720p: URL;
-  format1080p: URL;
-};
type SubtitleFormatUrls = {
-  english: URL;
-  german: URL;
-};

An example of an object matching these type definitions:

const videoFormats: VideoFormatUrls = {
-	format720p: https://www.format720p.co.uk,
-	format1080p: https://www.format1080p.co.uk
-}

Imagine we wanted to be able to check whether a given film is available in a certain video format. We could write a function like this:

function isFormatAvailable(
-  obj: VideoFormatUrls,
-  format: string
-): format is keyof VideoFormatUrls {
-  return format in obj;
-}

Now imagine that we need to do the same thing with subtitles, but given that isFormatAvailable() is typed to the VideoFormatUrls type we would get an error if we used this function for subtitles. But we also don’t want to write a near identical function typed to SubtitleFormatUrls to subtitles just to ensure adequate type safety.

Alternatively we could use a union type, for example:

function isFormatAvailable(
-  obj: VideoFormatUrls | SubtitleFormatUrls,
-  format: string
-): format is keyof VideoFormatUrls {
-  return format in obj;
-}

But this quickly becomes unwieldy if we, for the sake of argument have a great many URL types that we want the function to utilise.

This is where generics become super helpful. Here is how we would rewrite the function as a generic:

function isAvailable<Formats>(obj: Formats, key: string): key is keyof Formats {
-  return key in obj;
-}

We could then explicitly type our calls of this function, viz:

isFormatAvailable<SubtitleFormatUrls>(subtitles, "english");
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/GPU_versus_CPU.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/GPU_versus_CPU.html deleted file mode 100644 index 42783e5..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/GPU_versus_CPU.html +++ /dev/null @@ -1,50 +0,0 @@ -GPU versus CPU - My Zettelkasten - - - - -

GPU versus CPU

  • GPU stands for Graphics Processing Unit. Originally designed for rendering graphics and video but now used for other applications of parallel computing eg. machine learning.

  • The standard CPU uses sequential processing whereas the GPU is designed for parallel processing, specialising in performing many simple calculations simultaneously.

  • Harnessing the GPU requires specialised programming approaches.

  • Most standard laptops and desktops (if they are not designed for graphically-intensive tasks) incorporate graphics processing within the CPU. The CPU chip is on the same chip as the CPU chip. This is called integrated graphics processing.

  • Some laptops, especially those marketed for gaming or professional work, have a separate GPU chip. This is a more powerful graphics processor, separate from the CPU.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Generics_in_TypeScript.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Generics_in_TypeScript.html deleted file mode 100644 index 713c17a..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Generics_in_TypeScript.html +++ /dev/null @@ -1,167 +0,0 @@ -Generics - My Zettelkasten - - - - -

Generics

Generics are a powerful feature in TypeScript that enables you to write reusable and flexible code while maintaining strong typing. With generics, you can create functions, classes, and interfaces that work with various types while preserving type information.

The main purpose of generics is to allow developers to write code that can operate on different data types without knowing the specific type beforehand. This helps to keep the code DRY and maintainable.

Basic usage

Functions

function identity<T>(arg: T): T {
-  return arg;
-}

Here, T is a generic type variable. The identity function is a generic function that takes an argument of type T and returns a value of type T.

To use this generic function you can either explicitly provide the type within the angle brackets, or let TypeScript infer the type based on the value passed:

// Explicitly specifying the type
-let output1 = identity<string>("hello");
-
-// TypeScript infers the type as `number`
-let output2 = identity(42);

Restricting the available types

In the previous example any type could be used with the identity function. The only constraint that we place on usage is that the types must be consistent: if we pass a string as an argument, then a string must be returned.

However we can add further restrictions on types by using the extend keyword, combined with an interface.

interface Lengthwise {
-  length: number;
-}
-
-function logLength<T extends Lengthwise>(arg: T): T {
-  console.log(arg.length);
-  return arg;
-}

In this example the logLength generic function is limited to types that implement the Lengthwise interface. So: any argument that is passed to logLength and any value that is returned by it must match the shape of Lengthwise, having the length property.

Interfaces and classes

Generics can also be used profitably when working with stricter OOP constructs.

interface KeyValuePair<K, V> {
-  key: K;
-  value: V;
-}

The KeyValuePair interface has two generic type parameters: K for the key and V for the value. The interface defines an object shape that must possess the properties key and value, e.g:

{
-  key: 2,
-  value: 'something'
-}

In this form the generic specifies that whatever types are used for the key and the pair must be used consistently, e.g. this would be wrong:

{
-  key: 'age',
-  value: 32
-}

The following class uses the KeyValuePair interface:

class Storage<K, V> {
-  private items: KeyValuePair<K, V>[] = [];
-
-  add(item: KeyValuePair<K, V>): void {
-    this.items.push(item);
-  }
-
-  getByKey(key: K): V | undefined {
-    const foundItem = this.items.find((item) => item.key === key);
-    return foundItem ? foundItem.value : undefined;
-  }
-
-  getAll(): KeyValuePair<K, V>[] {
-    return this.items;
-  }
-}

This class stores objects that match the KeyValuesPair interface in an array and provides and add and list method for accessing/returning them.

The add method takes an item of type KeyValuePair<K, V> and adds it to the items array. The getByKey method takes a key of type K and returns the value of type V associated with that key or undefined if the key is not found. The getAll method returns all stored key-value pairs.

Here is an example of instantiating the class:

const storage = new Storage<number, string>();
-
-storage.add({ key: 1, value: "one" });
-storage.add({ key: 2, value: "two" });
-
-const value = storage.getByKey(1);
-const allItems = storage.getAll();
-
-console.log(value);
-// value: "one"
-
-console.log(allItems);
-
-// allItems: [
-//   { key: 1, value: "one" },
-//   { key: 2, value: "two" }
-// ]

Real examples

GraphQL client for query and mutation requests over fetch

type GraphQlResult<T> = {
-  data: T;
-  errors?: Array<{
-    message: string;
-    locations: Array<{ line: number; column: number }>;
-    path: Array<string | number>;
-  }>;
-};
-
-export class GraphQlClient {
-  private endpoint: string;
-
-  constructor(endpoint: string) {
-    this.endpoint = endpoint;
-  }
-  async request<T>(
-    query: string,
-    variables?: Record<string, unknown>
-  ): Promise<T> {
-    try {
-      const response = await fetch(this.endpoint, {
-        method: "POST",
-        headers: {
-          "Content-Type": "application/json",
-        },
-        body: JSON.stringify({ query, variables }),
-      });
-
-      if (!response.ok) {
-        throw new Error(
-          `Network error: ${response.status} - ${response.statusText}`
-        );
-      }
-
-      const result: GraphQlResult<T> = await response.json();
-
-      if (result.errors) {
-        throw new Error(`GraphQL error: ${JSON.stringify(result.errors)}`);
-      }
-
-      return result.data;
-    } catch (error) {
-      console.error(error);
-      throw error;
-    }
-  }
-}

VSCode extension TreeView generator

In VSCode a TreeView is a list of values that may have nested values, like a directory. The following generic is a helper function that generates a TreeView based on a given class that is passed in as an argument, along with the class’s constructor values (args in the example). It also calls a method refresh on each instance of the class.

function createTreeView<
-  T extends IndexHyperlinksProvider | IndexMetadataProvider,
-  U extends LinkTypes | MetadataTypes
->(
-  viewType: string,
-  ProviderClass: new (...args: any[]) => T,
-  type: U,
-  activeEditor?: string | undefined,
-  ...args: ConstructorParameters<typeof ProviderClass>
-): T {
-  const view = new ProviderClass(...args, type);
-  if (view instanceof IndexHyperlinksProvider) {
-    view.refresh(activeEditor, type as LinkTypes);
-  } else if (view instanceof IndexMetadataProvider) {
-    view.refreshIndex();
-  }
-  vscode.window.registerTreeDataProvider(viewType, view);
-  return view;
-}
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Git_bisect.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Git_bisect.html deleted file mode 100644 index 6681c15..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Git_bisect.html +++ /dev/null @@ -1,54 +0,0 @@ -Bisect - My Zettelkasten - - - - -

Bisect

Bisect can be used to identify commits that introduce a bug or regression in our code.

It is most useful for when we know there is a problem in the code and we know there was a point in the past where the bug did not exist. We can compare the two points and try to identify where things went wrong.

We mark the last good revision and the first bad revision. Bisect will the reset the code to the midpoint between the good and bad versions and let you test it. You mark that as a good or bad version and then bisect repeats the process.

Procedure

git bisect start
-
-git bisect good <SHA, tag, branch>
-
-git bisect bad <SHA, tag, branch>
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Git_rebasing.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Git_rebasing.html deleted file mode 100644 index b380b53..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Git_rebasing.html +++ /dev/null @@ -1,72 +0,0 @@ -Rebasing - My Zettelkasten - - - - -

Rebasing

Rebasing is a way to integrate changes from one branch into another. In this regarding it is like merging a branch B into another branch A. However rebasing differs from normal merging in the way in which it modifies the Git history.

In a normal merge of branch B into branch A, Git creates a new commit that combines the changes of branches B and A. This is known as the merge commit and is evident from the following automatic commit message that is generated:

Merge branch B of github.com:thomasabishop/remote-repository into A

In this scenario the merge commit has two or more parent commits each representing the history of the merged branches. The resulting history of A will include the commits of B. Basically the two histories are combined.

This would give us a history that looks like the following, with different colours for the separate SHAs of each merged branch:

If we were to create a rebase branch of A from B, there would be a new singular history without distinguishing multiple parents that combines the commits of A and B. The rebased branch’s commits are recreated with new commit IDs and new timestamps, based on the current state of the branch that you are rebasing onto. This is obviously potentially destructive because it does not preserve the respective branch’s separate history. It rewrites history as a continuous stream of commits in a single branch.

When a rebase is applied, it will put the diverging B commits at the tip of A like so:

And then rebrand the previous A commits to be continuous with B presenting a flat and linear Git history like the following:

Benefits, use-cases

The purpose of rebasing is to ensure that the commit history of a project is as linear and simple as possible, by incorporating changes from one branch into another, as if the changes had been made on the other branch all along.

A common use-case is with feature branches as it makes the features fit more seamlessly with the main or develop branch.

It is also a technique that can be used to integrate recent commits without merging.

When to use one over the other:

  • Merge to allow commits to stand out or to be clearly grouped
  • Merge to bring large feature branches back into main
  • Rebase to add minor commits in a main branch into a feature branch
  • Rebase when you need to move commits from one branch to another

So in terms of my personal workflow, I should be using

  • Merge when I want to bring a feature into develop
  • Merge when I want to bring develop into main for a release
  • Merge any time the feature branch is already public and being used by others.
  • Rebase to capture small changes in the parent branch
  • Rebase when I have branched from a branch because a refactor or something has become more complex than originally anticipated.

Syntax

For example if we are working on a feature branch off of main, we would run the following from this feature branch:

git rebase main

This will move the feature branch to the tip of main.

If this completes successfully, we would then go on to merge the feature with main.

If conflicts occur, the rebase will halt. You fix the conflicts and then run:

git rebase --continue

Or if you don’t want to resolve the conflict (not advised):

git rebase --skip

Or stop the whole process:

git rebase --abort

Isolate the point at which one branch diverges from another

This can be useful to check before you create a rebase:

git merge-base main feature/some-feature
-
-c33acc84f06fcb94e0e87d9adb240c038da6d71c

Golden rule of rebasing

When we rebase we remove the additional merge commit but we are changing history. The commits are still there but the SHAs are changed. For this reason you should not rebase a public branch, otherwise you will mess up your collaborators history. You should do your rebasing locally and then make a pull request.

Difference from cherry-picking

The main difference between the two approaches is that Cherry_picking_a_branch is a more selective process, where you can pick and choose specific commits that you want to include in another branch. This can be useful when you only want to apply specific changes or fixes from one branch to another, without including all the changes made in the original branch.

On the other hand, rebasing is a more comprehensive process that can include all the changes from one branch to another, but it modifies the commit history, making it more linear and easier to understand. Unlike rebasing, cherry-picking does not modify the commit history of either branch.

Squashing commits

This is a handy feature of rebasing. It allows you to combine multiple commits into one. This is useful when you have been doing a lot of trial and error to resolve a bug and you have lots of small commits that are not that important in themselves.

We use the interactive rebase tool for this.

Checkout the branch where the commit you want to squash is located.

Then run:

git rebase -i HEAD~n

Where n is the number of commits you want to squash starting from the most recent. This will open an interactive rebase window, listing the commits. You can then use the keywords to decide what you want to do with them. In our case this will be s for squash.

Example

I made a small fix commit because something went wrong during build. I do not want this commit to be in the history because it is so minor. Instead I want to incorporate these changes into the last public commit.

Trivial commit is xy Previous commit is aa

git rebase -i HEAD~2

This displays:

pick xy
-pick aa

Change this to:

pick xy
-squash aa

Now xy == aa

Another example

Here we will rebase the interim commits into the last feature commit

git rebase -i HEAD~10
pick a691a7667 feature (shared-nav) add active app check
-pick 74a07fdb1 interim: add logging
-pick 9af4e2652 interim: more logging
-pick 51b36f667 interim: use href not origin
-pick 33f161198 interim : try catch handler
-pick 41c144ddf interim: remove didLoadCheck
-pick ebd1c9f24 interim: fix flash star
-pick 77af452e7 interim: rm redundant active app check
-pick 79a9b737a iterim: test ternary
-pick a90d23223 interim: further tidying
pick a691a7667 feature (shared-nav) add active app check
-squash 74a07fdb1 interim: add logging
-squash 9af4e2652 interim: more logging
-squash 51b36f667 interim: use href not origin
-squash 33f161198 interim : try catch handler
-squash 41c144ddf interim: remove didLoadCheck
-squash ebd1c9f24 interim: fix flash star
-squash 77af452e7 interim: rm redundant active app check
-squash 79a9b737a iterim: test ternary
-squash a90d23223 interim: further tidying

git pull rebase

We can use this command to combine a rebase with a pull. This way we silently update our local version of a branch with the remote, without adding a merge commit.

git pull --rebase

Add --rebase=preserve to keep merges that have been done locally. It is generally a good idea to do this.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Global_object_in_NodeJS.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Global_object_in_NodeJS.html deleted file mode 100644 index e083ff4..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Global_object_in_NodeJS.html +++ /dev/null @@ -1,50 +0,0 @@ -Global object - My Zettelkasten - - - - -

Global object

In Node every function and variable should be scoped to a module. We should not define functions and variables within the global scope.

  • In Node the equivalent to the browser’s Window object is global. The properties and methods that belong to this method are available anywhere in a program.

  • Just as we can technically write Window.console.log(), we can write global.console.log() however in both cases it is more sane to use the shorthand.

  • However if we declare a variable in this scope in browser-based JavaScript, this variable becomes accessible via the Window object and thus is accessible in global scope. The same is not true for Node. If you declare a variable at this level it will return undefined.

  • This is because of Node’s modular nature. If you were to define a function foo in a module and then also define it in the global scope, when you call foo, the Node interpreter would not know which function to call. Hence it chooses not to recognise the global foo, returning undefined.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Grep.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Grep.html deleted file mode 100644 index 6ec95c6..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Grep.html +++ /dev/null @@ -1,50 +0,0 @@ -Grep - My Zettelkasten - - - - -

Grep

Purpose of grep

grep stands for “global regular expression print”. It allows you to search plain text data sets for strings which match a regular expression or pattern.

Syntax

Schematic

grep [options] [pattern] [source file] > [output file]

Note that above we redirect the file matches to a new file. You don’t have to do this. If you omit the redirection, grep will output to standard output.

Applied

grep -i -n "banana" fruits.txt > banana.txt

The above example searches, using regex, for strings matching the pattern “banana” in the file fruits.txt regardless of the character case (-i ensures this) and outputs its findings to the file banana.txt, with the line number where the match occurs appended to the output (-n takes care of this).

Note that for simplicity, you can chain optional values together, i.e. the options in the above example could be input as -in.

Useful options

  • ignore case: i
  • count matches instead of returning actual match: -c
  • precede each match with the line number where it occurs: -n
  • invert the match (show everything that doesn’t match the expression): -v
  • search entire directories recursively: -r
  • list file names where matches occur (in the scenario of a recursive match): -l

ripgrep

ripgrep is generally faster however it does not come as default with Unix and only works recursively, i.e. it is designed to find strings within files within multiple directories not just single files or piped streams.

It also respects .gitignore files that it finds within directories by default and node_modules which is really handy.

Most of the standard grep options transfer over.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Ground.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Ground.html deleted file mode 100644 index 8bb33eb..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Ground.html +++ /dev/null @@ -1,51 +0,0 @@ -Ground - My Zettelkasten - - - - -

Ground

The term ‘ground’ is used as a general reference for ‘zero potential’: the point in an electrical circuit where there is no potential difference between the positive and negative terminals of the voltage source.

As a consequence of the lack of potential, ground is a point at which no current can be generated.

The term originates from domestic electrical systems where the circuit box is literally attached to the ground (represented by the green and yellow ribboned wires in plug sockets and light fixtures etc) where current is discharged to prevent appliances emitting electrical shocks.

In circuit diagrams with simple DC current, ground is taken to be the negative terminal of the voltage source.

The symbol for ground in circuit diagrams:

-
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Guide_to_YAML.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Guide_to_YAML.html deleted file mode 100644 index 63500a7..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Guide_to_YAML.html +++ /dev/null @@ -1,78 +0,0 @@ -Guide to YAML - My Zettelkasten - - - - -

Guide to YAML

  • Data description language
  • Alternative to XML and JSON
  • Easy to read by humans and process by code

Main rule

Never use tabs for indentation, use two spaces

Available data types

  • strings
  • numbers
  • booleans
  • arrays
  • maps (key, value pairs)

Example

# Basic scalar data types
-age: 51
-greeting: Hello, world
-length: 182.3
-happy: true
-``
-
-```yaml
-# array
-pets:
-  - cat
-  - dog
-
-# nested array
-pets:
-  - cat
-  - dog
-    - staffy
-    - pitty
# map
-languages:
-  - java: advanced
-  - python: average
-  - javascript: basic

Strings

  • Don’t have to use quotes unless string contains reserved YAML characters (dashes, colons etc)
  • Can use single or double quotes

Multi-line text

Two methods:

# Literal block preserves new line characters
-literal_block: |
-  Lorem ipsum dolar sit avcc lorem dolar 
-  Blah blah
-  Blah
folded_block: >
-  Each different line will be folded back on itself so you don't have to keep
-  scrolling to the right
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/HTTP_request_types.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/HTTP_request_types.html deleted file mode 100644 index e126d6c..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/HTTP_request_types.html +++ /dev/null @@ -1,50 +0,0 @@ -HTTP request types - My Zettelkasten - - - - -

HTTP request types

GET

  • Get data

POST

  • Create data

PUT

  • Update data

DELETE

  • Remove data
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Half_adder_and_full_adder.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Half_adder_and_full_adder.html deleted file mode 100644 index eed3122..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Half_adder_and_full_adder.html +++ /dev/null @@ -1,60 +0,0 @@ -The half adder and full adder - My Zettelkasten - - - - -

The half adder and full adder

Binary arithmetic

The half adder and full adder are components of digital circuits that enable us to carry out binary addition. Using adders and half adders we can add two binary numbers together. Adders are a type of integrated circuit comprising certain logic gates where the arrangement allows for the representation of the addition of bits.

Example addition

Consider the following binary addition:

  c_1
-0   0   1   0
-0   0   1   1
-_____________
-0   1   0   1

How does the calculation proceed? Moving from the right-most column:

  • \(1 + 0 = 1\) hence the sum of the first column (the binary 1 coumn) is \(1\) with no carry
  • Moving to the second column (the binary 2 column), \(1 + 1 = 2\) however we do not have the digit “2” in binary, therefore we must bump the place value by one place and carry this sum as a \(1\) leaving a zero to mark the place value
  • Thus the third column (the binary 4 column) has the calculation: \(1 + 0 + 0 = 1\) with no carry.

Bits

From the previous example we can identified the following repeated actions:

  • For calculations of the form \(1 + 0\) or \(0 + 0\) there will be no carried digit
  • For calculations of the form \(1 + 1\) there will be a carried digit

In the context of adders the digits are bits. We distinguish three core bits by their role in the calculation: the carry, the least significant bit and the most significant bit. The least significant bit is the right-most digit in the calculation. The most significant bit is the leftmost.

The two types of adders are distinguished by which bits of the calculation they operate on. The half adder focuses on the least significant bit whereas the full adder focuses on the most significant bit.

Half adder

The half adder receives two bits (A and B) which are to be added together. It outputs this value as the sum bit. If there is a bit to be carried to the next column in the binary calculation this will be output as the carry-out bit.

ABSC_out
The first number to be addedThe second number to be addedThe sum bitThe carry-out bit

The diagram below shows the circuit representation of a half-adder and an example calculation. This calculation matches the ones column of the earlier binary addition example: \(0011 + 0010\).

Implementation with logic gates

If we think about it, the possible inputs and outputs of a half adder are highly circumscribed:

  • If the sum exceeds \(1\), the sum bit will be \(0\) and the carry-out bit will be \(1\)
  • In all other cases the carry-out bit will be \(0\). These other cases are when the sum bit is either \(0\) or \(1\), e.g: \(1 + 0\) or \(0 + 0\).

We can represent this with a simple truth-table:

ABSC_out
0000
0110
1010
1101

We can see that the sum bit column replicates the truth-conditions of XOR:

PQP V Q
TTF
TFT
FTT
FFF

And the carry-out bit replicates the truth conditions of AND:

PQP & Q
TTF
TFF
FTF
FFT

It is therefore possible to implement a half-adder with just these two logic gates:

The digital circuit above has the same inputs and outputs as the half adder diagram above.

-

Full adder

As the half adder only calculates the least significant bit, it is not sufficient by itself to complete a binary addition; it cannot account for movements in binary place value. To carry out full calculations it must be supplemented with the full adder.

The full adder takes in three inputs and has two outputs. It is identical to the half-adder apart from the fact that one of its inputs is carry-in. This is equivalent to the value that is designated as carry-out in a half adder. It is an incoming value that is the product of a previous operation that resulted in a carry-out. This is added together with the full adders own two inputs (A and B) and like the half adder, generates a sum bit and a carry-out bit.

ABC_inSC_out
The first number to be addedThe second number to be addedThe incoming carried bitThe sum bit (A+B+C_in)The carry-out bit (A+B+C_in)

The diagram above is equivalent to the calculation taking place in the fours column. It has received a carry from the twos column (\(1 + 1\) results in \(1\) as a carry) and then adds this together with its own inputs (\(0\) and \(0\)).

  c_1
-0   0   1   0
-0   0   1   1
-_____________
-0   1   0   1

Implementation with logic gates

When it comes to implementing the full adder with logic gates we can allow ourselves greater abstraction as we already have the half adder to work with. We don’t need to create a half adder from scratch, we can reuse it.

We are adding three bits: \(1\), \(0\) and \(0\). This can be achieved with two half adders:

  • One half adder (HA1) for the sum of \(0 + 0\)
  • One half adder (HA2) for the sum of \((0 + 0) + 1\) (the previous sum plus the third bit)

The sum of HA1 (\(0 + 0\)) is passed in to the B input on HA2 and the \(1\) is passed in as the A input of HA2. This gives us \(1\) as the sum bit of HA2.

At this point we have completed the addition and have successfully added the three bits: \(1\), \(0\), and \(0\) to get \(1\) as ths sum. However we also have to account for the fact that the addition may result in its own carry-out bit. What if the inputs were \(1, 1, 0\) for example?

-
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Handle_multiple_endpoints_single_lambda.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Handle_multiple_endpoints_single_lambda.html deleted file mode 100644 index 93addcb..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Handle_multiple_endpoints_single_lambda.html +++ /dev/null @@ -1,116 +0,0 @@ -Handle multiple API Gateway endpoints in a single lambda - My Zettelkasten - - - - -

Handle multiple API Gateway endpoints in a single lambda

With the following config we have a single lambda (/query-waktime) with multiple endpoints:

Resources:
-  QueryWakatimeFunction:
-    Type: AWS::Serverless::Function
-    Properties:
-      CodeUri: src/query-wakatime/
-      Handler: index.handler
-      Events:
-        MainMetrics:
-          Type: Api
-          Properties:
-            Path: /query-wakatime/main-metrics
-            Method: get
-            Auth:
-              Authorizer: AWS_IAM
-        Durations:
-          Type: Api
-          Properties:
-            Path: /query-wakatime/durations
-            Method: get
-            Auth:
-              Authorizer: AWS_IAM
-        TodayOnly:
-          Type: Api
-          Properties:
-            Path: /query-wakatime/today-only
-            Method: get
-            Auth:
-              Authorizer: AWS_IAM

Our endpoints are as follows:

  • /query-wakatime/main-metrics
  • /query-wakatime/durations
  • /query-wakatime/today-only

Each returns a different dataset from an external API. The lambda function makes a different request to the API based on the endpoint it receives and the time period that is passed as a query string parameter, e.g. /query-wakatime?range=last_7_days.

Below is a template for concisely handling requests to the different endpoints in the single lambda function wihout excessive repetition.

const getEndpoint = (path: string, timePeriod?: string | undefined) => {
-  const basePath = "/users/current";
-  switch (path) {
-    case "/query-wakatime/main-metrics":
-      return `${basePath}/stats/${timePeriod}`;
-    case "/query-wakatime/durations":
-      return `${basePath}/summaries?range=${timePeriod}`;
-    case "/query-wakatime/today-only":
-      return `${basePath}/status_bar/today`;
-  }
-};
-
-export const handler = async (event) => {
-  const fetchClient = new FetchClient("https://wakatime.com/api/v1/");
-  const path = event.path;
-  const timePeriod = event.queryStringParameters?.timePeriod;
-  const endpoint = getEndpoint(path, timePeriod);
-
-  const init: RequestInit = {
-    headers: {
-      Authorization: `Basic ${encodedApiKey}`,
-    },
-  };
-
-  if (!endpoint) {
-    throw new Error("Endpoint is undefined")
-  }
-
- let data = await fetchClient.get(endpoint, init)
- let dataJson = (await data.json()) as string
-
- response = {
-    statusCode: 200,
-    body: JSON.stringify(dataJson),
-    headers: responseHeaders,
-    }
-};
-
-
-
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Handling_negative_fractions.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Handling_negative_fractions.html deleted file mode 100644 index 2e54495..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Handling_negative_fractions.html +++ /dev/null @@ -1,52 +0,0 @@ -Negative fractions - My Zettelkasten - - - - -

Negative fractions

To work with negative fractions we draw on the Rules for operations on like and unlike terms.

Fractions with unlike terms

  • A fraction is just one number divided by another. \(\frac{5}{10}\) is just ten divided by 5.

  • A positive integer divided by a negative or vice versa will always result in a negative. Thus \(\frac{5}{-15}\) is equal to \(-3\).

  • We can therefore express the whole fraction as a negative:

    $$

    • \frac{5}{15} $$
  • Or we could apply the negative symbol to the numerator. It would stand for the same value: $$ -\\frac{-5}{15} -$$

Therefore:

Let \(a,b\) be any integers. The following three fractions are equivalent: $$\frac{-5}{15}, \frac{5}{-15}, - \frac{5}{15}$$

Fractions with like terms

  • In cases where both the numerator and denominator are both negative, the value that the fraction represents will be positive overall. This is because the quotient of a negative integer divided by a negative integer will always be positive.

  • Thus: $$ \frac{- 12xy^2}{ - 18xy^2} = \frac{12xy^2}{18xy^2}$$

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Hardware_Description_Language.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Hardware_Description_Language.html deleted file mode 100644 index a14d1e0..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Hardware_Description_Language.html +++ /dev/null @@ -1,72 +0,0 @@ -Hardware Description Language - My Zettelkasten - - - - -

Hardware Description Language

An HDL is a declarative programming language used to describe the behaviour or structure of digital circuits. They are used to simulate the circuit and check its response.

The hardware designer specifies a chip’s logic by writing an HDL program which is then rigorously tested. At this stage, a hardware simulator takes the HDL program as input and creates a software representation of the chip logic. The designer can instruct the simulator to test the virtual chip on various sets of inputs. This is done to check the chip’s functionality but also to benchmark a variety of other parameters such as speed of computation and energy consumption.

There are many HDLs but the most popular are VHDL (“very high speed integrated-circuit description language”) and Verilog.

Usage in NAND to Tetris

We won’t use an actual HDL language, instead we will use a simplified toy language called HDL that is simple enough that when it is used with a simulator, we can learn the main facets of chip design. Its syntax is very similar to VHDL.

Demonstration of HDL program

Boolean function to enact

We will create an HDL program for an XOR gate that is implemented through the following arrangement of NOT, AND, and OR gates:

HDL file (Xor.hdl):

Here is our HDL file:

/* Xor gate
-   If a!=b out=1 else out=0
-*/
-CHIP Xor {
-  IN a, b;
-  OUT out;
-  PARTS:
-  Not (in=a, out=nota);
-  Not (in=b, out=notb);
-  And (a=a, b=notb, out=w1);
-  And (a=nota, b=b, out=w2);
-  Or  (a=w1, b=w2, out=out)
-}

Interface (CHIP, IN, OUT)

At the top level of the HDL program, the CHIP name and IN/OUT declaration is the interface of the chip. Here we specify our naming convention for the IN and OUT values which we will refer to in the implementation declaration in PARTS.

Implementation (PARTS)

Everything under the PARTS section is the chip implementation. We can draw on composite gates in the PARTS declaration (e.g. Not, And, Or). The convention is to work from left to right when transcribing from a digital circuit diagram

Pins

In an HDL program we distinguish internal pins along with the standard input and output pins. At the level of the interface, we are concerned only with input and output pins (in the example program these are a, b and out). It is at the level of the implementation that internal pins are encountered. In the example these are the connections between, e.g. the AND and NOT gates such as And (a=a, b-notb, out=w1). This means the AND gate is receiving through its a pin the input a value and through its b pin the value of b inverted by a NOT. out is the value that is computed based on the input pins of a and b.

Test file (Xor.tst)

Along with the HDL file we also create a test file. This runs the chip against the inputs we supply, these will typically be equivalent to the (left-hand) truth-values column in a truth table which is the same as the parameters passed to a Boolean function, for example:

load Xor.hdl
-output-list a, b, out;
-set a 0, set b 0, eval, output;
-set a 0, set b 1, eval, output;
-set a 1, set b 0, eval, output;
-set a 1, set b =, eval, output;

Output file (Xor.out)

When the test file is run against the HDL file it will generate an output file. This is effectively the result of the unit test. And will take the form of a truth table:

a | b | out
------------
-0 | 0 | 0
-0 | 1 | 1
-1 | 0 | 1
-1 | 1 | 0
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Hardware_abstraction_and_modularity.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Hardware_abstraction_and_modularity.html deleted file mode 100644 index bb3b7e7..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Hardware_abstraction_and_modularity.html +++ /dev/null @@ -1,56 +0,0 @@ -Hardware abstraction and modularity - My Zettelkasten - - - - -

Hardware abstraction and modularity

In computer architecture we deal with complexity by breaking the system into modules. For each module we distinguish abstraction from implementation.

-
abstraction
-
what the module does
-
implementation
-
how it does it
-
-

When using a module as a building block you are to focus exclusively on the module’s abstraction, ignoring completely its implementation details.

The abstraction-implementation paradigm helps developers manage complexity and maintain sanity: by dividing an overwhelming system into well-defined modules we create manageable chunks of implementation work and localize error detection and correction.

[N.Nisan, S.Schoken. 2021. The Elements of Computing Systems (Second Edition)]

The design of the diagram below emphasises the role of abstraction and modularity in the movement from transistors to chips:

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Hardware_simulation.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Hardware_simulation.html deleted file mode 100644 index b056ae1..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Hardware_simulation.html +++ /dev/null @@ -1,60 +0,0 @@ -Hardware simulation - My Zettelkasten - - - - -

Hardware simulation

In order to test our HDL files we load them into the hardware simulator program. We will demonstrate this with the following XOR implementation:

There are several simulation options:

  • interactive
  • script-based (where we load a test script into the simulator along with the HDL file
  • comparative (running the HDL program against our intended output specified in the .cmp file)

The use-cases for each mode are based on the complexity of the chip you are evaluating. For a small chip, interactive and script-based testing would be sufficient but for much larger components like an ALU a comparative approach would be more manageable and efficient.

Interactive

The image below shows a basic interactive usage of the simulator. We have uploaded the Xor.hdl file into the simulator and changed the input pins to a=1, b=0 and clicked the calculator icon (representing “evaluation”). This then shows the output and internal pin values for these inputs.

-

Script-based

This time we have clicked the script icon to load Xor.tst. This loads the test script into the main GUI panel on the left. We can step through each line of the test file and we will see the pin values update in accordance with the test.

When this is run it automatically generates an output file in the source directory at Xor.out. This can be viewed within the simulator via the ‘View’ drop down.

Comparison-based

With a comparison-based approach to chip testing we run a comparison against the .out file that the simulator generates when running the HDL program against a .cmp comparison file that we provide. Both are simply truth-tables. For XOR if the program matched the comparison specification both Xor.out and Xor.cmp would look like the following:

a | b | out
------------
-0 | 0 | 0
-0 | 1 | 1
-1 | 0 | 1
-1 | 1 | 0

You don’t have to do anything to apply the comparison since the compare file will already be loaded as part of the test file’s set up:

load Xor.hdl
-output file Xor.out
-compare-to Xor.cmp
-output-list a, b, out;
-set ...
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Headless_Raspi_network_setup.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Headless_Raspi_network_setup.html deleted file mode 100644 index 54a1eb2..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Headless_Raspi_network_setup.html +++ /dev/null @@ -1,58 +0,0 @@ -Headless network setup - My Zettelkasten - - - - -

Headless network setup

If you are using a headless system and you aren’t using an ethernet connection, you face a chicken-egg issue of how to connect the device to WiFi via ssh when the device isn’t yet on the network.

You can get around this by saving a file called wp_supplicant.conf to the /boot directory of the device. This specifies the SSID name and password and will be used to auto-connect when the device boots.

For example:

country=GB
-ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
-update_config=1
-network={
-     ssid="SKYVL7XP"
-     scan_ssid=1
-     psk="WIFI_PASSWORD"
-     key_mgmt=WPA-PSK
-}
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Heap_memory.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Heap_memory.html deleted file mode 100644 index 9bfe1b0..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Heap_memory.html +++ /dev/null @@ -1,51 +0,0 @@ -Heap memory - My Zettelkasten - - - - -

Heap memory

Along with Stack memory, programs make use of heap memory during runtime.

Heap memory does not use a standardised data structure and can be accessed from any point within the program.

Whereas stack memory with it’s LIFO structure has memory management built-in when programs allocate memory from the heap they must manually deallocate it when it is no longer required. This process of “freeing memory” is known as garbage collection. In a language like C, this is the explicit concern of the programmer and is not abstracted away. Failure to properly manage garbage collection is what causes Memory leaks.

Heap memory is used in combination with the stack since a given heap memory allocation address is stored as a stack variable during runtime. It points to the heap memory address whilst not being that memory itself.

Here is an example of managing heap memory allocation in C:

void * data;
-data = malloc(512)

The first line assigns a special pointer variable (indicated by void * rather than int or str) . This is a variable only holds a memory address. The malloc method requests 512 bytes that it wants to assign to the data variable. It will return the address of the first byte in the newly allocated memory. data will then refer to the address on the stack that holds the address allocation on the heap.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Hexadecimal_number_system.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Hexadecimal_number_system.html deleted file mode 100644 index 20279f3..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Hexadecimal_number_system.html +++ /dev/null @@ -1,59 +0,0 @@ -Hexadecimal number system - My Zettelkasten - - - - -

Hexadecimal number system

Hexadecimal is the other main number system used in computing. It works in tandem with the binary number system and provides an easier and more accessible means of working with long sequences of binary numbers.

Hexadecimal place value

Unlike denary which uses base ten and binary which uses base two, hexadecimal uses base 16 as its place value.

Each place in a hexadecimal number represents a power of 16 and each place can be one of 16 symbols.

Hexadecimal values

The table below shows the symbols comprising hexadecimal alongside their denary and binary equivalents:

HexadecimalDecimalBinary
000000
110001
220010
330011
440100
550101
660110
770111
881000
991001
A101010
B111011
C121100
D131101
E141110
F151111

This table shows the raw value of each hexadecimal place value:

\(16^{3}\)\(16^{2}\)\(16^{1}\)\(16^{0}\)
4096256161

Hexadecimal prefix

The custom is to prefix a hexadecimal number with 0x to indicate that the number is hexadecimal.

Converting hexadecimal numbers

Using the previous table we can convert hexadecimal values to decimal.

For example we can convert 1A5 as follows, working from right to left:

\((5 \cdot 1 = 5) + (A \cdot 16 = 160) + (1 \cdot 256 = 256) = 421\)

The process is quite easy: we get the n from \(16^{n}\) based on the position of the digit and then multiply this by the value of the symbol (1,2,…F):

$$ -16^{n} \cdot 1,2,...F -$$

As applied to 0x1A5:

\(16^{3}\)\(16^{2}\)\(16^{1}\)\(16^{0}\)
\(1\cdot 16^{3} = 4096\)\(1\cdot 16^{2} = 256\)\(A (10)\cdot 16^{1} = 160\)\(5\cdot 16^{0} = 5\)

Another example for 0xF00F:

\((15 \cdot 4096 = 61440) + (0 \cdot 256 = 0) + (0 \cdot 16 = 0) + (15 \cdot 1 = 15) = 61455\)

Using hexadecimal to simplify binary numbers

Whilst computers themselves do not use the hexadecimal number system (everything is binary), hexadecimal offers advantages for humans who must work with binary:

  1. It is much easier to read a hexadecimal number than long sequences of binary numbers
  2. It is easier to quickly convert binary numbers to hexadecimal than to convert binary numbers to decimal

Look at the following equivalences

Number systemExample 1Example 2
Binary1111 0000 0000 11111000 1000 1000 0001
HexadecimalF00F8881
Decimal61,45534,945

It is obvious that a pattern is maintained between the hexadecimal and binary numbers and that this pattern is obscured by the decimal conversion. In the first example the binary half-byte 1111 is matched by the hexadecimal F00F.

Mathematically comparing hex F and binary 1111:

$$ -\textsf{1111} = ((1 \cdot 2^{3}) + (1 \cdot 2^{2}) + (1 \cdot 2^{1}) + (1 \cdot 2^{0})) \\ -= 8 + 4 + 2 + 1 \\ -= 15 -$$

$$ -\textsf{F} = 15 \cdot 16^{0} \\ -= 15 -$$

Every four bits (or half byte) in binary corresponds to one symbol in hexadecimal. Therefore a byte can be easily represented with two hexadecimal symbols, a 16-bit number can be represented with four hex symbols, a 32-bit number can represented with eight hex symbols and so on.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/IO_in_Python.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/IO_in_Python.html deleted file mode 100644 index 632c437..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/IO_in_Python.html +++ /dev/null @@ -1,108 +0,0 @@ -IO in Python - My Zettelkasten - - - - -

IO in Python

The open() object

The built-in open() function creates a file object that allows us to read, write and append to files.

The general syntax is as follows:

file_object = open(<file_name>, <access_mode>)

<file_name> is obviously a path to the file you want to read, create or modify. The <access_mode> denotes the mode in which to open the file. The most frequently used are:

  • r
    • read
  • w
    • write
  • a
    • append

All access modes

In addition we have the following access modes

Reading files

Once a file object has been intialised with open() there are several ways in which the content can be read:

Read methodBehaviour
readReturn the entire contents of the file as a single string.
readlineRead the contents of a file a line at a time. You would combine this with a loop so that you can do something with each individual line.
readlinesReturn a list of all the lines in a file. Each line will be an element in the list.

Read

read reads the entire contents of a file and returns it as a single string.

read() reads the entire file into memory at once, so it may not be suitable for very large files that exceed the available memory of your system. In such cases, you can use the readline() method to read the file line by line instead.

The basic syntax is as follows:

# Open the file for reading
-file = open('filename.txt', 'r')
-
-# Read the entire contents of the file
-contents = file.read()
-
-# We could also limit the read to a number of characters:
-contents = file.read(100)
-
-# Close the file
-file.close()

Once we have the file contents stored, we can then interact with it. The standard way of doing this is to parse it line by line. For example, say we were reading a CSV:

lines = content.split(',')
-for line in lines:
-    if line: # if the line is not empty
-        # do something with line

Readline

The readline() method in Python is used to read a single line from a file. It is typically used when you want to process a file line by line, rather than reading the entire file into memory at once.

readline() returns the line including the newline character at the end of the line, so you may need to strip this character off using the strip() method before processing the line further.

# Open the file for reading
-file = open('filename.txt', 'r')
-
-# Loop through the file, reading one line at a time
-line = file.readline()
-while line:
-    # Strip off the newline character
-    line = line.strip()
-
-    # Do something with the line
-    print(line)
-
-    # Read the next line
-    line = file.readline()
-
-# Close the file
-file.close()

Readlines

The readlines() method is used to read all the lines of a file and return them as a list of strings, where each element of the list is a line from the file.

# Open the file for reading
-file = open('filename.txt', 'r')
-
-# Read all the lines of the file and store them in a list
-lines = file.readlines()
-
-# Loop through the lines and print them to the console
-for line in lines:
-    print(line)
-
-# Close the file
-file.close()

Error handling

Obviously file access can raise errors - typically when the file you want to access does not exist (i.e. a FileNotFoundError exception). We can manage this scenario with exception handlers:

try:
-    with open('filename.txt', 'r') as file:
-    contents = file.readlines()
-    for line in lines:
-        print(line)
-except FileNotFoundError as err:
-    print("File does not exist")
-    print(err)

Close and “with as”

You notice that once we have finished with our I/O operation, we must call file.close() to terminate the process. This removes the reference to the file from memory.

A more pythonic and concise way of reading files and closing them is to use with...as syntax. When this phrasing is used, a self-contained context is created for the I/O operation that closes the file automatically.

with open('filename.txt', 'r') as file:
-    contents = file.read()
-    print(contents)

Writing to files

Again we create a file object with open() and this time use the write method:

# Open file in write mode
-file = open("example.txt", "w")
-
-# Write some text to the file
-file.write("Hello, this is an example text written using Python.")
-
-# Close the file
-file.close()

Note that in the above example, if the file does not already exist, it will create it. If it does exist, it will overwrite its contents with the new data. So we use write to create new files as well as to write to existing files.

Renaming and deleting files

We have to use another built-in module to rename and delete files: os.

To rename an existing file:

import os
-os.rename('original-file-name.txt', 'new-file-name.txt')

To delete a file:

import os
-os.remove('file-name.txt')
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/IP_addresses.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/IP_addresses.html deleted file mode 100644 index 6318336..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/IP_addresses.html +++ /dev/null @@ -1,69 +0,0 @@ -IP addresses - My Zettelkasten - - - - -

IP addresses

IPv4 vs IPv6

IP addresses come in two formats and bit-lengths depending on which version of the Internet Protocol is being used.

  • IPv4 addresses are 32-bits in length
  • IPv6 addresses are 128-bits in length

The larger the bit-length, the more unique addresses that can be generated. Thus IPv6 can create more addresses that IPv4.

This entry focuses on IPv4 addresses.

Anatomy of an IPv4 address

Each of the 32 bits are divided into four groups which are each 8 bits in length. Each group therefore comprises an octet and is separated by dots.

The decimal number system, rather than binary is used to represent the values. This means each binary octet is three decimal digits in length.

The 32 bits comprise two major groupings

  • the network prefix
  • the host

Different sections of IP address

Devices connected to the same network share the same network prefix. They are said to be on the same subnet. However each device will have a unique value for the host octet.

(This account is somewhat idealised. The length of the prefix does not always align with the octet boundary. For instance, the prefix could be 25 bits in length, rather than 24. In this case it would “steal” one bit from the host section making it 23 bits in length.)

Any changes to the length of the network prefix change the number of hosts available on the subnet. If the network prefix is longer, the number of unique hosts is reduced. If the network prefix is shorted, the number of unique hosts is increased.

Identifying the network and host groupings

Given that the network prefix and host identifier do not always stick to set boundaries, we require a way of distinguishing the two values. There are two dominant methods.

CIDR notation

This stands for Classless Inter-Domain Routing. An example:

192.168.1.23/24

The value after the forward slash is the number of bits that specify the network address. In the example, it is the standard 24-bits. Thus 192.168.1.23 stands for the network.

Subnet masking

The subnet mask is another number in addition to the network address. It is a kind of superimposed map on top of the address.

Here is an example of a subnet mask:

11111111.11111111.11111111.00000000

The denary form would be as follows (as 255 is the maximal decimal number that can be represented with a single 8-bit number and 0 is the smallest):

255.255.255.0

In the binary form, the 1 values represent the bits which designate the network address and the 0 values represent the bits that designate the host.

In the example above this corresponds to the idealised 32-bit:8-bit ratio of CIDR /24.

There is a clever consequence of the subnet mask: if you apply a bitwise AND operator against the IP address and mask (both in their binary form) you can determine whether two addresses are on the same network.

To compare the IP address 192.168.1.23 against 192.168.1.100 to demonstrate:

192.168.1.23:
-IP:     11000000.10101000.00000001.00010111
-Mask:   11111111.11111111.11111111.00000000
-Result: 11000000.10101000.00000001.00000000
-___________________________________
-
-192.168.1.100:
-IP:     11000000.10101000.00000001.00010111
-Mask:   11111111.11111111.11111111.00000000
-Result: 11000000.10101000.00000001.00000000

After applying the bitwise AND logic we see that the result is identical for both IPs indicating they are on the same network (share the same network prefix), whilst the host value is “masked”.

Here is a scenario where the subnet mask indicates that two IPs are not on the shared network:

192.168.1.23:
-IP:     11000000.10101000.00000001.00010111
-Mask:   11111111.11111111.11111111.00000000
-Result: 11000000.10101000.00000001.00000000
-___________________________________
-
-192.168.2.1
-IP:     11000000.10101000.00000010.00000001
-Mask:   11111111.11111111.11111111.00000000
-Result: 11000000.10101000.00000010.00000000
-

255.255.255.0 is not the only possible subnet mask. There are masks corresponding to ratios other than CIDR /24. For example:

  • 255.0.0.0 (/8)
  • 255.255.0.0 (/8)
  • 255.255.255.192 (/26)
  • 255.255.255.240 (/28)

As noted previously, the different ratios will obviously affect the number of unique hosts available on the subnet.

Determining the range of hosts: practical example

Let’s say we have the following IP address expressed in CIDR: 192.168.0.133/27. In binary this would be:

110000000.10101000.00000000.100--00101

The -- indicates the demarcation point between the network prefix and the bits designated for the host. 32 - 27 leaves us 5 bits for our range of hosts. This gives us 2^5 = 32 unique host values.

In fact it will actually be 30 values since the first value (00000) will be used to identify the network itself and the last value (11111) will be the broadcast address - the address used when a message needs to be sent to all hosts on the network.

An actual host address in this range is included in the example: 00101.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Identify_merged_branches.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Identify_merged_branches.html deleted file mode 100644 index 33331f3..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Identify_merged_branches.html +++ /dev/null @@ -1,70 +0,0 @@ -Identify merged branches - My Zettelkasten - - - - -

Identify merged branches

# View merged
-git branch --merged
-
-# View merged remote
-git branch -r --merged
-
-# View unmerged
-git branch --no-merged
-
-# View unmerged remote
-
-git branch -r --no-merged

The above cases run the merge check from the point of view of HEAD as this is the default.

But we can also run it from any branch.

git branch --merged non_head_branch

Demonstration

We have the following branches

git branch
-
-* main
-key_feature
-another_feature

The branches other than main, have not been merged:

git branch --merged
-
-* main

Just to confirm:

git branch --no-merged
-
-key_feature
-another_feature
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Importing_MongoDB_data.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Importing_MongoDB_data.html deleted file mode 100644 index 2b94d5e..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Importing_MongoDB_data.html +++ /dev/null @@ -1,50 +0,0 @@ -Importing data to MongoDB - My Zettelkasten - - - - -

Importing data to MongoDB

We can use the command line to import data into a Mongo database. We can also combine the importing of data with the creation of a database:

mongoimport --db [preexisting_or_new_database name] --collection [collection_name] --file sourcedata.json --jsonArray

We use --jsonArray to indicate the format of the data we are importing.

Once this has executed, the data will be visible in Compass.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Increasing_fractions_to_their_highest_terms.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Increasing_fractions_to_their_highest_terms.html deleted file mode 100644 index 1450f28..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Increasing_fractions_to_their_highest_terms.html +++ /dev/null @@ -1,56 +0,0 @@ -Increasing fractions to their highest terms - My Zettelkasten - - - - -

Increasing fractions to their highest terms

Given the equivalence between factors and divisors we can increase fractions to higher terms in a very similar way to when we reduce fractions. In the latter case we are dividing by divisors to reduce. In the former, we are multiplying by factors to increase.

Whenever we increase a fraction, the resultant fraction will always be equivalent to the fraction we started with.

Demonstration

Express \(\frac{3}{4}\) as an equivalent fraction having the denominator 20

$$ -\\frac{3 \cdot 4}{5 \cdot 4} = \frac{12}{20} -$$

Express \(\frac{2}{3}\) as an equivalent fraction having the denominator 21

$$ -\\frac{2 \cdot 7}{3 \cdot 7} = \frac{14}{21} -$$

Increasing fractions with variables to higher terms

Express \(\frac{2}{9}\) as an equivalent fraction having the denominator 18a

In these cases, just append the variable to the factor:

$$ -\\frac{2 \cdot 2a}{9 \cdot 2a} = \frac{4a}{18a} -$$

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Insert_data_into_SQL_table.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Insert_data_into_SQL_table.html deleted file mode 100644 index 3818d4e..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Insert_data_into_SQL_table.html +++ /dev/null @@ -1,53 +0,0 @@ -Insert data into table with SQL INSERT statement - My Zettelkasten - - - - -

Insert data into table with SQL INSERT statement

A table named sales:

saleIdmodelIddatesalesPerson
22322020-01-09tgomay
32132020-03-14snedgamon
49142021-08-06tricksahoy
INSERT INTO sales
-VALUES (1, 11, '2020-01-01','mhogan');

If you intend to miss out a value, you shouldn’t leave it blank, you should instead use NULL :

INSERT INTO sales
-VALUES (1, 11, '2020-01-01', NULL);

The approach above works well if the order of entry matches the order of the table fields. If this is not the case you can specify the order as part of the INSERT statement:

INSERT INTO sales**(employee_id, sale_id, model_id, sale_date)**
-VALUES ('mhogan', 1, 11, '2020-01-01',);
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Instruction_set_architectures.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Instruction_set_architectures.html deleted file mode 100644 index adaa732..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Instruction_set_architectures.html +++ /dev/null @@ -1,50 +0,0 @@ -Instruction Set Architectures - My Zettelkasten - - - - -

Instruction Set Architectures

Summary

  • Computers with different hardware execute machine code instructions (e.g add) in different ways. They have different instruction set architectures (ISAs).

  • A family of CPUs that implement the core instructions of the Arithmetic Logic Unit (ALU) in the same way share an ISA. Any software built for that ISA will work on any CPU that implements the ISA

  • The two main CPU architectures are ARM and x86

Architecture is logical not physical

The “architecture” of an ISA is logical rather than physical, i.e processors that share an ISA may work very differently on the hardware level whilst still adhering to the same instruction set.

ARM and x86

The two main processor architectures are ARM and x86. x86 processors were first introduced by Intel but are also made by AMD.

x86

  • First introduced by Intel but also made by AMD.

  • Name stems from Intel’s internal naming conventions - every new processor they introduced would have a letter designation ending with “86”. Later they would adopt names such as “Pentium”, “Celeron” etc. Regardless, these processors still fall under the “x86” family.

  • Over time, new instructions have been added to the x86 architecture but they all maintain backwards compatibility with preceding generations.

  • There have been different, successive generations of x86 corresponding to their word-size: 16-bit, 32-bit, 64-bit. Word size here just means how many bits the processor can work with at a time. A 34-bit processor can operate on values that are 32 bits in length. This means it has 32bit registers, a 32-bit data bus, a 32-bit address bus and so on.

  • AMD introduced the first 64-bit processor, not Intel but they later caught up. A 64-bit x86 processor is often referred to as x64 or x86-64.

ARM

  • x86 processors dominate the personal computer and server space

  • On movile devices ARM ISA predominates

  • The ARM company develops the architecture and standard which it licenses it to other companies to implement.

  • Preferred on mobile because they have reduced power consumption and lower costs compared to x86.

  • The processor is on a single chip that contains the CPU as well as memory and other hardware.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Integers.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Integers.html deleted file mode 100644 index 3c2c77d..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Integers.html +++ /dev/null @@ -1,50 +0,0 @@ -Integers - My Zettelkasten - - - - -

Integers

Come back to as many back links

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Integrated_circuits.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Integrated_circuits.html deleted file mode 100644 index 9ad937b..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Integrated_circuits.html +++ /dev/null @@ -1,50 +0,0 @@ -Integrated circuits - My Zettelkasten - - - - -

Integrated circuits

An integrated circuit (IC) is a single unit that comprises several logic gates designed for the easy construction of Digital_circuits. The terms “integrated circuit” and “chip” are often used interchangeably.

An IC puts the gates on a single piece of silicon that has electrical contact points called pins. There are two types of pins on an IC: input pins and output pins. Input pins are used to receive signals from other components in the circuit, while output pins are used to send signals to other components. The function of a pin is determined by the connection it has to the rest of the circuit and the type of signal it is intended to transmit or receive.

The type we will look at are called dual in-line packages (DIPs). They are rectangular wth two parallel rows of pins. The pins make it easy to connect DIPs to a breadboard.

An integrated circuit and its use on a breadboard:

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Interactive_staging.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Interactive_staging.html deleted file mode 100644 index 3f5edba..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Interactive_staging.html +++ /dev/null @@ -1,53 +0,0 @@ -Interactive staging - My Zettelkasten - - - - -

Interactive staging

With interactive staging we can stage sub-portions of files rather than the whole file. This makes commits much more targetted and atomic.

Basic use

We enter interactive mode with:

git add -i

This opens an interface:

We select 2 and it lets us stage by number. If I enter 1, it will stage the first change.

If we then go into 3 for revert, we can undo what we have staged.

Note that untracked files are not automatically added to the changes. We have to manually add them with 4 (“add untracked”).

Interactive mode doesn’t commit anything, it is only for staging.

Working with patches and hunks

There’s not much utility in interactive mode if you are commiting whole files. You can just use git add [file] and not bother with it.

But it is useful for staging sub-portions of a file, which are called hunks.

We access these via patch mode:

Splitting hunks

Git will try to suggest the best hunks it can but these will sometimes not reflect the changes you want. Sometimes they will reflect multiple changes rather than a single change.

So long as there is an unchanged line between the different changes that it has selected as a hunk you can split the hunk further. You just hit s in patch mode, and it will repeatedly split the hunk each time until you get what you want.

This is still an automated process and you may not find that the splitting results in a hunk you want to commit. In this case you can use manual splitting mode. We enter this with e.

This will oped up Vim for the manual work to be done:

We use the diff symbols +, - and space to do this.

Accessing patch mode directly

If we just want to go straight to patch mode, without anything else:

git add -p

We can also work with patches in the following commands:

git stash -p
-git reset -p
-git restore -p
-git commit -p
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Internet_Layer_of_Internet_Protocol.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Internet_Layer_of_Internet_Protocol.html deleted file mode 100644 index 572569a..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Internet_Layer_of_Internet_Protocol.html +++ /dev/null @@ -1,50 +0,0 @@ -Internet Layer of the Internet Protocol Suite - My Zettelkasten - - - - -

Internet Layer of the Internet Protocol Suite

The Internet Layer is concerned with establishing the basis for the connection and communication between hosts accross the internet.

In order for the data to get from a machine on one local network to a machine on another local network, each machine must have a way of identifying and interfacing with the other.

The Internet Layer utilises the Internet Protocol to determine how devices will be publicly identified to devices on other networks and how different devices on the same local network will be distinguished from outside of this network. This is achieved through Internet Protocol (IP) addresses.

Packets

Data is sent accross the internet between hosts as packets. These packets, when sent and received within the Link Layer on the local network, are enclosed within a Link Layer frame (in its payload section):

Internet Layer packet

Like a frame, an IP packet has a header and a payload. The payload comprises the data between sent between hosts. The header contains a source IP address and a destination IP address and also specifies which version of the Internet Protocol is being used.

// Need to find out more about packets work.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Internet_fundamentals.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Internet_fundamentals.html deleted file mode 100644 index cdf9577..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Internet_fundamentals.html +++ /dev/null @@ -1,50 +0,0 @@ -Internet fundamentals - My Zettelkasten - - - - -

Internet fundamentals

The internet is a network of networks. A globally connected set of computer networks that all use a suite of common protocols.

The protocols governing the communication between networks on the internet are specified in the Internet Protocol Suite.

This combines two protocols:

  • TCP
    • The Transmission Control Protocol
  • IP
    • The Internet Protocol

Hence the Internet Protocol Suite is also known as “TCP/IP”.

The TCP/IP is a network stack comprising four layers, each with its own protocols. From the top:

TCP/IP stack diagram

  • The Link Layer concerns communication between devices on the same local network. The transfer of information once it has been received from the internet or its transfer between devices before it sent out into the internet. Ethernet and WiFi are two core protocols utilised at this layer.

  • The Internet Layer is concerned with communication accross networks. It is responsible for identifying hosts on the inter-network by their addresses and routing data from network to network.

  • The Transport Layer creates a commmunication channel between two hosts using ports and sockets.

  • The Application Layer concerned with software that utilises information received and sent over the internet, for instance web pages and emails. This is the highest level of abstraction for which all the lower levels serve as “plumbing”. Examples of protocols operative at the Application Layer include HTTP and SSH.

See: Example_scenario_internet_data_transfer

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Intersection_types_in_TypeScript.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Intersection_types_in_TypeScript.html deleted file mode 100644 index a55a0ce..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Intersection_types_in_TypeScript.html +++ /dev/null @@ -1,78 +0,0 @@ -Intersection types - My Zettelkasten - - - - -

Intersection types

Like union types, intersection types allow us to combine the properties of existing primitive and custom types to make composites.

Creating an intersection

Say you have the following three types:

type IConcert = {
-  date: number;
-  location: string;
-  band: string;
-};
-
-type IConference = {
-  date: number;
-  location: string;
-  keynoteSpeaker: string;
-};
-
-type IMeeting = {
-  date: number;
-  location: string;
-  agenda: string[];
-};

Each type corresponds to a different event and has two properties in common with the other events: date and location.

Rather than repeat these properties for each individual type, we could create a general IEvent type and apply this as an intersection to each of the individual event types:

// The common event type
-type IEvent = {
-  date: number;
-  location: string;
-};
// The intersection
-
-type IConcert = IEvent & {
-  band: string;
-};
-
-type IConference = IEvent & {
-  keynoteSpeaker: string;
-};

In the case of interfaces, instead of using & we would write interface IConcert extends IEvent

Alternative method

There is another equivalent way of intersecting the types. We could first define IConcert and IConference as their own types (without extends or &) and then intersect with, e.g., type IConcert = SelfStandingConcertType & IEvent.

Benefits of intersections

  • It is more concise and we do not repeat ourselves needlessly
  • Common properties can be modelled in one place which makes updates and changes much easier: we do not have to change multiple type declarations, just change the ‘master’ type that is intersected with the variants.
  • It is more readable: we can see which properties are unique to the type without having to parse repeated properties.

Set theory: understanding errors

With intersections we literally use the & operator which discloses that the logic is equivalent to logical AND: a member of the intersection must have the properties of both types. In the case of primitive values this is impossible or, more accurately, it results in an empty set because, for example, string and boolean do not share any common values. This means you will get an error if you assign an intersection type to a value that does not have all the features of each custom type in the intersection.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Intro_to_the_Unix_shell.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Intro_to_the_Unix_shell.html deleted file mode 100644 index 8b14687..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Intro_to_the_Unix_shell.html +++ /dev/null @@ -1,50 +0,0 @@ -Introduction to the Unix shell - My Zettelkasten - - - - -

Introduction to the Unix shell

Unix based systems

Many operating systems are based on the UNIX software architecture. macOS/OSX (Darwin) and GNU/Linux are two very popular examples. Most web servers run a version of Linux as their native OS thus a knowledge of command line for UNIX systems is invaluable for web developers. Windows systems are not UNIX based so everything that is written here is not applicable to the Windows command line program Command Prompt although there are obvious conceptual overlaps.

UNIX was initially developed by AT&T and is still owned by them. GNU (the basis for Linux) is a recursive acronym for ’GNU is not UNIX’. Functionally it is the same as Unix however, it just doesn’t contain the proprietary code.

Key terms

Kernal

The kernel is the central part of an operating system. It manages the operations of the computer and the hardware; most notably memory and CPU time. There are two types of kernels: a micro-kernel, which only contains basic functionality; and a monolithic kernel, which contains many device drivers.

Shell

A shell is a user interface for access to an operating system’s services. In general, operating system shells use either a command-line interface or GUI, depending on a computer’s role and particular operation. It is named a shell because it is the outermost layer around the operating system kernel

Bash

Bash is a Unix shell and command language written by Brian Fox for the GNU Project as a free software replacement for the Bourne shell. First released in 1989, it has been distributed widely as the default login shell for most Linux distributions and Apple’s macOS.

What is the command line?

Command line is both a general computing concept and a specific utility. In its general sense, engaging with a computer via command line means inputting abbreviated written commands into a console or terminal window on a computer. The computer then runs these commands on the basis of the instructions you have given.

You can get the computer to ‘do things’ (make files, connect to networks etc) via command line and you can use it to check the status of systems within your computer.

This mode of engagement contrasts with the engagement facilitated by modern graphical user interfaces (GUIs) where the user navigates via a combination of keyboard and mouse inputs and interacts with windows whose functionality is usually self-explanatory and therefore more user-friendly. Command line predates GUIs but it is considered a more efficient and expansive means of interacting with the whole of your computer especially if you are a developer or programmer.

In the more specific sense, the ‘command line’ refers to the location in the console window where you input your commands. The command line consists in a user name and the current directory you are in followed by a dollar sign and a cursor waiting for input.

Basic orientation

When you are using command line you are always situated somewhere within a file system. Typically this will be your own user files. directory structure By default you are always in your home directory, this is represented by the tilda symbol: ~. This is why you see the tilda symbol as part of the command line. In command line, we do not use the term ‘folders’, instead they are called directories. (I will follow this convention from hereon.) You do not have to worry too much about remembering the names of specific folders and files you can always ask the computer to display them to you by using ls argument or pwd.

Command line syntax

The syntax of the language used to input commands is analogous to the grammar of natural languages. We have a verb that is operative on an object/noun and which can be modified through adverbs. The syntax of a command sequence is as follows:

  1. Command (verb): what we want to do
  2. Option (adverb): modifying the command - always starts with a hyphen
  3. Argument (noun/object): what we want our command to operate on

We will see that not all commands require arguments, but this is the general structure

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Inversion_of_operators.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Inversion_of_operators.html deleted file mode 100644 index e30f4c3..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Inversion_of_operators.html +++ /dev/null @@ -1,55 +0,0 @@ -Inversion of operators - My Zettelkasten - - - - -

Inversion of operators

Addition, subtraction

Addition is the inverse of subtraction: $$(x - a) + a = x$$ $$ (6 - 2) + 2 = 6

$$

Subtraction is the inverse of addition: $$(x + a) - a = x$$ $$ (3 + 2) - 2 = 3$$

Division is the inverse of multiplication $$ \frac{a \cdot x}{a} = x$$ $$ \frac{6 -\cdot 3}{6} = 3 -$$

Multiplication is the inverse of division $$ a \cdot \frac{x}{a} = x$$

$$ -2 \cdot -\frac{8}{2} = 8 -$$

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Invoking_the_shell_in_Python.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Invoking_the_shell_in_Python.html deleted file mode 100644 index 0c19795..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Invoking_the_shell_in_Python.html +++ /dev/null @@ -1,63 +0,0 @@ -Invoking the shell in Python - My Zettelkasten - - - - -

Invoking the shell in Python

import subprocess
-
-try:
-    process = subprocess.run(
-        ["ls", "-la"],
-        shell=True,
-        stdout=subprocess.PIPE,
-        stderr=subprocess.PIPE,
-        text=True,
-    )
-    return process.stdout
-
-except subprocess.CalledProcessError as e:
-        return e.stderr.strip()
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Iterating_in_React.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Iterating_in_React.html deleted file mode 100644 index 85c76be..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Iterating_in_React.html +++ /dev/null @@ -1,113 +0,0 @@ -Iterating through data - My Zettelkasten - - - - -

Iterating through data

As React follows the functional programming paradigm and state versioning, looping is not the recommended way of engineering repeated processes since it presupposes pre-existing state. Instead React relies on the functional methods of modern JavaScript such as map , filter , reduce to output the values of iterative data structures.

Instead of mutating the state of a reference type, these methods are ‘non-destructive’: they create a new array that meets the requirements set in the particular method. These newly created arrays and objects therefore form the basis of the state versioning, because each new array that is engendered, is a new state configuration.

The key attribute

The key attribute is a special React attribute that should be added to the elements of any listed content (i.e numbered lists, unordered lists, select options etc; basically anything rendered that comes about through mapping arrays and objects).

This enables React to monitor the state of the list: which items have changed, been added, or removed.

The best way to pick a key is to use a string that uniquely identifies a list item among its siblings.

For instance, using our earlier numbers array, assuming each number is unique, we could use the number itself as the key:

const numbers = [1, 2, 3, 4, 5];
-const listItems = numbers.map((number) => (
-  <li key={number.toString()}> {number}</li>
-));

Keys have to be unique to the individual element and not shared by any other sibling. But they do not need to be globally unique. You could use the same key name in another array list.

Keys should be string types, not other data types. You can use the .toString() method to ensure this is the case.

If you can’t find a unique basis for naming a series of keys, you can use the index value of the Array.map function. This should only be used if the order of the items doesn’t change. An example:

class List extends React.Component {
-  render() {
-    const demoArr = ["cat", "dog", "mouse"];
-    return (
-        <ul>
-          {demoArr.map((x, index) => (
-            <li key={index}>{x}</li>
-          ))}
-        </ul>
-      </div>
-    );
-  }
-}

Demonstration

Source data

const blogData = [
-  {
-    id: 1,
-    date: "2020-11-15",
-        shortByline:
-      "Quisque cursus, metus vitae pharetra auctor, sem massa mattis sem, at interdum magna augue eget diam. ",
-    longByline:
-      "Quisque cursus, metus vitae pharetra auctor, sem massa mattis sem, at interdum magna augue eget diam. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Morbi lacinia molestie dui. Praesent blandit dolor.",
-    image: blogImage,
-  },
-  {
-    id: 2,
-    date: "2020-08-11",
-        shortByline:
-      "Quisque cursus, metus vitae pharetra auctor, sem massa mattis sem, at interdum magna augue eget diam. ",
-    longByline:
-      "Quisque cursus, metus vitae pharetra auctor, sem massa mattis sem, at interdum magna augue eget diam. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Morbi lacinia molestie dui. Praesent blandit dolor.",
-    image: blogImage,
-  },
-];

Child component

export default function BlogPreviewCard(props) {
-  return (
-    <Card>
-      <CardMedia image={props.image} />
-      <CardContent>
-        <Typography>{props.date}</Typography>
-        <Typography>{props.title}</Typography>
-        <Typography>{props.shortByline}</Typography>
-      </CardContent>
-      <CardActions>
-        <Button>Read</Button>
-      </CardActions>
-    </Card>
-  );
-}

Iteration

// This uses the Material-UI grid component
-
-import BlogPreviewCard from "../components/BlogPreviewCard"
-import blogData from "../data/blogData
-
-export default function BlogPreviewSet() {
-  return (
-    <Grid>
-      {blogDummyData.map((data, index) => (
-        <Grid key={index}>
-          <BlogPreviewCard key={index} {...data} />
-        </Grid>
-      ))}
-    </Grid>
-  )
-}
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Iterating_through_complex_data_structures_in_Python.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Iterating_through_complex_data_structures_in_Python.html deleted file mode 100644 index ba0fab4..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Iterating_through_complex_data_structures_in_Python.html +++ /dev/null @@ -1,95 +0,0 @@ -Iterating through complex data structures in Python - My Zettelkasten - - - - -

Iterating through complex data structures in Python

// TODO: sections :

  • Looping, mapping, filtering lists
  • Looping, mapping, filtering dictionaries
  • As above with multi-dimensional lists
  • As above with list of dictionaries

Complex data structures

In JavaScript when we return data from an API we tend to use an array of objects as the canonical form of a repeating iterable, e.g:

const data = [
-  {
-    name: "Thomas",
-    age: 35,
-  },
-  {
-    name: "Joe",
-    age: 75,
-  },
-];

In Python there are two common ways to handle similar data structures:

  • A list of lists:
    data = [
    -  ["Thomas", 35],
    -  ["Joe", 75]
    -]
  • A list of dictionaries:
    data = [
    -   {"name": "Thomas", "age": 35},
    -   {"name": "Joe", "age": 75},
    -]

Multi-dimensional lists (list of lists)

Sorting by common property

Assuming the sub-lists have an identical structure, you can sort them by a common property by passing a lambda function to the key value of sorted() and .sort().

For example, to sort the following list of lists by the second age property:

people = [["Alice", 30], ["Bob", 25], ["Clare", 35], ["Dave", 28]]

Using sorted():

sorted_people = sorted(people, key=lambda x: x[1])
-print(sorted_people)
-# Output: [['Bob', 25], ['Dave', 28], ['Alice', 30], ['Clare', 35]]

Using .sort:

people.sort(key=lambda x: x[1])
-print(people)
-# Output: [['Bob', 25], ['Dave', 28], ['Alice', 30], ['Clare', 35]]

If you want to sort by name instead, you could change the lambda function to lambda x: x[0]:

# Using sorted()
-sorted_people = sorted(people, key=lambda x: x[0])
-print(sorted_people)
-# Output: [['Alice', 30], ['Bob', 25], ['Clare', 35], ['Dave', 28]]
-
-# Using .sort()
-people.sort(key=lambda x: x[0])
-print(people)
-# Output: [['Alice', 30], ['Bob', 25], ['Clare', 35], ['Dave', 28]]

Updating an inner value within a multidimensional list

In the following example we have a list of the following structure:

data = [
-    ["1688582410", "Article One"],
-    ["1688647447", "Article Two"],
-    ["1689023491", "Article Three"],
-]

Below we use map and a lambda function to convert the first element of each iner list from a Unix timestamp to a readable string:

 readable_date = list(map(lambda i: [convert_timestamp(i[0])] + i[1:], date))

We could also use list comprehension to achieve the same outcome:

readable_date = [[convert_timestamp(i[0])] + i[1:] for i in data]

Filter elements in a multidimensional list

Say we have the following data structure:

name_age = [ ["Anthony", 16], ["Christopher", 22], ["James", 6] ]

We can return only the people who are older than 18 with the following filter function and lambda:

filtered_ages = list(filter(lambda person: person[1] > 18, name_age))

Remove duplicate entries from multidimensional list

If we are just working with a normal list, a quick way to remove duplicates is just:

our_list = [9, 9, 3, 2]
-unique = list(set(our_list))

This won’t work with a list of lists because lists are not hashable.

There are different approaches. Let’s say we have the following multidimensional list:

dummy_data = [
-    ["1689023491", "Article Three", "Lorem ipsum...", "https://example.com"],
-    ["1688582410", "Article One", "Lorem ipsum...", "https://example.com"],
-    ["1688647447", "Article Two", "Lorem ipsum...", "https://example.com"],
-    ["1689023491", "Article Three", "Lorem ipsum...", "https://example.com"],
-]

Here is one method:

unique = []
-seen = set()
-for element in dummy_data:
-    element_to_check = element[0]
-    if element_to_check not in seen:
-        unique.append(element)
-        seen.add(element_to_check)
-print(unique)

We designate a unique property in the inner lists and then store a unique record of each. If the seen set doesn’t have the incoming element, we add it to the unique array.

It’s more efficient to use a dictionary because it allows us to do this in 0(1) time rather than 0(n):

unique_dict = {x[0]: x for x in dummy_data}
-unique_data = list(unique_dict.values())

This approach leverages the fact that a dictionary cannot have duplicate keys: if you try to insert an element with a key that already exists, the new value will simply overwrite the old value for that key.

Accordingly, we create a dictionary which uses the unique key in each list as the key of each dictionary entry via dictionary comprehension that loops through each value in the inner lists of the multidimensional array. We then parse the values of the dictionary into a list.

List of dictionaries

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Joins_in_SQL.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Joins_in_SQL.html deleted file mode 100644 index 655a81f..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Joins_in_SQL.html +++ /dev/null @@ -1,80 +0,0 @@ -Joins in SQL - My Zettelkasten - - - - -

Joins in SQL

-

We perform joins in SQL when we combine and integrate data from multiple tables. In order for a join to be possible, the tables you want to join must have rows that share the same fields.

The output will be represented as a table but it is virtual, not an actual table. (If you wish to actually create a table or a view off the back of a join operation you should combine the join with the CREATE TABLE command etc.)

Inner joins

An inner join combines rows that have matching values in two or more tables. This join is based on the existence of a common field between the tables and is used to retrieve data that appears in both tables.

The following is a good scenario for creating an inner join:

We want to create a list of the name of all computers that have been sold and when they were sold.

We will be working from the following tables.

The sales table:

saleIdmodelIdsaleDateemployeeIdprice
1442020-07-27tbishop40.99
2222021-02-05tbishop986.99
3142022-11-16tgnomay1248.99

The model table:

modelIdmodelName
44Raspberry Pi Model A
22Apple MacBook Air
14Lenovo ThinkPad P15

The data points we need are not provided in a single table. sales gives us the saleDate but not the modelName. In order to meet our requirements we must perform a join that combines modelName from the model table and saleDate from the sale table to give us a table like the following:

modelNamesale_date
Raspberry Pi Model A2015-02-01
Apple Macbook Air2018-11-01
Lenovo ThinkPad P152018-11-01

We can do this by utilising the field they have in common: modelId.

Implementation

The general syntax for creating an inner join from two tables that share a common field is as follows:

SELECT column_name(s)
-FROM table1
-INNER JOIN table2
-ON table1.columnName = table2.columnName

So basically, look at table1 and table2 return the rows where the fields for table1 and table2 match, where these fields are the ones specified in the SELECT.

Applied to our example:

SELECT model.modelName, sales.saleDate -- Name the fields
-FROM model -- Specify the first table
-INNER JOIN sales -- Specify the second table
-ON model.model_id = sales.model_id; -- Specify the match criteria

It is important to note that the match must be a match. Both tables must have a row with the same value for modelId for the join to be applied. If there is a modelId of X in sales but no corresponding X for modelId in model, nothing will be returned for that row.

We can represent the logical relationship that obtains between the sales and model tables as follows:

Outer joins

Outer joins are joins that return matched values and unmatched values from either or both tables.

To explain outer joins we need to expand our data set:

The sales table:

saleIdmodelIdsaleDateemployeeIdprice
1442020-07-27tbishop40.99
2222021-02-05tbishop986.99
3142022-11-16tgnomay1248.99
42020-03-01msmelk699.99

The model table:

modelIdmodelName
44Raspberry Pi Model A
22Apple MacBook Air
14Lenovo ThinkPad P15
66Google Chromebook

We will assume that sales is our left table and model our right.

Left outer join

A left outer join returns all records from the left or first table and the matching records from the right or second table. If there are not matches on the right then only the left data is returned.

In the context of our dataset, in the sales database we have a row where there is a sale with no corresponding modelId. If we performed a left outer join this would give us the following table in return:

modelNamesale_date
Raspberry Pi Model A2015-02-01
Apple Macbook Air2018-11-01
Lenovo ThinkPad P152018-11-01
2020-03-01

The logical relationship sustained between sales and model by a left inner join is represented in the following diagram:

Implementation

The schematic form:

SELECT column_name(s)
-FROM table1
-LEFT JOIN table2
-ON table1.column_name = table2.column_name;

Applied to our data set:

SELECT model.modelName, sales.saleDate
-FROM sales.saleDate
-LEFT JOIN model
-ON sales.modelId = model.modelId

Right outer join

This is the inverse of the right outer join. A right outer join returns all records from the right or second table and the matching records from the left or first table. If there are not matches on the left then only the right data is returned.

In the context of our dataset, in the model database we have a row where there is a modelId without a corresponding entry in the sales table. If we performed a right outer join this would give us the following table in return:

modelNamesale_date
Raspberry Pi Model A2015-02-01
Apple Macbook Air2018-11-01
Lenovo ThinkPad P152018-11-01
Google Chromebook

The logical relationship sustained between sales and model by a right inner join is represented in the following diagram:

Implementation

The schematic form:

SELECT column_name(s)
-FROM table1
-RIGHT JOIN table2
-ON table1.column_name = table2.column_name;

Applied to our data set:

SELECT model.modelName, sales.saleDate
-FROM sales.saleDate
-RIGHT JOIN model
-ON sales.modelId = model.modelId

Full outer join

The full outer join returns all rows when there is a match in either the left or the right table. So, for table A and table B the full join returns all rows in A and all rows in B including those where there is a match between A and B. This is the broadest type of join and can often result in large data sets.

In the context of our dataset it would result in the following table being generated:

modelNamesale_date
Raspberry Pi Model A2015-02-01
Apple Macbook Air2018-11-01
Lenovo ThinkPad P152018-11-01
2020-03-01
Google Chromebook

Represented by the following diagram:

Implementation

The schematic form:

SELECT column_name(s)
-FROM table1
-FULL OUTER JOIN table2
-ON table1.column_name = table2.column_name;

Applied to our data set:

SELECT model.modelName, sales.saleDate
-FROM sales.saleDate
-FULL OUTER JOIN model
-ON sales.modelId = model.modelId

This type of join is used when you want to discern when there is not a match between two fields across tables. For example: imagine that you wanted a list of computers that had never been sold. In this case, you would be interested in rows where there is a model_id without a corresponding sales_id .

In SQL this would be achieved with:

SELECT model.name, sales.sale_date
-FROM model
-LEFT JOIN sales on model.model_id = sales.model_id;

Note that this would return all the model names but where there isn’t a sale data, NULL would be returned. This is an important distinction : the outer join method doesn’t just return the rows with a NULL value for sale_date as we might expect. It returns all models along with those that have not been sold. This is because it is oriented to the “left” table, equivalent to the table in the SQL that we cited first with the on keyword.

A left outer join returns all the records from the left (model) table and those that match in the right (sales) table. Where there are no matching records in the right (sales) table, a NULL value is returned.

A right outer join, often referred to as a right join, is the opposite of a left outer; it returns all the records from the right table and those that match in the left table. In our scenario this would be all the models that had a sale_date including models that didn’t have a sale_date , i.e which returned NULL

Finally, a full outer join returns all the records from both tables, and where a record cannot be matched, a NULL value is returned. So this would mean there could be NULLs in both fields of the returned rows.

We can combine multiple types of join in the same SQL query:

SELECT model.name, sales.sale_date, manufacturer.url
-FROM model
-LEFT JOIN sales on model.model_id = sales.model_id
-INNER JOIN manufacturer on model.manufacturer_id = manufacturer.manufacturer_id;
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Journey_of_GraphQL_query.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Journey_of_GraphQL_query.html deleted file mode 100644 index bbf6f74..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Journey_of_GraphQL_query.html +++ /dev/null @@ -1,50 +0,0 @@ -The journey of a GraphQL query - My Zettelkasten - - - - -

The journey of a GraphQL query

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Key_characteristics_of_GraphQL.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Key_characteristics_of_GraphQL.html deleted file mode 100644 index b361564..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Key_characteristics_of_GraphQL.html +++ /dev/null @@ -1,58 +0,0 @@ -Key characteristics of GraphQL - My Zettelkasten - - - - -

Key characteristics of GraphQL

In a nutshell, GraphQL is all about optimizing data communication between a client and a server. This includes the client asking for needed data and communicating that need to the server, and the server preparing a fulfillment for that need and communicating the fulfillment back to the client. GraphQL allows clients to ask for the exact data they need and makes it easier for servers to aggregate data from multiple data storage resources.

  • GraphQL is a query language from which you can build APIs. It exists as an abstraction layer between a client that issues requests and a backend comprising any number of databases that responds to queries.
  • Crucially, with applications that utilise GraphQL, both the backend and the frontend use the same GraphQL syntax. They speak the same language. This means that neither needs to take account of the way in which the other is implemented. For example, a client could request data from both a relational database and an object database without knowing there is any difference from its point of view. Conversely, client requests could be made through JavaScript or Python and the structure of the request received by the backend would be the same.
  • The main benefit is its interoperability and its network economy when compared to REST APIs: you ask only for what you want and you get only that; there is no surplus data, increasing efficiency, reducing the number of network requests and reducing the size of the payload.

The best way to think of GraphQL architecturally is to think of it as a different technique for instantiating the uniform interface, client/server decoupling, and layered-system architecture contraints of traditional REST APIs. However, instead of making GET or POST requests to a REST endpoint URL and passing parameters, you send a structured query object.

Architecture

From the point of view of the frontend, GraphQL is a query language that may be used via wrappers for a given framework or programming language (such as Apollo) or directly simply by sending requests over HTTPS to a single URL.

From the point of view of the backend, GraphQL is a runtime that provides a structure for servers to describe the data to be exposed in their APIs. We call this structure the schema. For example, the GraphQL server might translate the query into SQL statements for a relational database then take what the storage engine responds with, translate it into JSON and send it back to the client application.

The backend implementation of GraphQL is known as the GraphQL server. This server is distinct from any of the physical servers that the backend may rely on. The client queries the GraphQL server.

Client requests are sent over HTTPS and the data is typically returned in the form of JSON:

Implementation overview

Queries, mutations, subscriptions

Queries can be used for both reading and modifying data.

  • When you need to read data with GraphQL you use queries
  • When you need to modify data, you use mutations

So, for comparison, a query would be akin to a READ instruction in SQL or a GET request send to a REST API. A mutation would be akin to WRITE then READ instruction in SQL or a POST request to a REST API.

There is a third request type called a subscription. This is used for real-time data monitoring requests, like a data stream, similar to a continuous READ process. Mutations typically trigger events that can be subscribed to.

Frontend

Below is an example of a request that would be made to a GraphQL server from the frontend:

query {
-  employee(id: 42) {
-    name
-    email
-  }
-}

Backend: structure and behaviour

We define the structure of a GraphQL API on the backend through the schema. A schema is strongly typed and is basically a graph of fields that have types, e.g

type Employee(id: Int!) {
-  name: String!
-  email: String!
-}

! stands for required. In addition to the standard primitive data-types you can also have custom types.

We implement the behaviour of the API through functions called resolver functions. Each field in a GraphQL schema is backed by a resolver function. A resolver function defines what data to fetch for its field.

A resolver function represents the instructions on how and where to access raw data. For example, a resolver function might issue a SQL statement to a relational database, read a file’s data directly from the operating system, or update some cached data in a document database. A resolver function is directly related to a field in a GraphQL request, and it can represent a single primitive value, an object, or a list of values or objects.

GraphQL endpoint

The GraphQL server exposes a single endpoint as a URL. This is in contrast to a REST API where there are multiple endpoints, each corresponding to a different resource. With GraphQL, the request is not specified by the URL and the payload but rather in the GraphQL string that you send to the endpoint, like the employee query above.

Benefits

Single requests

With a REST API if you require multiple resources you have to make multiple requests to different endpoints and then once they resolve, synthesise them on the client side. With GraphQL you can send a single request that encompasses each individual resource:

The REST scenario:

The GraphQL scenario:

Abstraction of multiple services

Stops overfetching

In a strict REST API you must request all resources from a given resource and then filter on the client. With GraphQL you request only the resource you need at the client-level.

Single endpoint

In GraphQL you have a single endpoint and it always remains the same. This makes updates easier to manage, since you don’t need to broadcast new endpoints as the API grows. It also simplifies frontend parsing, since you don’t need to account for, or interpolate different endpoints in your request URL.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Killing_processes.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Killing_processes.html deleted file mode 100644 index 32a6fb3..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Killing_processes.html +++ /dev/null @@ -1,57 +0,0 @@ -Killing processes - My Zettelkasten - - - - -

Killing processes

Kill a process running on a port

For example a local server.

sudo lsof -t -i:8000
-# List files and proces ID (-t) and internet connections (-i) on port number
-
-$ 7890
-# Gives you process id
-
-sudo kill -9 7890
-# Kill the process that is running there

Alterntive

ss -ltnp | grep ':8000'

Returns:

LISTEN 0      511            [::1]:8000          [::]:*    users:(("node",pid=10493,fd=34))

Kill with:

kill 10493
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/LEDs.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/LEDs.html deleted file mode 100644 index 2e73a64..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/LEDs.html +++ /dev/null @@ -1,50 +0,0 @@ -LEDs - My Zettelkasten - - - - -

LEDs

LED’ stands for Light Emitting Diode, a circuit component that emits light. The symbol for an LED is displayed below:

A diode is a special kind of component that only permits current to flow through it in one direction. To achieve this it has very low resistance in one direction to allow current flow and high resistance in the other direction to impede current flow. This feature of diodes is clearly represented in the generic diode circuit symbol:

An LED diode lights up when the right amount of current flows through it. A standard LED has a maximum current of 20mA. An appropriate resistor must therefore be added to the circuit to ensure the current doesn’t exceed this amount.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Lambda_directory_structure.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Lambda_directory_structure.html deleted file mode 100644 index 9c7a6aa..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Lambda_directory_structure.html +++ /dev/null @@ -1,60 +0,0 @@ -Lambda directory structure - My Zettelkasten - - - - -

Lambda directory structure

I am using the following structure for my lambdas:

lambda-name/
-    events/
-    function-name/
-        src/
-            index.js
-        tests/
-        local-env.json
-        production-env.json
-        package.json
-    template.yaml
-    README.md
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Lambda_handler_function.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Lambda_handler_function.html deleted file mode 100644 index f397803..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Lambda_handler_function.html +++ /dev/null @@ -1,74 +0,0 @@ -AWS Lambda handler function - My Zettelkasten - - - - -

AWS Lambda handler function

Every Lambda function begins the same way with a handler function. In NodeJS:

module.exports.handler = function(event, context, callback){...}

The handler is the entry point for the Lambda. It is a function that Lambda can call to start the execution of your code when an event triggers your Lambda function.

You may put your whole code in the body of the handler, or you may call other modules and keep the handler clean and focused on bootstrapping.

The module.exports part is just the standard way of exporting a module in Node. handler is a property that is being exported.

You always have access to the parameters event, context and callback.

  • event
    • The triggering event of the Lambda function stored as an object. The object’s contents will be different depending on the trigger. It could be any AWS service that serves a trigger (S3, DynamoDB, API Gateway etc).
    • For example, if the triggering function is a request to API Gateway, the event object will contain information about the HTTP request such as headers, path, and the request body.
  • context
    • contains information about the runtime environment and the current execution of the Lambda function. The context object provides properties and methods that you can use to interact with the AWS Lambda service and the current invocation.
  • callback
    • an optional parameter that represents a callback function provided by AWS Lambda. The callback function allows you to signal the completion of your Lambda function’s execution and return a response or an error. The callback function accepts two arguments: error and result. If the first argument is not null, AWS Lambda treats it as an error, and the Lambda function invocation fails. If the first argument is null, AWS Lambda treats the second argument as the result and considers the invocation successful. Using the callback function is more common in non-async handler functions. When you use async functions, you can return a response or throw an error directly, without using the callback function.

Full example:

In JavaScript:

module.exports.handler = async (event, context) => {
-  // Your logic to handle the incoming event
-  // For example, you can call other AWS services, process the event data, etc.
-
-  // Return a response
-  return {
-    statusCode: 200,
-    body: JSON.stringify({
-      message: "Your Lambda function has successfully executed!",
-    }),
-  };
-};

In Python:

import json
-
-def handler(event, context):
-    # Your logic to handle the incoming event
-    # For example, you can call other AWS services, process the event data, etc.
-
-    # Return a response
-    response = {
-        'statusCode': 200,
-        'body': json.dumps({
-            'message': 'Your Lambda function has successfully executed!'
-        })
-    }
-    return response
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Lambda_programming_model.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Lambda_programming_model.html deleted file mode 100644 index a20e643..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Lambda_programming_model.html +++ /dev/null @@ -1,50 +0,0 @@ -AWS Lambda programming model - My Zettelkasten - - - - -

AWS Lambda programming model

The overall architecure consists in the following three processes:

  1. Triggers
  2. Handler function
  3. Code

Triggers

See AWS Lambda triggers

Handler function

See AWS Lambda handler function

Code

This is just the stuff that runs in the body of the handler or that is called from the handler body.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Lambda_triggers.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Lambda_triggers.html deleted file mode 100644 index 569621b..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Lambda_triggers.html +++ /dev/null @@ -1,50 +0,0 @@ -AWS Lambda triggers - My Zettelkasten - - - - -

AWS Lambda triggers

Here are some common trigger patterns

API Gateway trigger

  • an HTTP request is sent to AWS API Gateway
  • API Gateway triggers a Lambda function to execute

DynamoDB table change trigger

  • a record in a DynamoDB table is modified
  • DynamoDB triggers a lambda function to execute

S3 trigger

  • a new file is created in S3
  • S3 triggers a Lambda function to execute

SQS trigger

  • a new message is added to an SQS queue
  • SQS triggers a Lambda function to execute
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Lambdas_in_Python.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Lambdas_in_Python.html deleted file mode 100644 index 43774d2..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Lambdas_in_Python.html +++ /dev/null @@ -1,56 +0,0 @@ -Lambdas in Python - My Zettelkasten - - - - -

Lambdas in Python

In Python, anonymous functions like arrow-functions in JavaScript (() => {}) are immediately invoked and unnamed. They are called lambdas.

Whilst they are unnamed, just like JS, the value they return can be stored in a variable. They do not require the return keyword.

They are most often used unnamed with the functional methods map, filter and reduce.

Here is the two syntaxes side by side:

// JavaScript
-
-const double = (x) => x * x;
# Python
-
-double = lambda x: x * x

Here is a lambda with multiple parameters:

func = lambda x, y, z: x + y + z
-print(func(2, 3, 4))
-# 9

Lambdas obviously enshrine functional programming paradigms. Therefore they should be pure functions, not mutating values or issueing side effects. For example, it would be improper (though syntactically well-formed) to use a lambda to print something

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Latches.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Latches.html deleted file mode 100644 index d529594..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Latches.html +++ /dev/null @@ -1,53 +0,0 @@ -Latches - My Zettelkasten - - - - -

Latches

The combinatorial digital circuits we have looked at so far have been non-sequential. The outcome is a function of its immediate set of inputs and everything happens at once: there is no means of storing state for future use. In other words there is no Memory.

In contrast, the output of a sequential digital circuit depends not only on its present set of inputs but also on past inputs to the circuit. It has some knowledge of its own previous state through the existence of memory. This can be implemented via components that allow for the storage and retrieval of binary data.

What is a latch?

A latch is a circuit component that wor

The SR Latch (for “set/reset”) has two inputs: S (for “set”) and R (for “reset”) and one output, Q. Q stands for the bit that is remembered. (There is also not-Q which is the opposite of whatever Q is currently set to.)

The SR Latch goes through the following state changes:

  • When S is set to 1, output Q becomes 1 also
  • When S goes to 0, Q remains 1
  • When R is set to 1, the memory bit is cleared and Q becomes 0.
  • Q remains at 0 even if R goes back to 0

This is represented more clearly in the table below:

SRQOperation
11XInvalid, null

The most succinct account of a latch:

A latch is a 1-bit memory device that has a state Q of either 1 or 0. The S input sets Q to 1 and the R input resets Q to 0.

The representation of an SR Latch in a digital circuit diagram:

Creating a latch circuit

The circuit diagram latch symbol obviously encapsulates more complex functionality that occurs at the sub-circuit level. We will demonstrate how this functionality can be achieved with two NOR gates.

The two gates are in a cross-coupled configuration. This basically means that the wires are crossed back on themselves such that the output of one is also an input of the other at a single stage in the sequence.

The circuit is created as follows:

Interactive version:

-
-Let's talk through the logic at each state change: -
  • When S is set to 1, output Q becomes 1 also
    • N1 is receiving 1 from S and 0 from R by way of N2. This is the inversion of OR so TF equals F. Thus N1 is outputting 0.
    • Thus N2 is receiving 0 from N1 as its top input and 0 from R as its bottom input. It is therefore outputting 1 because with NOR, FF equals T. For this reason, Q is 1 because is directly connected to R.
  • When S goes to 0, Q remains 1
    • N2 is receiving 0 from N1 as the top input and 0 from R as the bottom input hence the overall input is FF which means N2 is outputting T and Q remains 1
    • N1 is outputting 0 because it is receiving 0 as its top input and 1 from its bottom input
  • When R is set to 1, the memory bit is cleared and Q becomes 0.
    • N2 is receiving 1 from R as its bottom input and 1 from the output of N1 as its top input. Therefore it is outputting TT which in NOR evaluates to F hence Q is 0
    • N1 is outputting 1 because it is receiving 0 from S as its top input and 0 from its bottom input coming from N2. FF equals T in NOR therefore 1 is outputting 1
  • Q remains at 0 even if R goes back to 0
    • N2 is receiving 0 as its bottom input from R and 1 as its top input from N1. TF equals F in NOR hence the output of N2 is 0 and Q remains 0
    • N1 is outputting 1 because it is receiving 0 as its top input from S and 0 as its bottom input from N2. FF equals T in NOR hence N1 is 1
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Law_of_Non_Contradiction.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Law_of_Non_Contradiction.html deleted file mode 100644 index 93a3886..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Law_of_Non_Contradiction.html +++ /dev/null @@ -1,52 +0,0 @@ -Law of Non-Contradiction - My Zettelkasten - - - - -

Law of Non-Contradiction

A proposition cannot be true and false at the same time.

$$ -\lnot (P \land \lnot P) -$$

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Law_of_the_Excluded_Middle.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Law_of_the_Excluded_Middle.html deleted file mode 100644 index 7f0479e..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Law_of_the_Excluded_Middle.html +++ /dev/null @@ -1,52 +0,0 @@ -Law of the Excluded Middle - My Zettelkasten - - - - -

Law of the Excluded Middle

Every proposition has to be either true or false. There can be no middle ground.

$$ -P \lor \sim P -$$

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Lifecycle_methods.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Lifecycle_methods.html deleted file mode 100644 index e620a2d..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Lifecycle_methods.html +++ /dev/null @@ -1,50 +0,0 @@ -Lifecycle methods - My Zettelkasten - - - - -

Lifecycle methods

Lifecycles are familiar from nature: something is born, it grows and reaches maturity and then dies and the process continues as what dies is broken down into constituent parts which form the basis of new life. And so on and so on.

The same metaphor can be applied to React components relative to the document object model:

  • Components are ‘born’ (created and mounted on the DOM)
  • They ‘grow’ by changing and updating their state
  • They ‘die’ by being unmounted from the DOM

Specific lifecycle phases

The outline above corresponds to specific methods that execute when React code runs:

  1. componentWillMount() : this method is called just before the render() method is called
  2. componentDidMount() : this method is called after the component is rendered in the DOM

The two methods above only occur once in a lifecycle.

The ‘updating’ phase is achieved with the following methods. This is when the data of the component, in the form of state and props updates in response to user interaction. We call this process ‘re-rendering’:

  1. shouldComponentUpdate() : determines whether component should update

  2. componentWillUpdate() : called before re-rerendering occurs

  3. componentDidUpdate() : called after re-rendering occurs

The final phase is unmounting: when the component is removed from the DOM:

  1. componentWillUnmount()

React component lifecycle

Side-effects: why lifecycle phases matter

React is built based on the principles of functional programming. In this paradigm, a side-effect (something that is generally discouraged) is any process that is not the direct result of a function executing or anything that is not covered by the return keyword.

Many of the methods detailed in the previous section will rarely be used in React development since they pertain to the inner engineering of the library, rather than its application in custom contexts. However sometimes you do need access to these methods, depending on the background context of what you are trying to achieving. This context could include external API and database requests or anything that does not directly pertain to the rendering of the component on the screen.

React groups these processes under the heading of side-effects.

Examples of side-effects and where in the lifecycle they should run

  • componentWillMount : It’s a good idea to run set-up scripts at this point, such as connecting to and authenticating access to a database. This process runs before the render method is called so it is an optimal point to establish these connections
    • You should not however make data requests at this point since data is typically returned asynchronously. You cannot therefore be sure that the data will be returned before mounting occurs.
  • componentDidMount : This is the time to do things that can’t occur without the DOM:
    • retrieve data
    • add event listeners
    • set timers using setTimeout or setInterval
  • Updating methods (shouldComponentUpdate, componentWillUpdate etc.)
    • As these precede or take place concurrently with the rerendering process, this phase is a good point to retrieve new data or run necessary external processes that are required by the re-rendering.
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Link_Layer_of_Internet_Protocol.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Link_Layer_of_Internet_Protocol.html deleted file mode 100644 index a266e82..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Link_Layer_of_Internet_Protocol.html +++ /dev/null @@ -1,50 +0,0 @@ -Link Layer of the Internet Protocol Suite - My Zettelkasten - - - - -

Link Layer of the Internet Protocol Suite

The Link Layer is the lowest level of the network stack that makes up the Internet Protocol Suite. It is concerned with the physical and logical connections between hosts on the same local network.

The physical and logical connections are known as Links.

Link Layer protocols goven communication between devices. Examples include:

  • WiFi
    • For wireless communication between devices using radio waves
  • Ethernet
    • Wired communication

All devices connected to the internet participate in the Link Layer since it is the base level and the gateway out of the local network to other networks. The same is not true for other layers. For example a device like a laptop participates in all four layers up to the Application Layer but a network router does not:

Link Layer diagram

MAC addresses

Each device on a link has a network address that uniquely identifies it. For most Link Layer Protocols this is a Media Access Control (MAC) address.

A device receives data addressed to its MAC address.

MAC addresses are limited to local networks. Remote networks cannot send data to a specific MAC address. This is off-limits from the outside.

Frames

Link Layer data is divided into small units called “frames”. The anatomy of a frame is as follows:

Link Layer frame

The header contains the source and destination MAC address plus a descriptor of the type of data it contains. The data is the payload. The footer is used to detect errors.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Linux_disk_partitions.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Linux_disk_partitions.html deleted file mode 100644 index 85e3982..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Linux_disk_partitions.html +++ /dev/null @@ -1,102 +0,0 @@ -Linux disk partitions - My Zettelkasten - - - - -

Linux disk partitions

A disk is divided up into partitions which are subsections of the overall disk. The kernel presents each partition as a block device as it would with an entire disk.

The disk dedicates a small part of its contents to a partition table: this defines the different partitions that comprise the total disk space.

Viewing current partitions

Whenever you install a Linux distribution on a real or virtual machine, you must partition the drive. There are three main tools to choose from: parted, g(raphical)parted, fdisk.

For a top-level overview of your disks and their main partitions you can run lsblk (list block devices):

$ lsblk
-
-NAME        MAJ:MIN RM   SIZE RO TYPE MOUNTPOINTS
-sda           8:0    0 465.7G  0 disk
-├─sda1        8:1    0   200M  0 part
-└─sda2        8:2    0 465.4G  0 part /run/media/thomas/ganesh
-nvme0n1     259:0    0 476.9G  0 disk
-├─nvme0n1p1 259:1    0   488M  0 part
-├─nvme0n1p2 259:2    0  27.9G  0 part /
-└─nvme0n1p3 259:3    0 448.5G  0 part /home

We can use parted -l to view the partition table for the current machine:

Model: SKHynix_HFS512GDE9X081N (nvme)
-Disk /dev/nvme0n1: 512GB
-Sector size (logical/physical): 512B/512B
-Partition Table: gpt
-Disk Flags:
-
-Number  Start   End     Size    File system  Name  Flags
- 1      1049kB  513MB   512MB   fat32              boot, esp
- 2      513MB   30.5GB  30.0GB  ext4
- 3      30.5GB  512GB   482GB   ext4

We can use fdisk -l to get slightly more info:

disk /dev/nvme0n1: 476.94 GiB, 512110190592 bytes, 1000215216 sectors
-Disk model: SKHynix_HFS512GDE9X081N
-Units: sectors of 1 * 512 = 512 bytes
-Sector size (logical/physical): 512 bytes / 512 bytes
-I/O size (minimum/optimal): 512 bytes / 512 bytes
-Disklabel type: gpt
-Disk identifier: 08175E77-CB9F-C34A-9032-DF29A3F8F0FE
-
-Device            Start        End   Sectors   Size Type
-/dev/nvme0n1p1     2048    1001471    999424   488M EFI System
-/dev/nvme0n1p2  1001472   59594751  58593280  27.9G Linux filesystem
-/dev/nvme0n1p3 59594752 1000214527 940619776 448.5G Linux filesystem

Standard Linux partitions

The two tools disclose that the main harddrive is /dev/nvme0n1 (equivalent to sda on older machines running Linux) and it has the standard three partitions:

  • Boot partition (/dev/nvme0n1p1)
  • Root dir (/dev/nvme0n1p2)
  • Home dir (/dev/nvme0n1p3)

Boot partition

  • Takes up the smallest amount of space
  • Contains the Linux kernel and the bootloader (GRUB, usually) and any other files required for booting.
  • Once the BIOS has initialized the hardware components it hands control to the bootloader stored in this partition.
  • The bootloader loads the kernel contained in its partition, into memory

Root partition (/)

  • This houses everything to do with the operation of the operating system apart from the initial booting process. Once the kernel is in memory it accesses the resources in the root partition to get the OS up and running. These resources include system libraries, utilities, system-wide configs and application software.

  • The root partition is vital for the system’s functionality. Without it, the system cannot boot or operate. It needs to be
    large enough to accommodate the operating system, installed programs, and system libraries, but it doesn’t need to store user data or
    additional applications, which can be located on other partitions.

  • This is the domain of the superuser. The part of the filesystem that you need sudo priveleges to access and where you manage users

Home partition

  • This is presented as /home/, i.e. that it is a descendent of /. But this is because the Linux file system is hierarchical. Typically /home/ is usually its own partition.
  • Separating user data and system data in this way protects user data during upgrades or reinstallation. Reinstalling or upgrading the OS can be done without affecting these files.
  • Each user has their own directory off of /home, e.g /home/thomas.
  • While the root partition (/) is essential for the operation of the OS, placing /home on a separate partition allows for better management of user data, enhancing the system’s flexibility and the user’s control over their own files, without compromising the integrity or performance of the OS. This approach exemplifies the Linux philosophy of giving the user control while maintaining a clear distinction between system
    resources and user data.

Types of partition table

In the Linux world there are two main types: MBR and GPT. The type of table used determines how the OS boots. So although partition tables are also responsible for the partitioning of non-bootable sectors of a disk, they are distinguished by the boot system they implement. If we look at the output from parted and fdisk above we see that the harddrive uses the GPT partition type.

Primary, extended and logical partitions

Most standard partition tables allow for primary, extended and logical partitions. The primary partition is the part of the harddisk that contains the operating system and is thus described as ‘bootable’ and may be called the ‘boot partition’. During the bootstrapping process this is injected into memory as the kernel.

The extended partition is basically everything other than the primary partition. This is typically subdivided into other partitions that are called logical partitions. This is because they physically reside in the same sector of the disk (the extended partition) but are treated as virtual and independent disks.

In our example above:

  • /dev/nvme0n1p1 is the primary/boot partition
  • /dev/nvme0n1p2 and /dev/nvme0n1p3 comprise the extended partition and by themselves are each logical partitions.
-
MBR
-
-
    -
  • Stands for Master Boot Record
  • -
  • Uses BIOS in the boot process
  • -
  • Can only works with disks up to 2TB in size
  • -
  • Only supports 4 primary partitions. This means the number of operating systems you install is limitied to this number.
  • -
  • This is the first 512 bytes of a storage device, preceding the first partition.
  • -
-
-
GPT
-
-
    -
  • Stands for GUID Partition Table
  • -
  • Gradually replacing MBR
  • -
  • Uses UEFI instead of BIOS
  • -
  • As name indicates, every partition on disk has its own globally-unique identifier
  • -
  • Vastly more partitions available than with MBR (dependent on operating system)
  • -
  • Offers greater recovery options and anti-corruption safeguards
  • -
-
-
-

Creating a Linux partition table

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/List_comprehension_in_Python.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/List_comprehension_in_Python.html deleted file mode 100644 index 431585b..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/List_comprehension_in_Python.html +++ /dev/null @@ -1,73 +0,0 @@ -List comprehension - My Zettelkasten - - - - -

List comprehension

List comprehension is a syntactic shorthand for applying a function to each element in a list without explicitly using loop syntax.

Since its introduction to the language, the same functionality has become achievable by using functional methods like map and filter, utilising lambdas however list comprehension is often more straightforward and easier to read.

Syntax

Here is a basic example which applies + 1 to each integer in a list:

values = [1, 2, 4, 6, 8, 9]
-
-new_values = [i + 1 for i in values]
-print('new_values', new_values)
-# new_values [2, 3, 5, 7, 9, 10]

The basic syntax is as follows:

new_list  = [expression for each member in an iterable]
  • The expression can be the member itself, a call to a method, or any other valid expression that returns a value. In the example above, the expression i + i adds one to each member value.

  • The member is the object or value in the list or iterable. In the example above, the member value is i.

  • The iterable is a list, set, dictionary or any other object that can return its elements one at a time. In the example above, the iterable is each value in values.

This is a much more condensed way of achieving the same outcome with a traditional loop:

values = [1, 2, 4, 6, 8, 9]
-new_list = []
-for i in values:
-  values.append(i+1)

Another example

In the following example, we apply list comprehension with a in range loop structure:

new_list = [i * i for i in range(10) ]
-print(new_list)
-# [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
-

Adding a condition

We can apply a conditional to a comprehension:

new_list = [item + 1 for item in values if item % 2 == 0]
-
-print('new_list:', new_list)
-# new_list: [3, 5, 7, 9]

Filters

By applying a condition (and no execution to each element) we effectively create a filter:

numbers = [1, 2, 3, 4, 4, 4]
-numbers_filtered = [i for i in numbers if i > 2]
-print(numbers_filtered)
-# [3, 4, 5]

For comparison, the same outcome could be achieved with a filter and lambda:

with_filter = list(filter(lambda x: x > 2, numbers))
-print(with_filter)
-# [3, 4, 5]

Set comprehension

We can also apply comprehension to sets. The syntax is practically identical but the difference is the resultant data structure will not contain duplicates.

numbers = [1, 2, 3, 4, 4, 4]
-unique =  {i for i in numbers}
-print(unique)
-# {1,2,3,4}

Dictionary comprehension

squares = {i: i * i for i in range(5)}
-print(squares)
-{0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Listing_and_navigating_directories_in_the_Shell.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Listing_and_navigating_directories_in_the_Shell.html deleted file mode 100644 index ee39dd1..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Listing_and_navigating_directories_in_the_Shell.html +++ /dev/null @@ -1,50 +0,0 @@ -Listing and navigating directories in the shell - My Zettelkasten - - - - -

Listing and navigating directories in the shell

Listing options

Obviously we know that in order to list the files and sub-directories in our current directory we use ls but here are some of the most useful of the different modifiers:

  • **ls -a**
    • list and include hidden dot files
  • **ls -l**
    • list with user permissions, file-size and date-modified (most detailed)
  • **ls ***
    • list organised by folders one level deep
  • cd -
    • Return to the directory you were last in
  • !!
    • Repeat the last command
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Lists_and_arrays_in_Bash.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Lists_and_arrays_in_Bash.html deleted file mode 100644 index c8bd91e..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Lists_and_arrays_in_Bash.html +++ /dev/null @@ -1,80 +0,0 @@ -Arrays in Bash - My Zettelkasten - - - - -

Arrays in Bash

We define an array as follows:

words=(here are some words)

We can also explicitly define an array using declare :

declare -a words=("element1" "element2" "element3")

Index notation

We access specific array elements by their index using the same braces style we use with variables:

echo "${words[2]}"
-
-# element3

Iterating through arrays

for i in "${words[@]}"
-do
-   echo "$i"
-   # or do whatever with individual element of the array
-done
-# element1 element2 element3

Note that @ here is a special symbol standing for all the members of the words array.

Sorting arrays

Sorting an integer array highests to lowest

sorted_array=($(echo "${array[@]}" | tr " " "\n" | sort -nr))

Where array is the name of the original array. The sorted array will be stored in the sorted_array array.

The sort command sorts the input in reverse numerical order (-n for numerical sort and -r for reverse sort). The tr command is used to convert the spaces in the array to newline characters so that each element is sorted on a separate line.

Pushing, appending to an array

We use the += shorthand to add elements to a preexisting array:

preExistingArray=(1 2 3)
-preExistingArray+=(4)
-echo preExistingArray
-# 1 2 3 4
-

Note that we have to put the item we want to addend within array brackets

Check if array empty

an_array=()
-
-if [ -z "${another_array[@]}" ]; then
-    echo "Array is empty"
-else
-    echo "Array is not empty"
-fi

Here we pass all the elements of the array to a test condition which tests for an empty string.

NB: This will not immediately work in the context of a function. See below.

Weirdness with functions

When you pass an array as an argument to a function it will not immediately be understood to be an array.

When we use $1 to individuate the first function argument this is read as string. So if you parsed an array argument as $1, any logic you have in the function will work on the assumption that the argument is a string, not an array.

To get round this we have to effectively redeclare the argument as an array before running any array logic. We do this through a nameref (a reference to a variable). The nameref resolves to the value of the variable it references. This allows you to indirectly manipulate the value of the original variable through the nameref.

A nameref is created with the -n flag. The following function uses this method to check if an array is empty:

function array_empty() {
-    declare -n arr=$1
-    if [ ${#arr[@]} -gt 0 ]; then
-        echo "array is not empty"
-    else
-        echo "array is empty"
-    fi
-}
-
-my_array=()
-array_empty "my_array"

You’ll notice when we invoke the function we pass the array as a string, this facilitates the nameref operation in the function.

Associational arrays / maps

With Bash 4 we gained an additional array-like data structure that is key-value based and similar to maps in other languages.

declare -A rock=(["win"]="scissors" ["lose"]="paper")

We would then individuate a value with "${rock[win]}"

Lists as implicit string arrays

When we use the term list in bash, we are not actually referring to a specific type of data structure. Instead a list variable is really just a normal variable wrapped in quote marks that has strings separated by spaces. Despite the fact that this is not an actual iterative data structure, we are still able to loop through variables of this type.

A_STR_LIST="cat dog hamster"
-AN_INT_LIST="1 2 3"

To iterate through a list variable, we can use a for loop:

for ele in $A_STR_LIST; do
-    echo $ele
-done

We are leveraging this aspect of Bash when we loop through each character in a string.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Lists_in_Python.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Lists_in_Python.html deleted file mode 100644 index 3e6cd3a..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Lists_in_Python.html +++ /dev/null @@ -1,117 +0,0 @@ -Lists in Python - My Zettelkasten - - - - -

Lists in Python

Lists are the equivalent of a simple array in JavaScript.

Lists have the following properties:

  • They are ordered
  • They are mutable and can be modified
  • They allow duplicate members
  • They are indexed
  • You can increase/decrease their length by adding/removing new members

Lists are denoted with [...]

Duplicating lists

When we want to duplicate a list, we can’t just reassign the list to a new variable and expect this to be a copy.

If we edit this “copy” it will update the original list since it copies the pointer and will therefore point to the same address in memory. Instead we have to use the List copy() function which returns a new list and doesn’t modify the original list.

Relatedly, we should distinguish those List methods and functions which create a new list (non-destructive) and those that mutate the existing list.

Basic usage

# Defining a list
-list1 = ['John', 'Paul', 'George', 'Ringo']
-list2 = [4]
-
-# Empty list
-list3 = []  # empty list
-list3 = list()  # Also empty list
-
-# Nested list
-list5 = [[2, 3], [6, 8]]

Slicing

list1 = ['John', 'Paul', 'George', 'Ringo']
-
-print(list1[1])
-print(list1[-1])
-print(list1[1:3])
-print(list1[:3])
-print(list1[1:])
-
-"""
-'John'
-'Ringo'
-['Paul', 'George']
-['John', 'Paul', 'George']
-['Paul', 'George', 'Ringo']
-"""

Adding additional values to existing list

Single value

list1 = ['John', 'Paul', 'George', 'Ringo']
-
-# Add single element to the end of a list
-list1.append('Pete')
-# ['John', 'Paul', 'George', 'Ringo', 'Pete']

Multiple values

list1.extend(['Albert', 'Bob'])
-list1 += ['Ginger', 'Sporty']
-# ['John', 'Paul', 'George', 'Ringo', 'Pete', 'Albert', 'Bob', 'Ginger', 'Sporty']

Specific index


-## Insert at specific index
-
-a_list = ['Adele', 'Madonna', 'Cher']
-a_list.insert(1, 'Paloma')
-print(a_list)
-
-# ['Adele', 'Paloma', 'Madonna', 'Cher']

Removing elements

We distinguish del from remove when removing elements from lists:

  • del requires an index value
  • remove requires a value reference (i.e. the name of the element rather than

del is simple deletion whereas remove searches the list. Therefore del is more efficient.

del

my_list = [10, 20, 30, 40, 50]
-del my_list[1]
-print(my_list)  # Output will be [10, 30, 40, 50]

We can remove multiple items at once via a slice:

my_list = [10, 20, 30, 40, 50]
-
-# Delete the elements from index 1 to 3 (inclusive of start index and exclusive of end index)
-del my_list[1:4]
-
-# Print the updated list
-print(my_list)  # Output will be [10, 50]

remove()

my_list = [10, 20, 30, 40, 50]
-
-# Remove the element with value 30
-my_list.remove(30)
-
-# Print the updated list
-print(my_list)  # Output will be [10, 20, 40, 50]

If the value is not found in the list, remove()`` will raise a ValueError. To avoid this, you can check whether the value exists in the list before calling remove()`

pop()

Remove and return the element removed

list6 = ['Once', 'Upon', 'a', 'Time']
-print(list6.pop(2))
-# a
-

Return index of a list element

list7 = [2, 3, 6, 8]
-print(list7.index(8))
-# 3
-
-list6 = ['Once', 'Upon', 'a', 'Time']
-print(list6.index('a'))
-# 2

Nesting lists

l1 = [1, 43.5, 'Phoebe', True]
-l2 = ['apple', 'orange', 31]
-root_list = ['John', l1, l2, 'Denise']
-print(root_list)
-# ['John', [1, 43.5, 'Phoebe', True], ['apple', 'orange', 31], 'Denise']

Merging (flattening) lists

list1 = [1, 2, 3]
-list2 = [4, 5, 6]
-
-merged_list = list1 + list2
-print(merged_list)  # Output: [1, 2, 3, 4, 5, 6]

See also

Sorting lists in Python

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Local_AWS_development_with_SAM.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Local_AWS_development_with_SAM.html deleted file mode 100644 index 314c4c7..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Local_AWS_development_with_SAM.html +++ /dev/null @@ -1,78 +0,0 @@ -Local AWS development with SAM - My Zettelkasten - - - - -

Local AWS development with SAM

We can run a local instance of our SAM stack for a given application without sending requests to the cloud. This is implemented through Docker.

The SAM CLI handles all the Docker-related tasks, such as pulling the required Lambda runtime images, creating containers, mounting your code and dependencies, and running your Lambda functions inside those containers.

Basic set up

Enter your project directory.

First build your SAM application:

sam build

We then run:

sam local start-api

If you have an API Gateway endpoint that you want to call over the local server. You will be able to call it after executing the above.

This will be indicated by:

If we want to invoke the function directly we use:

 sam local invoke [FunctionName]

Using environment variables

If you have an API key or database credentials, you are going to typically want to use different values dependent on environment.

Even if the values are the same accross environments, it’s a good idea to not call a secret when working locally since this request is billable.

In the example below I show how to set up environment variables for an API key locally and in production.

Create secret

Go to AWS SecretsManager and add the API key as a secret. This will be sourced in production.

Create local ENV file

These must be in JSON to work with SAM:

Local env

// local-env.json
-{
-  "FunctionName": {
-    "API_KEY": "xxx-yyy-xxx",
-    "NODE_ENV": "development"
-  }
-}

We save these to the root of the given function’s directory not at the global repo level.

Be sure to add this to .gitignore so that it does not become public

Update template.yaml

Every environment variable you intend to use, must exist in the template.yaml, otherwise it will not be sourced at runtime:

...
-Resources:
-  Properties:
-    Environment:
-      Variables:
-        SECRET_ARN: "arn:aws:secretsmanager:eu-west-2:885135949562:secret:wakatime-api-key-X9oF3v",
-        NODE_ENV: production
-        API_KEY:
-...

We go ahead and populate the values for production. But we leave the variable we use in development blank, since we don’t want it committed and we will source it at the SAM invocation. It still needs to exist though.

Pass in the environment variable at invocation:

sam local start-api --env-vars /home/thomas/repos/lambdas/wakatime-api/get-coding-stats/local-env.json

In production, the variables required will be automatically sourced from the template.yaml

Create handler within the Lambda itself

You are obviously going to need to distinguish between the different deployments when the Lambda executes. Here is an example helper function:

import * as AWS from "aws-sdk";
-
-const secretsManager = new AWS.SecretsManager();
-
-async function getApiKey(): Promise<string> {
-  if (process.env.NODE_ENV === "production") {
-    const response = await secretsManager
-      .getSecretValue({ SecretId: process.env.SECRET_ARN as string })
-      .promise();
-    const secretValues = JSON.parse(response.SecretString as string);
-    return secretValues.API_KEY;
-  } else {
-    return process.env.API_KEY as string;
-  }
-}
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Logarithms.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Logarithms.html deleted file mode 100644 index 7afb648..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Logarithms.html +++ /dev/null @@ -1,50 +0,0 @@ -Logarithms - My Zettelkasten - - - - -

Logarithms

Most simply a logarithm is a way of answering the question:

How many of one number do we need to get another number. How many of x do we need to get y

More formally:

x raised to what power gives me y

Below is an example of a logarithm:

$$ \log _{3} 9

$$

We read it:

log base 3 of 9

And it means:

3 raised to what power gives me 9?

In this case the answer is easy: \(3^2\) gives me nine, which is to say: three multiplied by itself.

Using exponents to calculate logarithms

This approach becomes rapidly difficult when working with larger numbers. It’s not as obvious what \(\log \_{5} 625\) would be using this method. For this reason, we use exponents which are intimately related to logarithms.

A logarithm can be expressed identically using exponents for example:

$$ \log _{3} 9 = 2 \leftrightarrow 3^2 = 9

$$

By carrying out the conversion in stages, we can work out the answer to the question a logarithm poses.

Let’s work out \(\log \_{2} 8\) using this method.

  1. First we add a variable (x) to the expression on the right hand:

    $$ \log _{2} 8 \leftrightarrow x

    $$

  2. Next we take the base of the logarithm and combine it with x as an exponent. Now our formula looks like this:

    $$ \log _{2} 8 \leftrightarrow 2^x

    $$

  3. Next we add an equals and the number that is left from the logarithm (8):

$$ \log _{2} 8 \leftrightarrow 2^x = 8

$$

Then the problem is reduced to: how many times do you need to multiply two by itself to get 8? The answer is 3 : 2 x 2 x 2 or 2 p3. Hence we have the balanced equation:

$$ \log _{2} 8 \leftrightarrow 2^3 = 8

$$

Common base values

Often times a base won’t be specified in a log expression. For example:

$$ \log1000

$$

This is just a shorthand and it means that the base value is ten, i.e that the logarithm is written in denary (base 10). So the above actually means:

$$ \log _{10} 1000 = 3

$$

This is referred to as the common logarithm

Another frequent base is Euler’s number (approx. 2.71828) known as the natural logarithm

An example

$$ \log _{e} 7.389 = 2

$$

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Logic_gates.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Logic_gates.html deleted file mode 100644 index 5c677fd..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Logic_gates.html +++ /dev/null @@ -1,56 +0,0 @@ -Logic gates - My Zettelkasten - - - - -

Logic gates

[A logic gate consists in] three connections where there may or may not be some electricity. Two of those connections are places where electricity may be put into the device, and the third connection is a place where electricity may come out of the device.

[J.C. Scott. 2009. But How Do It Know? The Basics of Computers for Everyone, 21]

Logic gates are the basic building blocks of digital computing. A logic gate is an electrical circuit that has one or more than one input and only one output. The input and output points of the gate are pins The input controls the output and the logic determining which types of input (on/off) lead to specific outputs (on/off) is isomorphic with the truth-conditions of the Truth-functional_connectives specifiable in terms of Truth-tables.

Physically, what ‘travels through’ the gates is electrical current and what constitutes the ‘gate’ is a transistor responding to the current. Going up a level of abstraction, the current/ charge is identified with a bit. It is bits that go into the gate and bits which come out: binary information that may be either 1 or 0.

Elementary and composite gates

We distinguish elementary from composite logic gates. An elementary gate is a single gate embodying a single logical connective. It cannot be reduced any lower as a logical abstraction. A composite gate is a gate made up of more than one elemen>tary gate and/or other composite gates.

An example of a composite gate would be a three-way AND. An AND with three inputs rather than the standard two that furnish the elementary AND gate. This gate would output 1 when all three gates have the value 1 and 0 otherwise. Adders and latche>s whilst being integrated circuits are also, technically speaking, composite gates.

Gate interface / gate implementation

The gate interface is an abstraction that the enables the user to think of the gate simply in terms of inputs and outputs, without being conc>erned with the technical details of how this is achieved. How it is achieved is the gate implementation.

We can demonstrate this with the earlier example of a three-way AND. The diagram below represents the gate as an interface:

// Add: Interface diagram

Whereas this diagram presents the implementation of the gate: it shows the specific combination of gates which creates the enables the behaviour represented in the interface diagram.

// Add: Implementation diagram

Importantly, a single interface may be implemented in a variety of ways. There is a one-to-many relationship at work here. From the point of view of the user interface these differences should not be detectable. This is another example of hardware abstraction

NOT gate

The NOT gate inverts the value of whatever input it receives

Truth conditions

\(P\)\(\lnot P\)
10
01

Interactive circuit

-

NAND gate

The NAND gate inverts the truth conditions of AND.

Symbol

Truth conditions

\(P\)\(Q\)\(\lnot(P \land Q)\)
110
100
010
001

Interactive circuit

-

NAND is a universal logic gate: equipped with just a NAND we can represent every other possible logical condition. In practice with circuits, it is more efficient to use specific dedicated gates (i.e OR, AND, NOT etc) for the other Boolean connectives but in principle the same output can be achieved through NANDs alone.

OR gate

The OR gate represents the truth conditions of the [disjunction](Truth-functional_connectives### Truth conditions.md#disjunction) truth functional connective

Symbol

Truth condition

Truth conditions

s

\(P\)\(Q\)\(P \lor Q\)
111
101
011
000

Interactive circui

Truth conditions

t

-

XOR gate

The OR gate represents the truth conditions of the exclusive OR

Symbol

Truth conditions

\(P\)\(Q\)\(\lnot(P \Leftrightarrow Q)\)
110
101
011
000

Interactive circuit

-

NOR gate

The NOR gate inverts the function of an OR gate

Symbol

Truth conditions

\(P\)\(Q\)\(P \lor Q\)
110
100
010
001

Interactive circuit

-
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Logical_consistency.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Logical_consistency.html deleted file mode 100644 index b3486a4..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Logical_consistency.html +++ /dev/null @@ -1,53 +0,0 @@ -Logical consistency - My Zettelkasten - - - - -

Logical consistency

Informal definition

A set of propositions is consistent if and only if it is possible for all the members of the set to be true at the same time. A set of propositions is inconsistent if and only if it is not consistent.

Demonstration

The following set of propositions form an inconsistent set:

  1. Anyone who takes astrology seriously is a lunatic.
  2. Alice is my sister and no sister of mine has a lunatic for a husband.
  3. David is Alice’s husband and he read’s the horoscope column every morning.
  4. Anyone who reads the horoscope column every morning takes astrology seriously.

The set is inconsistent because not all of them can be true. If (1), (3), (4) are true, (2) cannot be. If (2), (3),(4) are true, (1) cannot be.

Formal definition

A finite set of propositions \(\Gamma\) is truth-functionally consistent if and only if there is at least one truth-assignment in which all propositions of \(\Gamma\) are true.

Informal expression

The book is blue or the book is brown
-The book is brown

Formal expression

$$ -\{P \lor Q, Q\} -$$

Truth table

$ {P, Q} $ form a consistent set because there is at least one assignment when both propositions are true. In fact there are two (corresponding to each disjunct) but one is sufficient.

\(P\)\(Q\)$ P \lor Q $\(Q\)
TTTT
TFTF
FTTT
FFFF

Derivation

In terms of logical derivation, a finite \(\Gamma\) of propositions is inconsistent in a system of derivation for propositional logic if and only if a proposition of the form \(P \& \lnot P\) is derivable from \(\Gamma\). It is consistent just if this is not the case.

In other terms, if you can derive a contradiction from the set, the set is logically inconsistent.

A contradiction has very important consequences for reasoning because if a set of propositions is inconsistent, any other proposition is derivable from it.

A demonstration of the the consequences of deriving a contradiction in a sequence of reasoning.

Here we want to derive some proposition \(Q\). If we can derive a contradiction from its negation as an assumption then, by the negation elimination) rule, we can assert \(Q\). This is why contradictions should be avoided in arguments, they ‘prove’ everything which, by association, undermines any particular premise you are trying to assert.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Logical_equivalence.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Logical_equivalence.html deleted file mode 100644 index 561e936..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Logical_equivalence.html +++ /dev/null @@ -1,52 +0,0 @@ -Logical equivalence - My Zettelkasten - - - - -

Logical equivalence

Two sentences, P and Q, are truth-functionally equivalent if and only if there is no truth assignment in which P is true and Q is false

Informal expression

P: If it is raining then the pavement will be wet.

Q: The pavement is not wet unless it is raining.

Formal expression

$$ -(P \rightarrow Q) \longleftrightarrow (\lnot P \lor Q) -$$

Truth-tables

\(P\)\(Q\)$ P \rightarrow Q $$ \lnot P \lor Q$
TTTT
TFTF
FTTT
FFFT

Derivation

Propositions \(P\) and \(Q\) are equivalent in a system of derivation for propositional logic if \(Q\) is derivable from \(P\) and \(P\) is derivable from \(Q\).

Note that the property of equivalence stated in terms of derivablity above is identical to the derivation rule for the material biconditional:

bi-intro.png

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Logical_indeterminacy.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Logical_indeterminacy.html deleted file mode 100644 index 3011c94..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Logical_indeterminacy.html +++ /dev/null @@ -1,50 +0,0 @@ -Logical indeterminacy - My Zettelkasten - - - - -

Logical indeterminacy

The vast majority of propositions in natural and formal logical languages are **neither logically true or logically false**. This makes sense because propositions of this form are all either tautologies or contradictions and as such do not express information about the state of events in the world. We call propositions that are neither logically true or logically false, logically indeterminate propositions.

Informal definition

A proposition is logically indeterminate if it is neither logically true or logically false. This is to say: it can be both Consistency asserted and consistently denied.

For example the proposition:

It is raining.

May be true or false thus it can it both be asserted and denied quite consistently. It is true if it actually is raining and false if it actually is not raining. There is no logical contradiction implied by saying it is raining when it isn’t raining, this assertion is simply false. There is a contradiction in saying that both states obtain. Thus the proposition:

It is raining and it is not raining.

Cannot be consistently asserted as there is no possibility of the proposition being true. It is either raining or it isn’t raining. Given the law for conjunction, both conjuncts must be true for the proposition as a whole to be true. But in the case of this proposition if one conjunct is true, the other must be false and vice versa, hence it is not possible for the proposition to be true at all. It can only be false.

Contrariwise the proposition:

It is raining or it is not raining.

Cannot be consistently denied as there is no possibility of it being false. It is either raining or not raining. Given the law for disjunction, either disjunct can be true to make the proposition as a whole true. Given that it is either raining or not raining in either scenario, the proposition as a whole will be true. Therefore there is no possibility of it being false, it can only be true.

Formal definition

A proposition P is truth-functionally indeterminate if and only if it is neither truth-functionally true or truth-functionally false. should be avoided in arguments, they ‘prove’ everything whi

P

Truth-table

\(P\)\(P\)
TT
FF
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Logical_possibility_and_necessity.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Logical_possibility_and_necessity.html deleted file mode 100644 index a616c86..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Logical_possibility_and_necessity.html +++ /dev/null @@ -1,52 +0,0 @@ -Logical possibility and necessity - My Zettelkasten - - - - -

Logical possibility and necessity

Logical possibility

In distinguishing the properties of logical consistency and validity we make tacit use of the notion of possibility. This is because when we consider the validity of an argument we are assessing truth-conditions and this consists in asking ourselves what could or could not be the case: were it such that P, then it would be the case that Q. It is important to understand what possibility means in the context of logic and how it differs from what we might mean ordinarily when we use the term.

It is evident from the case of arguments that are valid but not sound that logic operates with a specialised notion of possibility. For example it has to be the case that the proposition Every woman can levitate is logically possible since the following argument is valid:

1.  P: Janice is a woman.
-2.  P: Every woman can levitate.
-3.  C: Janice can levitate.

But we know of course that women cannot levitate. When we assert that this is impossible we are relying on a stronger notion of possibility than logical possibility. It follows that the concept of possibility can have different degrees. The scope of the concept of possibility has been the concern of logicians and philosophers since at least the time of Plato and numerous different formulations exist. The notion that we mostly work with unreflectively in everyday life is nomological possibility. This means ‘governed by the application of laws’ where these laws pertain to our current understanding of the natural world as determined by physics. Levitation is therefore nomologically impossible but logically possible.

If logical possibility is not constrained by the laws of physics does it place any restrictions on what is possible? Logic applies a single restriction, the law of non-contradiction: a proposition cannot both be true and false at once. The following propositions are examples of a contradictory propositions.

Some examples of contradictions:

  • There is a dog that is not a dog
  • Today is Tuesday and today is not Tuesday
  • The cat that is dead is alive

From this we can derive the following property of logical possibility:

A proposition is logically possible just if it does not imply a contradiction.

Logical necessity

A proposition is logically necessary if it is true in every logically possible circumstance which is to say: true on every possible truth functional assignment. Necessity and logical truth are therefore synonyms: anything that is logically true (a tautology) is true by necessity (could not be otherwise.)

Further, every logical truth is logically possible but not everything that is logically possible is logically true. It is possible that it is raining but this is not logically necessary - it could be otherwise, i.e not raining. However it is not possible that it could be both raining and not raining.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Logical_truth_and_falsity.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Logical_truth_and_falsity.html deleted file mode 100644 index 91956dd..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Logical_truth_and_falsity.html +++ /dev/null @@ -1,59 +0,0 @@ -Logical truth and falsity - My Zettelkasten - - - - -

Logical truth and falsity

We say of certain propositions that they are logically true or logically false.

Logical falsity

Informal definition

A proposition is logically false if and only if it is not possible for the proposition to be true. The proposition itself cannot be consistently asserted.

Demonstration

There is a country that is not a country.
-Apples are fruits and apples are not fruits

Neither proposition can be true because the truth of the first clause is contradicted by the second. By the principle of consistency, it is not possible for both clauses to be true at once therefore the proposition, overall has the truth value of false.

It is raining and it is not raining.

Formal definition

A proposition P is truth-functionally false if and only if P is false on every truth-value assignment

Formal expression

$$ P \land \lnot P $$

Truth-table

\(P\)\(P \land \lnot P\)
TF
TF

Logical truth

Informal definition

A proposition is logically true if and only if it is not possible for the proposition to be false. The proposition itself cannot be consistently denied.

Demonstration

A rose is a rose.
-Today is Tuesday unless today is not Tuesday.

Regardless of any facts obtaining in the world, these propositions cannot be false.should be avoided in arguments, they ‘prove’ everything whi

As with logically false propositions, logical truth can also apply to compound propositions:

A rose is a rose and a shoe is a shoe

Formal definition

A proposition P is truth-functionally true if and only if P is true on every truth-value assignment

$$ P \lor \lnot P$$

Truth-table

\(P\)\(P \lor \lnot P\)
TT
FT

Consequences

The existence of logically false and logically true propositions affects the validity and soundness of arguments in which they are used. These are technicalities that have philosophically interesting consequences.

  • If an argument contains premises which are logically false than this argument will perforce be valid. This is because one cannot consistently assert the premises and deny the conclusion which is the definition of validity. However the reason why one cannot consistently assert the premises and deny the conclusions is because one cannot consistently assert the premises - they conflict with each other. Furthermore as the argument contains false premises, it cannot be sound.

    (P1) Russia is a country.
    -(P2) Russia is not a country
    -(P3) All countries have languages.
    -____________________________________________
    -(C) Russian is a language.
  • Any argument with a logically true conclusion is valid. Because the conclusion cannot be consistently denied it follows that we cannot consistently assert the premises and deny the conclusion. Whether or not the argument is sound remains an open question however. If the premises happen to be true then the argument will be sound on the strength of the conclusion being logically true but if the premises are false it will be unsound regardless of the truth of the conclusion.

    (P1) Horses have legs.
    -(P2) Animals with legs can move.
    -____________________________________________
    -(C) A horse is a horse
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Loops_in_Python.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Loops_in_Python.html deleted file mode 100644 index c743b2b..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Loops_in_Python.html +++ /dev/null @@ -1,97 +0,0 @@ -Loops in Python - My Zettelkasten - - - - -

Loops in Python

For

There are three main types of for loop in Python and they all use the for...in clause:

  1. Traditional for loop with range:

    for i in range(0, 5):
    -    print(i)

    This is equivalent to the following in JavaScript:

    for (let i = 0; i <= 5: i++) {
    -    console.log(i)
    -}
  2. for loop with iterable:

    fruits = ["apple", "banana", "cherry"]
    -for fruit in fruits:
    -    print(fruit)
  3. for loop with enumerate() function: Iterate over an iterable whilst also keeping track of the index of the current element:

    for index, fruit in enumerate(fruits):
    -    print(f"Index {index}: {fruit}")

Loop in increments greater than 1

The following loop increments by 2 on each iteration

for i in range(0, 10, 2):
-    print(i, ' ', end='')
-print()
-
-# 0  2  4  6  8

Break and continue

Break

num = int(input('Enter a number from 1-6 to check for: '))
-for i in range(0, 6):
-    if i == num:
-        break
-    print(i, ' ')

Continue

for i in range(0, 10):
-    print(i, ' ', end='')
-    if i % 2 == 1:
-        continue
-    print('hey its an even number')
-    print('we love even numbers')
-print('Done')
-
-"""
-0  hey its an even number
-we love even numbers
-1  2  hey its an even number
-we love even numbers
-3  4  hey its an even number
-we love even numbers
-5  6  hey its an even number
-we love even numbers
-7  8  hey its an even number
-we love even numbers
-9  Done
-"""

While

count = 0
-print('Starting')
-while count < 10:
-    print(count, '', end='')
-    count += 1
-
-print()  # not part of the while loop
-print('Done')
-
-"""
-Starting
-0 1 2 3 4 5 6 7 8 9
-Done
-"""

There are no do while loops in Python

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Loops_in_bash.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Loops_in_bash.html deleted file mode 100644 index e535454..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Loops_in_bash.html +++ /dev/null @@ -1,69 +0,0 @@ -Loops in Bash - My Zettelkasten - - - - -

Loops in Bash

Traditional for loop

for (( i=0; i<=5;i++  )); do
-  echo $i
-done
-
-# 1 2 3 4 5

for..in: loop through an array

for element in "${arr[@]}"
-do
-    echo "$element"
-done

While loop

while loops execute while a condition is true (0)

We can use a while loop as a condition in two senses:

  • execute while a given condition obtains
  • expand and execute a given command as long as the final command in the `while’ for the command has an exit status of zero (i.e. truthy)

Here is an exampe of using while in the former case:

declare -i n=0
-while (( n<10 ))
-do
-  echo "n:$n"
-  (( n++ ))
-done

Here is an example of using while in the latter case:

while read line;
-do
-    # something
-done < "$file_to_read"

Until loop

until loops execute until a condition is false (1)

declare -i m=0
-until (( m==10 )): do
-  echo "m:$m"
-  (( m++ ))
-done

This gives us the same output as n with the while loop but here it runs so long as m==10 is false. As soon as m is equal to 100, the condition becomes true and hence the loop stops.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/MAC_addresses.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/MAC_addresses.html deleted file mode 100644 index 3b6e4ad..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/MAC_addresses.html +++ /dev/null @@ -1,50 +0,0 @@ -MAC addresses - My Zettelkasten - - - - -

MAC addresses

A Media Access Control (MAC) address is a physical address in contrast to, say, an IP address which is logical.

Each device on a local network has a MAC as a unique identifier. It is a hardware-based, physical attribute of the device, typically permanently encoded onto a non-volatile memory chip attached to the network_card.

MAC addresses consist of 6 bytes (48-bits) represented as 12 hexadecimal_digits.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Machine_code.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Machine_code.html deleted file mode 100644 index e3c5083..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Machine_code.html +++ /dev/null @@ -1,50 +0,0 @@ -Machine code - My Zettelkasten - - - - -

Machine code

No matter how a program was originally written, it eventually needs to execute on a CPU as a series of machine language instructions.

Example machine instruction

The following machine instruction is an instruction that would be understood by an ARM ISA. It moves the number 4 into the r7 register:

11100011101000000111000000000100

This 32-bit line of binary has a series of instructions embedded within it. We partition each part of the sequence below, from left to right, mapping it to the instruction:

Binary sequenceInstructionAction
1110conditionalways execute (unconditional)
00
1immediatevalue is in the last 8 bits
1101opcodemov : move the value
0
0000
0111destination registerdestination is 0111 which means r7
0000
00000100immediate valuethe binary representation of decimal ‘4’
  • The blank zeros are also instructions, they are just not used in this instruction

  • The condition sequence tells us the instruction should run in all conditions not only under certain circumstances

  • The immediate bit (1) tells us whether the the value we are accessing is contained within the instruction or whether it is stored in a register. In this scenario 1 means the value is in the instruction. If it were 0, the register where the value is located would be specified elsewhere in the instruction (in one of the currently blank sequences).

  • The opcode correspoons to mov the value.

  • THe destination register details where the value should be moved to (r7)

  • Finally, the immediate value is equivalent to decimal 4

Difficulty

Binary sequences are hard to understand, even if converted to the Hexadecimal number system. We have a better way of managing operations on the machine level: assembly

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Magnetic_core_memory.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Magnetic_core_memory.html deleted file mode 100644 index e197aff..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Magnetic_core_memory.html +++ /dev/null @@ -1,50 +0,0 @@ -Magnetic core memory - My Zettelkasten - - - - -

Magnetic core memory

Like Magnetic_drum_memory, magnetic core memory was faster and more reliable than delay_line_memory and vacuum-tubes, and was also persistent. Thus it was used for volatile memory as well as storage.

It worked as follows. Magnetic beads made of ferrite and threaded with copper were arranged in a crisscross grid. A bead would be placed at the overlap of two copper threads. This constitutes a “core”.A pulse of electric current would magnetise/de-magnetise the cores.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Magnetic_drum_memory.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Magnetic_drum_memory.html deleted file mode 100644 index 951354a..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Magnetic_drum_memory.html +++ /dev/null @@ -1,50 +0,0 @@ -Magnetic drum memory - My Zettelkasten - - - - -

Magnetic drum memory

Along with the Williams_Tube, another early approach to RAM used in 1950s-1960s era of computing.

Magnetic drum

A magnetic drum was a metal cylinder coated with a magnetic material. Data was stored by magnetising small regions on the drum’s surface. The drum would rotate at high speeds and read/write heads were positioned along the length of the drum to access data.

Seen as a improvement on Williams Tubes and delay line memory but superseded by magnetic core memory later. It’s concept lived on in harddisk drives which became the dominant form of secondary storage.

It had a larger capacity than the technologies that preceded it and it was also non-volatile - the data would remain intact when the power was turned off.

It was used in the IBM 650 (1953) and Ferranti Mark I (1951)

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Magnetic_tape.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Magnetic_tape.html deleted file mode 100644 index cf8a5c1..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Magnetic_tape.html +++ /dev/null @@ -1,50 +0,0 @@ -Magnetic tape - My Zettelkasten - - - - -

Magnetic tape

Used for data storage in early digital computers (broadly from the UNIVAC) era until the mini-computer era.

While the UNIVAC was not the first to use magnetic tape, it popularised the method due to its success and high profile.

Magnetic tape reader in IBM computer

It worked as follows. The tape was a long, narrow strip of plastic coated with a magnetic material. Data is recorded on the the tape by magnetising tiny particles on its surface. It was first used in the 1920s for audio recording.

Data is accessed in a linear, sequential manner. To reach a specific piece of data, you often need to wind through all the preceding data

It was used for long term storage rather than RAM memory due to its sequential nature. It stored data and program instructions that would be read into the machine’s memory. Data was also written out to magenetic tape, in order to store and further process results.

It could store more data than punched cards and its sequential nature accommodated batch processing well. However its sequential nature meant it was slow at retreiving specific pieces of data as it would have to cycle through all the values stored on the tape.

Magnetic tape stored as casette

It developed from open-reel tapes to cartridges and cassettes. It was superseded by hard disk drives and solid state drives.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Mainframe_computers.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Mainframe_computers.html deleted file mode 100644 index 23ffe46..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Mainframe_computers.html +++ /dev/null @@ -1,50 +0,0 @@ -Mainframe computers - My Zettelkasten - - - - -

Mainframe computers

A mainframe computer, also known as a “big iron” is a high performance computer used for resource-intensive tasks that require greater security and availability than smaller scale machines. They are typically used for centralised rather than distributed computing.

The heyday of mainframes was before the mini- and micro-computer revolution but they are still used.

IBM remains the main manufacturer and service provider for mainframes. Example use cases include banks who need to process large volumes of transatction and high frequency tranding; government departments, the military and internal revenue who require huge databases.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Managing_environments_in_NodeJS.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Managing_environments_in_NodeJS.html deleted file mode 100644 index 2cb80c7..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Managing_environments_in_NodeJS.html +++ /dev/null @@ -1,62 +0,0 @@ -Managing environments - My Zettelkasten - - - - -

Managing environments

With a full-scale Node application you will typically run three environments:

  • Development
  • Testing
  • Production

Accessing the current environment

To determine the current environment we can use the variable process.env.NODE_ENV from the Process_object. This works universally regardless of the kind of Node app we are building.

If you have not manually set up your environments, process.env.NODE_ENV will return undefined.

Setting the Node environment

For the session

NODE_ENV is a bash environment variable like any other. So we can set it in the normal way:

export NODE_ENV=production

In Express

In Express, there is a built in method for retrieving the current envrionment: app.get('env'). Express will default to the development environment.

! How to keep Express and Node environment in sync?

-

Configuring environments

We use the third-party node-config package to manage different configurations based on the environment.

Once installed we set up a dedicated config directory with a structure as follows:

config/
-    default.json
-    development.json
-    production.json

For example:

// default.json
-{
-  "name": "My Express app"
-}

Then to utilise config variables:

const config = require("config");
-console.log("Application name:" + config.get("name"));

If we toggled the different environments, we would see different outputs from the above code (assuming we had different config files in /config with different names).

Sensitive config data

We will need to store passwords, API keys and other kinds of authentication data for our application. We obviously shouldn’t store this data openly in our config files since it would be made public.

We can do so securely by utilising environmental variables alongside the config pacakage.

We create a file called custom-environment-variables (must be called this) and map a property to an environmental environment we have already set.

Let’s create an environmental variable for a password:

export APP_PASSWORD='mypassword123'

Then in our custom variable file:

{
-  "password": "APP_PASSWORD"
-}

We can then safely reference this value in the course of our normal code:

console.log(config.get("password"));

! But how would this be achieved in a production server?

-

! And how could we do this programmatically at the start of a local development session without manually setting each environment variable in the terminal?

-
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Map_and_filter_in_Python.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Map_and_filter_in_Python.html deleted file mode 100644 index c41d7da..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Map_and_filter_in_Python.html +++ /dev/null @@ -1,74 +0,0 @@ -Map and filter in Python - My Zettelkasten - - - - -

Map and filter in Python

Map

data = [1, 3, 5, 2, 7, 4, 10]
-
-new_data = map(lambda i: i + 10, data)
-print(new_data)

We can also pass-in a function rather than use a lambda:

def add_one(i):
-    return i + 1
-
-x = list(map(addOne, data))
-# [2, 4, 6, 3, 8, 5, 11]
-# necessary to add `list` to get some output

Map returns an object

When you run map against a list it returns a map object not a list. This can present problems if you are not aware of it since it is not an entity that you can loop through.

The following map removes whitespaces from elements in a list:

  lines = map(lambda x: x.strip(), lines)

In order to be able to run list-like operations against the resulting lines object we would need to convert it to a list:

  lines = list(map(lambda x: x.strip(), lines))

Filter

data = [1, 3, 5, 2, 7, 4, 10]
-
-d1 = list(filter(lambda i: i % 2 == 0, data))
-print(d1)
-#  [2, 4, 10]
-
-def is_even(i):
-    return i % 2 == 0
-
-
-# Filter for even numbers using a named function
-d2 = list(filter(is_even, data))
-
-# [2, 4, 10]

Chaining

data = [1, 3, 5, 2, 7, 4, 10]
-new_data = list(map(lambda i: i + 10, filter(is_even, data)))
-print(new_data)
-# new_data: [12, 14, 20]
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Map_and_filter_to_reduce_in_JS.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Map_and_filter_to_reduce_in_JS.html deleted file mode 100644 index 0145955..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Map_and_filter_to_reduce_in_JS.html +++ /dev/null @@ -1,65 +0,0 @@ -Expressing combined map and filter operations to a single reduce - My Zettelkasten - - - - -

Expressing combined map and filter operations to a single reduce

map + filter

The following combines a map and a filter to square a list of numbers and then filter the ones that are greater than or equal to 10:

const arr = [1, 2, 3, 4];
-
-const filteredSquaredNumbers = arr.map((x) => x * x).filter((y) => y >= 10);

Using reduce we can combine these operations more concisely:

const filteredSquaredNumbers = arr.reduce((acc, x) => {
-  const squared = x * x;
-  if (squared >= 10) {
-    acc.push(squared);
-  }
-  return acc;
-}, []);

filter + map

Here we use a filter and then a map to filter the even numbers and then double them:

const arr = [1, 2, 3, 4];
-
-const evenDoubled = arr.filter((x) => x % 2 === 0).map((y) => y * 2);

Using reduce :

const evenDoubled = arr.reduce((acc, x) => {
-  if (x % 2 === 0) {
-    acc.push(x * 2);
-  }
-  return acc;
-}, []);

The empty array [] is the initial value of the accumulator. As the callback function processes each element of the array, it can add or modify the accumulator based on the desired logic. By providing an empty array as the initial value for the accumulator, we ensure that the results will be collected in a new array without modifying the original array.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Mapped_types_in_TS.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Mapped_types_in_TS.html deleted file mode 100644 index 257a16e..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Mapped_types_in_TS.html +++ /dev/null @@ -1,119 +0,0 @@ -Mapped types in TypeScript - My Zettelkasten - - - - -

Mapped types in TypeScript

A mapped type is a way to create new types based on existing ones by transforming their properties

As it works on a single type and typically narrows or limits the properties it works in a way that is opposite to a union or intersection type.

Mapped types are an example of when type is preferable to interface, since you cannot generate mapped types as interfaces, although you may generate a mapped type from an interface.

For the demonstrations we will use the following type as the example that we will map from:

type Person = {
-  name: string;
-  age: number;
-  city: string;
-  country: string;
-};

Main varieties of mapped types

Read only

Creates a type with all properties of the given type set to readonly:

type Readonly<T> = {
-  readonly [P in keyof T]: T[P];
-};
-
-type ReadonlyPerson = Readonly<Person>;

This is equivalent to:

type ReadonlyPerson = {
-  readonly name: string;
-  readonly age: number;
-  readonly city: string;
-  readonly country: string;
-};

Partial

Creates a type with all properties of the given type set to optional.

type Partial<T> = {
-  [P in keyof T]?: T[P];
-};
-
-type PartialPerson = Partial<Person>;

This is equivalent to:

type PartialPerson = {
-  name?: string;
-  age?: number;
-  city?: string;
-  country?: string;
-};

Pick

This is useful when you want to create a new type based on a subset of properties from an existing type.

type Pick<T, K extends keyof T> = {
-  [P in K]: T[P];
-};
-
-type PersonNameAndAge = Pick<Person, "name" | "age">;

This is equivalent to:

type PersonNameAndAge = {
-  name: string;
-  age: number;
-};

Record

Creates a type with keys of the given type and values of the specified type. It is a way of shoehorning keys from an existing type with new values.

Basic syntax:

Record<Keys, ValueType>;

Example:

type UserRole = "admin" | "user" | "guest";
-
-// Create a Record type to store user role descriptions
-type UserRoleDescriptions = Record<UserRole, string>;
-
-// Create an object that implements the UserRoleDescriptions type
-const roleDescriptions: UserRoleDescriptions = {
-  admin: "Has full access to the system",
-  user: "Can access limited resources",
-  guest: "Can view public resources only",
-};

Here is a simpler example

type Person = {
-  name: string;
-  nationality: string;
-};
-
-type PersonInstance = Record<string, Person>;
-const thomasInstance: PersonInstance = {
-  thomas: {
-    name: "Thomas",
-    nationality: "British",
-  },
-};

Exclude

Creates a type by excluding specific properties from the given type.

type Exclude<T, U> = T extends U ? never : T;
-
-type KeysWithoutAge = Exclude<keyof Person, "age">;

This is equivalent to:

type KeysWithoutAge = "name" | "city" | "country";

Extract

Creates a type by extracting specific properties from the given type. Basically the opposite operation to Exclude.

type Extract<T, U> = T extends U ? T : never;
-
-type NameKey = Extract<keyof Person, "name">;

This is equivalent to:

type NameKey = "name";

Non-nullable

Creates a type by removing null and undefined from the given type.

type NonNullable<T> = T extends null | undefined ? never : T;
-
-type NullablePerson = {
-  name: string | null;
-  age: number | null;
-  city: string | null;
-  country: string | null;
-};
-
-type NonNullablePerson = NonNullable<NullablePerson>;

Equivalent to:

type NonNullablePerson = {
-  name: string;
-  age: number;
-  city: string;
-  country: string;
-};
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Maps_and_sets_in_JS.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Maps_and_sets_in_JS.html deleted file mode 100644 index 2d901e6..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Maps_and_sets_in_JS.html +++ /dev/null @@ -1,109 +0,0 @@ -Maps and Sets - My Zettelkasten - - - - -

Maps and Sets

Both Map and Set are new data structures introduced with ES6. They combine the properties of the pre-existing data structures: arrays and objects and offer advantages in certain non-typical use cases.

Maps

Concepts

A map (not to be confused with the array map method) introduces something like the associative array model to JavaScript. Prior to ES6 the closest thing JS had to this was an object.

Maps are like objects in that their structure consists in key/map pairs but like arrays in that the order in which the entries are placed is retained and can be referred to throughout the lifecycle of the Map. Also, the length of the Map is a known and easily returnable quantity, with objects we have to do some wrangling with Object.keys and Object.entries to retrieve meta data about the object itself. Moreover, with an object the order in which the keys are stored is not recorded.

At the same time Maps are different from arrays because the index of an array element is not unique, it will always be a number of the form [0], [1], [2]... .

Finally, the key can be any data type not just a string. This is an important characteristic of maps because although you can use numbers or booleans as the keys in an object, they are not actually numbers, they are converted to strings at execution. With Maps, whatever data type you assign as a key, retains its type.

Maps

  • Have key/value pair structure
  • Have length property
  • Order of entries and insertions is maintained
  • Can use any data type as a key
  • Disallow duplicate keys

Creating a Map and adding entries

const map = new Map();
-
-// We then pass in key/value pairs using `set`:
-map.set("firstName", "Luke");
-map.set("lastName", "Skywalker");
-map.set("occupation", "Jedi Knight");

There is an alternative method for defining a map:

const map = new Map([
-  ["firstName", "Luke"],
-  ["lastName", "Skywalker"],
-  ["occupation", "Jedi Knight"],
-]);

Internally, this data will be represented as follows:

Map(3)
-0: {"firstName" => "Luke"}
-1: {"lastName" => "Skywalker"}
-2: {"occupation" => "Jedi Knight"}

Working with map elements

// check for the existence of an item in a map by searching for existence of key
-map.has("firstName"); // return boolean
-
-// return all keys in a Map as iterator
-map.keys(); // MapIterator {'firstName', 'lastName', 'occupation'}
-
-// return all values as iterator
-map.values();
-
-// return array of key/value pairs
-map.entries(); // {"firstName" => "Luke", "lastName" => "Skywalker", "occupation" => "Jedi Knight"}
-// retrieve an item from a Map
-map.get("lastName"); // Skywalker
-
-// delete an item from a map by key, returns boolean as confirmation
-map.delete("occupation"); // true
-
-//return the length of a map (just like array.length)
-map.size; // 3
-// clear all values
-map.clear();

Looping

// Map has its own .forEach method, like with arrays. Hewre they are side by side
-
-// Map
-Map.prototype.forEach((value, key, map) = () => {})
-
-// Array
-Array.prototype.forEach((item, index, array) = () => {})
-
-// You can also use a for of loop
-// Destructure the key and value out of the Map item
-for (const [key, value] of map) {
-  // Log the keys and values of the Map with for...of
-  console.log(`${key}: ${value}`)
-}

Interfacing between Maps and other reference types

Given that we can create a map with both object and array-style syntax, its easy to convert maps to and from the more established data structures.

It’s easy to convert an object to a map:

const luke = {
-  firstName: "Luke",
-  lastName: "Skywalker",
-  occupation: "Jedi Knight",
-};
-
-const map = new Map(Object.entries(luke));

And a map to an object:

const obj = Object.fromEntries(map);

A map to an array:

const arr = Array.from(map);

We saw earlier that a Map is a multidimensional array, so any multidimensional array can be used in the Map constructor invocation to turn it into a Map.

Sets

A set is special kind of array, an atypical supplement to arrays. It is basically an array of unique values. If you try to add a duplicate entry to a set it will be ignored.

const set = new Set();
-set.add("Beethoven");
-set.add("Bach");
-
-// Or:
-const set = new Set(["Beethoven", "Bach"]);
-
-// Convert array to set (note, this will remove duplicates on initialisation)
-const arr = [...set];

We can use keys(), values(), and entries() with sets but obviously, keys and values will be identical.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Match_statements_in_Python.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Match_statements_in_Python.html deleted file mode 100644 index 2a0fd2b..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Match_statements_in_Python.html +++ /dev/null @@ -1,81 +0,0 @@ -Match statements in Python - My Zettelkasten - - - - -

Match statements in Python

A match statement is the equivalent of a switch or case statement in Python

command = input("What are you doing next? ")
-
-match command:
-    case "quit":
-        print("Goodbye!")
-    case "look":
-        print("Looking out")
-    case "up" | "down":
-        print("up or down")
-    case _:
-        print("The default")
-
-"""
-What are you doing next? up
-up or down
-"""
-
-match command.split():
-    case ["go", "left"]:
-        print("go left")
-    case ["go", ("fast" | "slow")]:
-        print("go fast or slow")
-
-point = (3, 3)
-match point:
-    case (x, y) if x == y:
-        print(f"The point is located on the diagonal Y=X at {x}.")
-    case (x, y):
-        print(f"Point is not on the diagonal.")
-"""
-The point is located on the diagonal Y=X at 3.
-"""
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Matter_and_atoms.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Matter_and_atoms.html deleted file mode 100644 index 371957a..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Matter_and_atoms.html +++ /dev/null @@ -1,50 +0,0 @@ -Matter and atoms - My Zettelkasten - - - - -

Matter and atoms

Matter, elements, compounds and mixtures

  • Matter is anything that occupies space and has weight. It may be found in any one of three states: liquid, solid, or gas.
  • Matter can be classed in terms of elements, compounds and mixtures.
    • An element is a substance that cannot be reduced to a simpler substance by chemical means.
    • The chemical combination of two or more elements is a compound. Compounds can be separated or reduced by chemical means but they cannot be physically separated.
    • A physical (note not chemical) combination of elements and compounds is a mixture.
    • For example “air” is a mixture which is made up of oxygen, nitrogen, carbon dioxide, and other gases.

Atoms and molecules

  • Elements are made up of atoms.
  • A molecule is a type of compound where the atoms of two types of elements have joined together. For example sodium and chlorine are two elements that can join to form sodium chloride. We call this chemical bonding.

Atomic particles

  • There are three particles comprising atoms: protons, neutrons and electrons.

  • Protons and neutrons comprise the nucleus of the atom. A proton is positively charged. A neutron has no charge.

  • Electrons orbit around the nucleus in concentric rings. Electrons are negatively charged. Because of this protons and electrons attract each other.

Atomic number

  • The number of protons in the nucleus is called the element’s atomic number.
  • We use the atomic number of elements to distinguish one element from another.

Atomic weight

  • The atomic weight of an atom is its mass.
  • The mass is determined by the number of protons and neutrons in the nucleus.
  • An electron \(\frac{1}{1845}\) the mass of a proton. Its mass is so neglible that it makes no significant difference to the atomic weight.
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Memoization_in_React.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Memoization_in_React.html deleted file mode 100644 index 8124987..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Memoization_in_React.html +++ /dev/null @@ -1,79 +0,0 @@ -Memoization with useCallback and useMemo - My Zettelkasten - - - - -

Memoization with useCallback and useMemo

Rationale

In the lifecycle of a component, React re-renders the component when an update is made. When React checks for any changes in a component, it may detect an unintended or unexpected change due to how JavaScript handles equality and shallow comparisons. This change in the React application will cause it to re-render unnecessarily.

Additionally, if that re-rendering is an expensive operation, like a long for loop, it can hurt performance. Expensive operations can be costly in either time, memory, or processing. In addition to potential technical issues, this may lead to poor user experience.

If one part re-renders, it re-renders the entire component tree. useCallback and useMemo can be used reduce this performance impact.

useCallback

The useCallback hook is used to wrap functions. It tells React to not re-create a wrapped function when a component re-renders, unless any of the useCallback’s dependencies change.

useCallback returns a memoized version of the callback function it is passed. This means that the function object returned from useCallback will be the same between re-renders.

Remember that in JavaScript, functions are objects and components are functions. As a result, every time a component containing a function re-renders, it create a new instance of the function in memory.

Given the same dependency value, the useCallback hook returns the same function instance between renderings (aka memoization).

This said, for small functions that are not intensive, it doesn’t really matter if they are not memoized.

Syntax

A standard case of this would be a function that runs on a button click, for instance when sending data from a form to a server. In the example below there is quite a lot going on, and most of it is independent of the actual UI-cycle of the component.

const handleSubmit = useCallback(
-  async (formValues) => {
-    setPendSaveConfig(true);
-    const payload = new GenerateConfig({
-      workflowId: project_id,
-      blockId: blockId,
-      config: formValues,
-    });
-    axios
-      .post(`${process.env.REACT_APP_ENDPOINT}/save-block-config`, payload)
-      .then((res) => console.log(res))
-      .finally(() => setPendSaveConfig(false))
-      .catch((err) => console.error(err));
-  },
-  [blockId, project_id]
-);

Note that the syntax is similar to React_useEffect: there is a dependency array. The effect is the same: the function contained within useCallback will only re-rendered if one of these dependencies changes. However (see next section) the function will run in its memoized form on every click.

Reference versus result

useCallback only memoizes the function object (the reference) not the value that is returned by the function (the result).

In the example below, the calculatePi() function reference will not change between renders but each time the click event fires, the value returned by calculatePi() will change. In other words, it will be assigned fresh memory.

function ParentComponent() {
-  const onHandleClick = useCallback(() => {
-    const special = calculatePi();
-  });
-
-  return <SubComponent handleClick={onHandleClick} />;
-}

Use cases

You should not apply useCallback in a blanket fashion, this can reduce performance rather than improve it. The best scenarios are:

  1. A functional component wrapped inside React.memo() accepts a function object prop

  2. When the function object is a dependency to other hooks, e.g. useEffect(..., [callback])

  3. When the function has some internal state, e.g. when the function is debounced or throttled.

useMemo

We can think of useMemo as a complement to useCallback. The main difference is that whilst useCallback memoizes the function reference, useMemo memoizes the function result; the value that is returned.

In memoization, the result is “remembered” when the same parameters are passed-in subsequently. If we have a function compute 1 + 1, it will return 2. But if it uses memoization, the next time we run 1’s through the function, it won’t add them up; it will just remember the answer is 2 without executing the adding function.

Like useCallback, useMemo takes a function and an array of dependencies for the same reason: if one of the dependencies changes then the function will recalculate (and re-memoize) the result but they don’t the same memoized value will be returned.

As with useCallback, useMemo is best applied to complex functions that are computationally expensive, it shouldn’t be used indiscriminately.

It should not be used with asynchronous functions, in these instances, useEffect would be a better choice.

Syntax

const List = React.useMemo(
-  () =>
-    listOfItems.map((item) => ({
-      ...item,
-      itemProp1: expensiveFunction(props.first),
-      itemProp2: anotherPriceyFunction(props.second),
-    })),
-  [listOfItems]
-);
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Memory_Management_Unit.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Memory_Management_Unit.html deleted file mode 100644 index 83367a6..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Memory_Management_Unit.html +++ /dev/null @@ -1,50 +0,0 @@ -Memory Management Unit (MMU) - My Zettelkasten - - - - -

Memory Management Unit (MMU)

The MMU is the bridge between the physical memory devices of the machine and the virtual memory space. It is a chip that sits between the CPU and the RAM and determines the physical location of the memory requested by the kernel as virtual memory.

Virtual memory diagram

Pages

We use the term pages to denote blocks of virtual memory and to distinguish them from addresses as physical blocks. The MMU possesses a page table which is registry logging which pages correspond to which physical blocks.

Shared pages

Virtual memory allows the sharing of files and memory by multiple processes. Crucially the shared data doesn’t have to be within the address of each process, instead there is a reference in the page table that each process has access to the shared data.

Page faults

There are two kinds of error that can occur with relation to paged memory:

  • minor page faults
    • The desired page is in main memory but the MMU doesn’t currently know where it is
  • major page faults
    • The desired page is not in main memory at all. Therefore the kernel must fetch it from disk

Minor page faults are very common and are to be expected; they resolve quickly. On the other hand too many major page faults can slow the system down both because of the time-costly process of fetching data from disk and because it demands more kernel resources to locate the missing page, which puts other processes on hold.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Memory_addresses.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Memory_addresses.html deleted file mode 100644 index 88535d9..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Memory_addresses.html +++ /dev/null @@ -1,50 +0,0 @@ -Memory addresses - My Zettelkasten - - - - -

Memory addresses

Computers assign numeric addresses to bytes of memory and the CPU can read or write to those addresses

We can think of the internals of RAM as grids of memory cells.

Each single-bit cell in the grid can be identified using two dimensional coordinates, like in a graph. The coordinates are the location of that cell in the grid.

Handling one bit at a time isn’t very efficient so RAM accesses multiple grids of 1-bit memory cells in parallel. This allows for reads or writes of multiple bits at once, such as a whole byte.

The location of a set of bits in memory is known as a memory address.

Demonstration

Let’s imagine we have a computer system that can address up to 64KB of memory and our system is byte addressable. This means there are \(64 \cdot 1024 = 65,536\) bytes of memory because 1KB = 1024 bytes.

We therefore have 65,536 addresses and each address can store one byte. So our addresses go from 0 to 65, 535.

We now need to consider how many bits we need to uniquely represent an address on this system.

What does this mean? Although there are approximately 64 thousand bytes of memory, to refer to each byte we can’t just use 1, 2, 3… because computers use binary numbers. We need a binary number to refer to a given byte in the the 64KB of memory. The question we are asking is: how long does this binary number need to be to be able to represent each of the 64 thousand bytes?

1 bit can represent two addresses: 0 and 1. 2 bits can represent four addresses: 00, 01, 10, 11. The formula is as follows: number of addresses = \(2^n\) where \(n\) is the number of bits.

We need to reverse this formula to find out how many bits we need to represent a given number of addresses. We can do this with a logarithm.

We can reverse the formula as follows: number of bits = \(\log_2\) (number of addresses).

In our case we have 65,536 addresses so we need \(\log_2(65,536)\) bits to represent each address. This is approximately 16 bits. Thus a 16 bit memory iaddress is needed to address 65, 546 bytes.

Using memory addresses we end up with tables like the following:

Memory addressData
00000000000000001010101010101010
00000000000000010010001001001011
00000000000000100010001001001010

This is hard to parse so we can instead use hexadecimal numbers to represent the addresses:

Memory address (as hex)Data (as binary)
0x00001010101010101010
0x00010010001001001011
0x00020010001001001010

By itself, the the data is meaningless but we know from binary encoding that the binary data will correspond to some meaningful data, such as a character or a colour, depending on the encoding scheme used. The above table could correspond to the characters for ‘A’, ‘B’ and ‘C’ in the ASCII encoding scheme:

Memory address (as hex)Data (as binary)Data (as ASCII)
0x00001010101010101010A
0x00010010001001001011B
0x00020010001001001010C
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Memory_leaks.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Memory_leaks.html deleted file mode 100644 index e5615ea..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Memory_leaks.html +++ /dev/null @@ -1,50 +0,0 @@ -Memory leaks - My Zettelkasten - - - - -

Memory leaks

A memory leak occurs when you program memory and forget to delete it once you are finished. The consequences of memory leak is that it reduces the performance of the computer by reducing the amount of available memory. Eventually, in the worst case, too much of the available memory may become allocated and all or part of the system or device stops working correctly, the application fails, or the system slows down vastly.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Memory_versus_processor.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Memory_versus_processor.html deleted file mode 100644 index 4bd4b4d..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Memory_versus_processor.html +++ /dev/null @@ -1,50 +0,0 @@ -Memory versus processor - My Zettelkasten - - - - -

Memory versus processor

Would a more powerful processor with average or reduced memory capacity perform better than, equal to, or less than a less powerful processor with more memory, in principle?

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Messaging_services.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Messaging_services.html deleted file mode 100644 index a98dc86..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Messaging_services.html +++ /dev/null @@ -1,50 +0,0 @@ -AWS Messaging services - My Zettelkasten - - - - -

AWS Messaging services

SQS

SQS: Simple Queue Service

SQS is a service that allows you to send, store and receive messages between apps and software components built in AWS, with automatic encryption. It helps with decoupling and scaling.

As the name indicates, its operating mode is that of a queue data structure offering first-in, first-out and other queue implementations.

An example application of this would be to set up an SQS queue that receives messages and triggers a lambda whenever a new message is added.

SNS

SNS: Simple Notification Service

Similar to SQS but the focus is on notifications rather than messages, i.e events that fire when something specific happens, not just a message-send event. It can be used for passing notifications between applications or to persons through SMS, text, push notifications and email.

SNS pushes messages out to subscribers while SQS stores the messages until someone reads them.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Middleware_in_NodeJS.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Middleware_in_NodeJS.html deleted file mode 100644 index 825a447..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Middleware_in_NodeJS.html +++ /dev/null @@ -1,64 +0,0 @@ -Middleware - My Zettelkasten - - - - -

Middleware

What is middleware?

  • Anything that terminates the req, res cycle counts as middleware. It is basically anything that acts as an intermediary once the request is received but before the resource is sent. A good example would be the app.use(express.json() or app.use(bodyParser.json) functions we call in order to be able to parse JSON that is sent from the client.
  • You will most likely have multiple middleware functions running at once. We call this intermediary part of the cycle the request processing pipeline.
  • Generally all middleware will be added as a property on the Express app instance with the app.use(...) syntax.

Creating custom middleware functions

Basic schema

app.use((req, res, next) => {
-  // do some middleware
-  next();
-});

next

The next parameter is key, it allows Express to move onto the next middleware function once the custom middleware executes. Without it, the request processing pipeline will get blocked.

Middleware functions are basically asynchronous requests and as such they use a similar syntax as Promises (e.g then) for sequencing processes.

Example of sequence

app.use((req, res, next) => {
-  console.log("Do process A...");
-  next();
-});
-
-app.use((req, res, next) => {
-  console.log("Do process B...");
-  next();
-});

It makes more sense of course to define our middleware within a function and then pass it as an argument to app.use()

Including middleware based on environment

With a full-scale Node application you will typically run three environments:

  • Development
  • Testing
  • Production

We will not want to run certain types of middleware in all environments. For example, it would be costly to run logging in the app’s production environment. It would make more sense to run this only in development.

Accessing current Node environment

We can control which middleware we run via the Node envrionment variables: process.env (see for instance ports).

We could set Morgan to run only in development with:

if (app.get("env") === "development") {
-  app.use(morgan("common"));
-  console.log("Morgan enabled");
-}
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Mixed_and_improper_fractions.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Mixed_and_improper_fractions.html deleted file mode 100644 index 2ddb7d5..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Mixed_and_improper_fractions.html +++ /dev/null @@ -1,79 +0,0 @@ -Mixed and improper fractions - My Zettelkasten - - - - -

Mixed and improper fractions

Improper fractions

  • Proper fraction:
    • The numerator is smaller than the denominator
    • E.g. \(\frac{2}{3}\), \(-\frac{5}{10}\)
  • Improper fraction
    • The numerator is greater than the denominator
    • E.g. \(\frac{3}{2}\), \(-\frac{5}{4}\)

Mixed fractions

A mixed fraction is part whole number, part fraction. For example: \(5 \frac{3}{4}\).

It means, in effect: \(5 + \frac{3}{4}\)

Converting mixed fractions into improper fractions

Mixed fractions are hard to calculate with. We need some way to convert them to fractions. We can do this by converting them to improper fractions.

With the example \(4 \frac{7}{8}\), we know this means \(4 + \frac{7}{8}\). We need to express the amount 4 in terms of eighths. It would be 4 lots of \(\frac{8}{8}\) given that 4 is a whole number not a fractional amount. Thus the process would be:

$$ -\frac{8}{8} + \frac{8}{8} + \frac{8}{8} + \frac{8}{8} + \frac{7}{8} -$$

But we know that when we add fractions with a common denominator, we only add the numerators, not the denominators. Thus the calculation would actually be:

$$ -\frac{8 + 8 + 8 + 8 + 7}{8} = \frac{39}{8} -$$

Addition helps to explain the concepts underlying the procedure but it is more efficient to use multiplication.

The procedure is as follows:

  1. Multiply the whole number part by the denominator
  2. Add the numerator
  3. Place the result over the denominator

Thus:

$$ -4 \frac{7}{8} = \frac{(4 \cdot 8) + 7 }{8} -$$

Converting improper fractions into mixed fractions

It is quite obvious how to reverse the process and turn an improper fraction into a mixed fraction.

Take \(\frac{27}{5}\). We work out how many times the numerator is divisible by the denominator and make that the whole number. The remainder is then left as the fractional part.

$$ -\begin{split} -\frac{27}{5} = 27 \div 5 \\ -= 5 r 2 \\ -= 5 \frac{2}{5} -\end{split} -$$

Multiplying and dividing by mixed fractions

Now that we know how to convert mixed fractions into improper fractions, it is straight forward to multiply and divide with them. We convert the mixed fraction into an improper fraction and then divide and multiply as we would with a proper fraction.

Demonstration of multiplication

Calculate \(-2\frac{1}{12} \cdot 2 \frac{4}{5}\):

  1. First convert each mixed fraction into an improper fraction: $$ -\begin{split} --2\frac{1}{12} = -2 \cdot -12 \\ -= 24 + 1 \\ -= - \frac{25}{12} -\end{split} -$$

$$ -\begin{split} -2 \frac{4}{5} =2 \cdot 5 \\ -= 10 + 4 \\ -= \frac{14}{5} -\end{split} -$$

  1. Then carry out the multiplication using factorization:

    $$ \begin{split}

    • \frac{25}{12} \cdot \frac{14}{5} = \
    • \frac{(5 \cdot 5) \cdot (7 \cdot 2)}{(3 \cdot 2 \cdot 2) \cdot (5)} = - \frac{5 \cdot 7 }{2 \cdot 3} \ \end{split} $$
  2. Then simplify:

    $$

    • \frac{35}{6} $$
  3. Finally, convert back into a mixed fraction:

$$ \begin{split}

  • \frac{35}{6} = -35 \div 6 \
  • 5 r 5 = \
  • 5 \frac{5}{6} \end{split} $$

Demonstration of division

Again we convert the mixed fraction into an improper fraction and then follow the requisite rule, in the case of division this is to invert and multiply.

Calculate \(-4 \frac{4}{5} \div 5 \frac{3}{5}\).

  1. Convert to improper fraction: $$ -\begin{split} --4 \cdot 5 = \\ --20 -\end{split} -$$

Adding and subtracting mixed fractions

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Modelling_relationships_in_MongoDB.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Modelling_relationships_in_MongoDB.html deleted file mode 100644 index 8b9e10c..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Modelling_relationships_in_MongoDB.html +++ /dev/null @@ -1,69 +0,0 @@ -Modelling relationships between data - My Zettelkasten - - - - -

Modelling relationships between data

So far we have taken the values of a document to be simple: the author value is just a string but what if author was itself another collection for instance a collection with the proprties age and publications and the author name, say Tosh Gnomay was a document in this collection? This means we would have an interaction between two collections. In this entry we will look at how to work with interrelated collections. This is equivalent to establishing 10_Joins in a relational database.

There are two main approaches to modelling relationships between data: normalisation and denormalisation.

Modelling relationships with normalisation: using references

In the case of normalisation we use a UUID from one document to connect it to another document.

Let’s say that we have a course document as follows which is an instance of the courses collection:

{
-    _id: "ceds89e"
-    name: "Java course",
-    author: "Tosh Gnomay"
-}

And we have a document which is an instance of another type of collection called authors. One instance of it could be:

{
-    _id: "de89w9",
-    name: "Tosh Gnomay",
-    courses: ["Java course", "C# course"]
-}

Using normalisation, we would establish the relationship by using the value of the _id propety in the courses document as the value of the name property in the authors document. We would rewrite the courses document like so:

{
-    _id: "ceds89e"
-    name: "Java course",
-    author: "de89w9"
-}

Modelling relationships with denormalisation: embedding

With denormalisation we achieve the same outcome but instead of using a reference we embed one value in another:

{
-    _id: "ceds89e"
-    name: "Java course",
-    author: {
-        name: "Tosh Gnomay",
-        courses: ["Java course", "C# course"]
-    }
-}

Tradeoffs: which approach to use?

There are drawbacks and benefits with each approach.

  • One benefit of normalisation is consistency. Because we are using the UUID and referencing it in another document, if we make a change to the values in the source document, it will automatically apply to all documents that reference it. We make a change in one place and it is reflected everywhere.

  • Conversely, a drawback of denormalisation is that it invites inconsistency between documents. Embedded values can easily go out of sync with their usage elsewhere as you don’t have a direct reference correspondence.

  • On the other hand a drawback of normalisation is performance when querying. Any time you have a document that references another document than this document also has to be retrieved. Therefore for every query you are returning two documents. As denormalised references embed the second document, only one document is being returned on each query.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Module_pattern.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Module_pattern.html deleted file mode 100644 index 417f172..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Module_pattern.html +++ /dev/null @@ -1,77 +0,0 @@ -Module pattern - My Zettelkasten - - - - -

Module pattern

Come back and compare this with learning from Node.js

With the module design pattern we create encapsulation: the variables and functions (as methods) are kept private inside the module and cannot be overwritten. This design pattern is familiar from Node.js development: every package you import into your project and download from NPM is a module.

Generally you will create the module as a class, import it and then instantiate a new instance. However for private development, you could just as well use an object and duplicate it with Object.create.

Example

Here is an example of a simple module that returns the age of a person.

export default class Age {
-  constructor(name, birthYear) {
-    this.name = name;
-    this.birthYear = birthYear;
-  }
-  currentYear() {
-    return new Date().getFullYear();
-  }
-  get age() {
-    return this.currentYear() - this.birthYear;
-  }
-}
const martha = new Age("Martha", 1997);
-console.log(martha.age); // 24

Controlling access

In the example above, aValue could be edited in instantiations of the class. Given that modules should not be overwrittable, you could make it a private property on the class. The benefit of getters and setters is that they dictate what can be modified and retrieved from the module. So if you use get and set you can prevent overwrites.

Object modules

If you want to use an object instead of a class, you have to take greater care to ensure that the objects are not overwritable. Also you cannot use the # modifier to make properties private.

  • Use getters and setters for updating and retrieving values
  • Use Object.seal to prevent changes to the parent object
  • Instead of using getters and setters, for individual properties you can set writable to be false for properties that you don’t want changed

There are examples of each in the following:

export const age = {
-  name: "",
-  birthYear: new Number(),
-  currentYear() {
-    return new Date().getFullYear();
-  },
-  get age() {
-    return this.currentYear() - this.birthYear;
-  },
-};
-
-Object.seal(age);
-Object.defineProperty(age, "aValue", {
-  value: 6,
-  writable: false,
-});
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Module_wrapping_at_runtime.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Module_wrapping_at_runtime.html deleted file mode 100644 index 7b83f75..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Module_wrapping_at_runtime.html +++ /dev/null @@ -1,51 +0,0 @@ -Module wrapping at runtime in NodeJS - My Zettelkasten - - - - -

Module wrapping at runtime in NodeJS

The Module Wrapper Function

When Node runs each of our module files are wrapped within an immediately-invoked function expression that has the following parameters:

(function (exports, require, module, __filename, __dirname))
-

This is called the module wrapper function

Note that one of these parameters is the module object.

Within any module we can access these parameters: you can think of them as metadata about the module itself. __filename and __dirname are particularly useful when writing to files and modifying directories.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Modules_in_NodeJS.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Modules_in_NodeJS.html deleted file mode 100644 index 1e09b7c..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Modules_in_NodeJS.html +++ /dev/null @@ -1,97 +0,0 @@ -Modules - My Zettelkasten - - - - -

Modules

Modules are partitioned files where we define our variables and functions. Values defined in modules are scoped to that specific module, constituting a unique name space. This avoids name clashes in large programs.

  • Every file in a Node application is considered a module.

  • The variables and methods in a module are equivalent to private properties and methods in object-oriented programming.

  • If you wish to use a function or variable defined in a module outside of its modular container you need to explicitly export it and make it public.

Structure of a module

Node keeps an internal record of the properties of a module. To see this we can log the property module to the console.

// index.js
-console.log(module);

This gives us:

Module {
- id: '.',
- path: '/home/thomas/repos/node-learning',
- exports: {},
- filename: '/home/thomas/repos/node-learning/index.js',
- loaded: false,
- children: [],
- paths: [
-   '/home/thomas/repos/node-learning/node_modules',
-   '/home/thomas/repos/node_modules',
-   '/home/thomas/node_modules',
-   '/home/node_modules',
-   '/node_modules'
- ]
-}

Exports

  • Whenever we export a property or method from a module we are directly targeting the exports property of the module object.
  • Once we add exports to a file they will be displayed under that property of the module object.
  • We can export the entire module itself as the export (typically used when the module is a single function or class) or individual properties.

Exporting a whole module

The example below is a module file that consists in a single function

module.exports = function (...params) {
-  // function body
-};

Note the module is unnamed. We would name it when we import:

const myFunction = require("./filenme");

Exporting sub-components from a module

In the example below we export a variable and function from the same module. Note only those values prefixed with exports are exported.

exports.myFunc = (...params) => {
-  // function bod[]()y
-};
-
-exports.aVar = 321.3;
-
-var nonExportedVar = true;

This time the exports are already name so we would import with the following:

const { myFunc, aVar } = require("./filename");

We can also do the exporting at the bottom when the individual components are named:

const myNamedFunc = (val) => {
-  return val + 1;
-};
-
-function anotherNamedFunc(val) {
-  return val * 2;
-}
-
-// This time we export at the bottom
-exports.myNamedFunc = myNamedFunc;
-exports.differentName = anotherNamedFunc; // We can use different names
-
-// Or we could export them together
-module.exports = { myNamedFunc, anotherNamedFunc };

The import is the same:

const { myNamedFunc, anotherNamedFunc } = require("./modules/multiExports");

Structuring modules

The techniques above are useful to know but generally you would want to enforce a stricter structure than a mix of exported and private values in the one file. The best way to do this is with a single default export.

Here the thing exported could be a composite function or an object that basically acts like a class with methods and properties.

Export a composite single function


-module.exports = () => {
-	foo() {...}
-	bar() {...}
-}

Export an object


-module.exports = {
-	foo : () => {...},
-    bar: () => {...}
-}

Both of these structures would be referred to in the same way when importing and using them.

Or you could export an actual class as the default. This is practically the same as the two above other than that you would have to use new to initiate an instance of the class.

export default class {
-  foo() {}
-  bar() {}
-}

Every method and property within the export will be public by default, whether it is an object, class or function. If you wanted to keep certain methods/properties private, the best approach is to define them as variables and functions within the module file but outside of the export block.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/MongoDB_Introduction.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/MongoDB_Introduction.html deleted file mode 100644 index 76a2be8..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/MongoDB_Introduction.html +++ /dev/null @@ -1,50 +0,0 @@ -MongoDB: Introduction - My Zettelkasten - - - - -

MongoDB: Introduction

MongoDB is not a relational database system like SQL, instead it is document-based which means you do not neeed to design database tables and schema, you are simply storing data as JSON and there is no transformation of the data.

Most of the notes on Mongo will introduce it within the context of Node.js backend. We will be sending Javascript objects and arrays to Mongo and returning them as JSON.

Databases, collections, documents

Although Mongo is not a relational database it has a structure that we can understand in relation to that paradigm. A database is obviously the overall structure. It comprises collections which are organised sets of data that are analagous to tables in RDBs. Within each collection are a series of documents which we can think of as being equivalent to rows in RDB table: units that comprise the collection.

A document is a container comprising key-value pairs in the manner of an object.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Monitoring_processes_and_resources.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Monitoring_processes_and_resources.html deleted file mode 100644 index 8689e6e..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Monitoring_processes_and_resources.html +++ /dev/null @@ -1,63 +0,0 @@ -Monitoring processes and resources - My Zettelkasten - - - - -

Monitoring processes and resources

General purpose diagnostic programs (memory, CPU, I/O)

top/htop

We can use ps to list the currently running processes but it does not provide much information about the resource metrics or how the process changes over time. We can use top to get more information.

top provides an interactive interface for the information that ps displays. It updates in real time and shows the most active processes based on the CPU time that they are utilising. You can also order by memory usage.

Here I have pressed u to show only the processes associated with my user:

Main commands

CommandAction
-uShow processes by selected user
MSort by memory usage
PSort by cumulative CPU usage
?View key and explanation

Understanding the categories

  • Main/IO
    • The first covers all processes. The second focuses on input/output processes (i.e. reading and writing to disks and other devices)
  • PRI
    • This stands for priority. This metric reflects the kernel’s current schedule priority for the process. The higher the value, it is less likely that the kernel will schedule the process if there are competing processes that require CPU time. The lower the value, the greater priority this process has over others.
  • NI
    • This stands for nice value. This metric exists in order to allow administrators to nudge or influence the priority of a given process. You cannot directly tell the kernel to do x now instead of y but you can make what are effectively suggestions by manipulating the nice value.
    • The kernel adds the nice value to the current priority value for the given process to determine its next time slot. When you increase the nice value of process P you are being “nicer” to the other processes by influencing the priority of P downwards so that the other processes receive greater precedence from the kernel.
    • By default, the nice value will be 0. To reduce priority of PID 1234, you would use:
      $ renice 20 1234
  • VIRT
    • The total amount of Virtual_memory_and_the_MMU_in_Linux used by the process including: program code, data, shared libraries, pages that have been swapped, pages that have been mapped but not used.
  • RES
    • Stands for resident size
    • The non swapped physical memory the process has used
  • SHR
  • S
    • Status:
      • S for sleeping (idle)
      • R for running
      • D for disk sleep

vmstat

vmstat provides similar metrics to htop but tells you more about the memory state and the activities of the kernel in a single row.

The default output is a single line with the averages since boot. You can add a delay parameter (in secs) which will then output at that interval, allowing you to see memory usage in realtime, e.g:

$ vmstat 5
-procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
- r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
- 2  0      0 4326768 334228 5050952    0    0     8    19   80   10  4  1 94  0  0
- 0  0      0 4365520 334260 5054468    0    0     0   125 2140 3434  4  1 94  0  0
- 1  0      0 4382400 334276 5068940    0    0     0    77 2102 3988  3  1 95  0  0
- 1  0      0 4434000 334288 5052908    0    0     0    25 2859 4278  6  1 92  0  0
- 0  0      0 4391576 334304 5086484    0    0     0   110 2899 6480  8  3 90  0  0
-
  • procs
    • The number of runnable processes (r) and the number of blocked (b) processes
  • memory
    • The core memory output distinguishing:
      • Total kbs swapped to disk
      • Total kbs free
      • Total kbs currently in buffer and not written
      • Total amount of virtual memory in the cache
  • swap
    • Distinguishes amount of memory swapped in (si) to memory and swapped out (so) to disk
  • io
    • Disk actions
    • Amount of data read from harddisk (bi)
    • Amount of data written to harddisk (bo)
  • system
    • The number of times the kernel switches to kernel code
  • cpu
    • Percentage of the different CPU behaviours:
      • Responding to user tasks (us)
      • Time that it is idle (id)

Files being used by active processes: lsof

lsof stands for list open files. It lists opened files and the processes using them. Without modifiers it outputs a huge amount of data. The best way to use it is to execute it against a specific PID. For example the below output gives me some useful info about which files VS Code is using:

System calls: strace

A system call is when a process requests a service from the kernel, for instance an I/O operation to memory. We can trace these system calls with strace.

CPU performance

We can use the uptime program to assess overall CPU performance in the form of a load average.

Load average is the number of active processes currently ready to run. It is an estimate of the number of processes that are capable of using the CPU at any given time.

Uptime gives you three load averages:

$ uptime
-11:19:16 up 14 days,  3:53,  1 user,  load average: 0.84, 0.57, 0.50
  • The three numbers are load averages for the past 1 minute, 5 minutes and 15 minutes respectively.

  • A load average close to 0 is usually a good sign because it means that your processor isn’t being challenged and you are conserving power. Anything equal to or above 1 means that a single process is using the CPU nearly all the time. You can identify that process with htop and it will obviously be near to the top. (This is often caused by Chrome and Electron-based software.)

Memory status

We know that processes primarily interact with virtual memory in the form of pages which are then translated to physical blocks by the kernel via the Virtual_memory_and_the_MMU_in_Linux. There are several tools which provide windows onto this process.

System page size

We can view the overall system page size which is a representation of the amount of virtual memory available:

$ getconf PAGE_SIZE
-4096

This will typically be the same for all Linux systems.

free : available physical memory

free displays the total amount of free and¬used physical and swap memory in the system, as well as the buffers and caches used by the kernel.

$ free
-              total        used        free      shared  buff/cache   available
-Mem:        16099420     5931512     5039344     2046460     5128564     7781904
-Swap:        3145724           0     3145724
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Morgan.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Morgan.html deleted file mode 100644 index 6b492b8..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Morgan.html +++ /dev/null @@ -1,50 +0,0 @@ -Morgan - My Zettelkasten - - - - -

Morgan

Morgan is middleware that is used to log HTTP requests to the Express instance.

app.use(morgan("dev"));

With Morgan in place, every time we run a request it will be logged on the console that is running our Node application, e.g:

GET /api/courses 200 95 - 1.774 ms

This uses the tiny default which logs the bare minimum giving us: request type; endpoint; response code; and time to execute. But there are more verbose settings.

It defaults to logging on the console but can also be configured to write to a log file.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Motherboard.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Motherboard.html deleted file mode 100644 index bd8f1d3..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Motherboard.html +++ /dev/null @@ -1,51 +0,0 @@ -Motherboard - My Zettelkasten - - - - -

Motherboard

-

The motherboard is the foundation of a computer. It allocates power and allows communication to and between the CPU, Memory, harddisk and all other hardware components.

It is a printed circuit board and is always the largest board within the computer chassis.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Multiple_pointers.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Multiple_pointers.html deleted file mode 100644 index 71d52dd..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Multiple_pointers.html +++ /dev/null @@ -1,89 +0,0 @@ -Multiple pointers - My Zettelkasten - - - - -

Multiple pointers

The multiple pointers pattern can be useful for moving through an array and comparing elements against each other in a time-efficient manner and without costly multiple loops.

Example: moving pairs

In this example we shuffle through an array creating a pair from each element encountered. Thus for an array such as [4, 3, 2, 1, 3, 6, 7] we would return [ [ 4, 3 ], [ 3, 2 ], [ 2, 1 ], [ 1, 3 ], [ 3, 6 ], [ 6, 7 ] ].

function movingPairs(arr) {
-  const store = [];
-  let left = 0;
-  let right = 1;
-  for (left; left < arr.length - right; left++) {
-    store.push([arr[left], arr[right + left]]);
-  }
-  return store;
-}

Example: identify unique values

An example application of the above pattern would be identifying the number of unique values in an array that contains duplicates. One way to do this in JavaScript would be to use a Set however this is a more generic approach that only requires a single loop:

function uniqueValues(arr) {
-  if (!arr.length) {
-    return 0;
-  } else {
-    let count = 1;
-    let left = 0;
-    let right = 1;
-    for (right; right < arr.length; right++) {
-      if (arr[left] !== arr[right]) {
-        count++;
-      }
-      left++;
-    }
-
-    return count;
-  }
-}

This works by having two pointers at either end of the array; one moving from the right and one moving from the left. Whilst the right pointer is less than the array length, the left pointer is incremented as the right moves closer to it. At each incrementation, the values of pointers (used as indexes) are compared for uniqueness, and a count is kept.

Example: identify duplicates

This is very similar to the above but this time we are looking for duplicates rather than unique values.

function areThereDuplicatesPointer(...input) {
-  let start = 0;
-  let next = 1;
-  while (next < input.length) {
-    let same = input[start] === input[next];
-    if (same) {
-      return true;
-    }
-    start++;
-    next++;
-  }
-
-  return false;
-}
-console.log(areThereDuplicatesPointer(1, 2, 3)); // false
-console.log(areThereDuplicatesPointer(1, 2, 2)); // true
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Multiplexers_and_demultiplexers.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Multiplexers_and_demultiplexers.html deleted file mode 100644 index 0991970..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Multiplexers_and_demultiplexers.html +++ /dev/null @@ -1,50 +0,0 @@ -Multiplexers (MUX) and demultiplexers (DMUX) - My Zettelkasten - - - - -

Multiplexers (MUX) and demultiplexers (DMUX)

Multiplexer

Multiplexing is the generic term used to describe the operation of sending one or more analogue or digital signals over a common transmission line at different times or speeds.

A multiplexer selects one of several input signals and forwards ths selected input to a single output line.

We have two inputs (A,B) plus a third input SEL (for “select”). Applying a value to SEL toggles the output between A and B.

Multiplexers can be used to build larger circuits by connecting the output of one multiplexer to the input of another. They are often used to implement data selection and switching in digital systems

Programable gates

One of the main use cases of multiplexers is to implement programmable gates. These are gates where the logic can be switched. For example an ANDMUXOR gate uses the SEL value to toggle the operation of a gate between AND and OR for its two inputs A and B

Demultiplexer

As the name suggests, a demultiplexer reverses the functionality of a multiplexer. It receives a single input and based on the selection of the SEL input it channels it to either an A or a B output.

We can think of it as a distributor of a value into one of several possible channels.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Multiplicative_identity.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Multiplicative_identity.html deleted file mode 100644 index fe02b4d..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Multiplicative_identity.html +++ /dev/null @@ -1,50 +0,0 @@ -The Property of Multiplicative Identity - My Zettelkasten - - - - -

The Property of Multiplicative Identity

Let \(a\) represent any member of \(\mathbb{W}\) or \(\mathbb{Z}\) then:

$$ a \cdot 1 = a $$

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Multiplicative_property_of_negative_one.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Multiplicative_property_of_negative_one.html deleted file mode 100644 index b87df8b..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Multiplicative_property_of_negative_one.html +++ /dev/null @@ -1,50 +0,0 @@ -The Multiplicative Property of Negative One - My Zettelkasten - - - - -

The Multiplicative Property of Negative One

Let \(a\) represent any member of \(\mathbb{Z}\), then:

$$ (-1) \cdot a = -a $$

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Multiplying_fractions.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Multiplying_fractions.html deleted file mode 100644 index 69fc5db..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Multiplying_fractions.html +++ /dev/null @@ -1,65 +0,0 @@ -Multiplying fractions - My Zettelkasten - - - - -

Multiplying fractions

To find the product of two fractions \(\frac{a}{b}\) and \(\frac{c}{d}\) multiply their numerators and denominators and then reduce:

$$\frac{a}{b} \cdot \frac{c}{d} = \frac{a \cdot c}{b \cdot d}$$

Example

$$ -\frac{1}{3} \cdot \frac{2}{5} = \frac{1 \cdot 2}{3 \cdot 5} = \frac{2}{15} -$$

Prime factorisation in place

The example above did not require a reduction, so here is a more complex example:

$$ -\frac{14}{15} \cdot \frac{30}{140} = \frac{420}{2100} -$$

It would be laborious to reduce such a large product using factor trees or the repeated application of divisors, as defined in reducing fractions. We can use a more efficient method. This method can be applied at the point at which we conduct the multiplication rather than afterwards once we have the product. We express the the initial multiplicands as prime factors:

$$ -\frac{14}{15} \cdot \frac{30}{140} = \frac{(2 \cdot 7) \cdot (2 \cdot 3 \cdot 5) }{(3 \cdot 5) \cdot (2 \cdot 2 \cdot 7 \cdot 5)} -$$

We now have the product in factorised form before we have applied the multiplication so we can go ahead and cancel:

$$ -\frac{\cancel{2}, \cancel{7}, \cancel{2}, \cancel{3}, \cancel{5}}{\cancel{3}, \cancel{5}, \cancel{2}, \cancel{2}, \cancel{7}, 5} = \frac{1}{5} -$$

Note that in the above case, there was only a single 5 left as a denominator and no value left as a numerator. This is equivalent to there just being “one five” so we write \(\frac{1}{5}\)

Example of multiplying fractions with negative fractions containing variables

Calculate: $$- \frac{6x}{55y} \cdot - \frac{110y^2}{105x^2}$$

First multiply in place:

$$ -\frac{(3 \cdot 2 \cdot x) \cdot (5 \cdot 2 \cdot 11 \cdot y \cdot y)}{(5 \cdot 11 \cdot y) \cdot (7 \cdot 5 \cdot 3 \cdot x \cdot x)} -$$

Then cancel:

$$ -\frac{(\cancel{3} \cdot 2 \cdot \cancel{x}) \cdot (\cancel{5} \cdot 2 \cdot \cancel{11} \cdot \cancel{y} \cdot y)}{(\cancel{5} \cdot \cancel{11} \cdot \cancel{y}) \cdot (7 \cdot 5 \cdot \cancel{3} \cdot \cancel{x} \cdot x)} = -\frac{2 \cdot 2 \cdot y}{7 \cdot 5 \cdot x} -$$

Then reduce:

$$ -\frac{2 \cdot 2 \cdot y}{7 \cdot 5 \cdot x} = \frac{4y}{35x} -$$

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Mutations_with_Apollo_Client.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Mutations_with_Apollo_Client.html deleted file mode 100644 index 5b309c3..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Mutations_with_Apollo_Client.html +++ /dev/null @@ -1,128 +0,0 @@ -Mutations with Apollo Client - My Zettelkasten - - - - -

Mutations with Apollo Client

Queries are read-only operations. Mutations are write-only operations.

Just like the Query type, the Mutation type serves as an entrypoint to the schema.

Naming convention

  • Use verb: add, create, delete
  • Refer to the datatype

For example addSpaceCat(){}

Demonstration mutation

We are going to create a mutation that increments the numberOfViews field on the Track type:

Updating the schema

type Mutation {
-    incrementTrackViews(id: ID!): IncrementTrackViewsResponse!
-}
-
-
-// Define a specific response type that specifically matches our needs
-type IncrementTrackViewsResponse {
-    code: Int! // status code
-    success: Boolean! // whether mutation was successful
-    message: String! // what to say if mutation successful
-    track: Track   // not nullable because might error
-}

Based on this schema, the mutation will recieve a Track id and increment the specified Track. It will return an object comprising the newly updated Track and a bundle of properties that provide feedback on the status of the operations: a status code, whether it succeeded, and a message.

Updating the data source

Remember that our sole data source in the demonstration project is a REST API. We handle it within GraphQL using Apollos RESTDataSource class. We need to add a method to this class that will increment the track views. We wil use the PATCH REST method:

class TrackAPI extends RESTDataSource {
-  constructor() {...}
-  getTracksForHome() {...}
-  getAuthor(authorId) {...}
-  getTrack(trackId){...};
-
-  incrementTrackViews(trackId) {
-    return this.patch(`track/${trackId}/numberOfViews`);
-  }
-}

The patch() method is procided by the RESTDataSouce class that TrackAPI inherits from

Adding resolver

Next we need a resolver that corresponds to the mutation we have defined in the schema. We will need to handle successful responses as well as errors.

Success case

As always we match the shape of the schema:

const resolvers = {
-  Query: {
-    // ...query resolvers
-  },
-  Mutation: {
-    // increments a track's numberOfViews property
-    incrementTrackViews: async (_, { id }, { dataSources }) => {
-      const track = await dataSources.trackAPI.incrementTrackViews(id);
-      return {
-        code: 200,
-        success: true,
-        message: `Successfully incremented number of views for track ${id}`,
-        track,
-      };
-    },
-  },
-};

There’s more going on with this resolver than the previous one. As is standard, we call the API using the TrackAPI class. However we don’t just immediately return this when it executes. This is because the schema specifies that the return type IncrementTrackViewsResponse requires more than just the updated Track. So we wait this and return it with the cluster of metadata about the mutation response (code, success, and message).

Error case

We can extend the Mutation resolver to allow for errors. We’ll do this by refactoring the resolver into a try...catch block and adding the error handling in the catch.

We’ll harness the details that are provided by Apollos’ own err object which is returned by the RESTDataSource class that our resolver ultimately traces back to:

const resolvers = {
-
-    Query: {
-        // ...query resolvers
-    }
-
-    Mutation: {
-        incrementTrackViews: async (_, {id}, {dataSources}) => {
-            try {
-                const track = await dataSources.trackAPI.incrementTrackViews(id);
-                return {
-                    code: 200,
-                    success: true,
-                    message: `Successfully incremented number of views for track ${id}`,
-                    track
-                };
-            } catch (err) {
-                return {
-                    code: err.extensions.response.status,
-                    success: false,
-                    message: err.extensions.response.body,
-                    track: null
-                };
-            }
-        },
-    }
-}

The useMutation hook

We invoke the useMutation hook to issue mutations from the client-side.

As with queries and query constants we wrap our mutation in a `gql` template string:

const INCREMENT_TRACK_VIEWS = gql`
-  mutation IncrementTrackViews($incrementTrackViewsId: ID!) {
-    incrementTrackViews(id: $incrementTrackViewsId) {
-      code
-      success
-      message
-      track {
-        id
-        numberOfViews
-      }
-    }
-  }
-`;

We then pass it to the useMutation hook including an options object with our variables. (This time the specific variable is named):

import { gql, useMutation } from "@apollo/client";
-
-useMutation(INCREMENT_TRACK_VIEWS, {
-  variables: { incrementTrackViewsId: id },
-});

useMutation returns an array of two elements:

  1. The mutation function that actually executes
  2. An object comprising (loading, error, data) - this is the same as is the return value of useQuery.

So we can destructure like so (we don’t always need the second element);

const [incrementTrackViews, dataObject] = useMutation(INCREMENT_TRACK_VIEWS...)

Given that we can isolate the mutation function as the first destructured element of the array, we could then attach incrementTrackViews to a button or other frontend interaction.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Naming_conventions.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Naming_conventions.html deleted file mode 100644 index 5960dbd..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Naming_conventions.html +++ /dev/null @@ -1,51 +0,0 @@ -Python naming conventions - My Zettelkasten - - - - -

Python naming conventions

Underscores

To name a variable or method with multiple words we use underscores to separate each word.

an_int = 32
-print(an_integer.is_integer) # true

Constants

There are no constants in Python. However there a pseudo-constants established by convention. To denote that a variable should not change you use UPPER_CASE.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Natural_numbers.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Natural_numbers.html deleted file mode 100644 index ee5cb69..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Natural_numbers.html +++ /dev/null @@ -1,50 +0,0 @@ -Natural numbers - My Zettelkasten - - - - -

Natural numbers

The set of natural numbers

$$ \mathbb{N} = {1, 2, 3, ...} $$

Natural numbers are most simply expressed as the set of numbers we use for counting. The set of natural numbers start at one and continuity to infinity.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Negation_Elimination.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Negation_Elimination.html deleted file mode 100644 index dc02170..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Negation_Elimination.html +++ /dev/null @@ -1,50 +0,0 @@ -Negation Elimination - My Zettelkasten - - - - -

Negation Elimination

Like the introduction rule for negation, the elimination rule also works by deriving a contradiction. It is basically Negation Introduction in reverse. Instead of starting the sub-proof with a true proposition from which you derive a contradiction, you start with the negation of a proposition, derive a contradiction and then assert the positive of the negated proposition you started out with.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Negation_Introduction.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Negation_Introduction.html deleted file mode 100644 index 246e7d3..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Negation_Introduction.html +++ /dev/null @@ -1,50 +0,0 @@ -Negation Introduction - My Zettelkasten - - - - -

Negation Introduction

This is also known as proof by contradiction. You start with an assumption declared in a sub-proof. If you can derive a contradiction from this assumption (typically from the introduction of another proposition and its negation), then you are permitted to derive the negation of the auxiliary assumption in the main proof.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Negative_exponents.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Negative_exponents.html deleted file mode 100644 index f336925..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Negative_exponents.html +++ /dev/null @@ -1,52 +0,0 @@ -Negative exponents - My Zettelkasten - - - - -

Negative exponents

When calculating the exponents of a negative number the answer will always will be positive:

$$ --5^2 = 25 -$$

This confused me but it was because I was thinking of it in terms of \(-5 \cdot 5\) when in fact it is \(-5 \cdot -5\) and when two negative numbers are multiplied the product is always negative.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Network_card.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Network_card.html deleted file mode 100644 index a8f81fe..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Network_card.html +++ /dev/null @@ -1,50 +0,0 @@ -Network card - My Zettelkasten - - - - -

Network card

The network card (technically know as the Network Interface Card (NIC)) or network adapter is the hardware device that allows a computer to connect to a network.

They are the physical interface between the computer and the network link, e.g. WiFi or ethernet.

They can be internal and built into the motherboard or external as in the case of USB adaptors.

Each network card has a unique MAC address to identify the device on the network.

Network cards on consumer-grade devices typically utilise the devices resources and the kernel manages its actions via a driver. More high-end devices (typically used in servers) have their own processors and memory.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Network_debugging.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Network_debugging.html deleted file mode 100644 index 07a9e17..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Network_debugging.html +++ /dev/null @@ -1,50 +0,0 @@ -Network debugging - My Zettelkasten - - - - -

Network debugging

Network scanning

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Network_fundamentals.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Network_fundamentals.html deleted file mode 100644 index dc192a9..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Network_fundamentals.html +++ /dev/null @@ -1,50 +0,0 @@ -Network fundamentals - My Zettelkasten - - - - -

Network fundamentals

A network is a system that allows computing devices to communicate and exchange information with each other.

In order for devices to be able to communicate they must share a common communication protocol.

A protocol specifies rules determining how information is to be exchanged. (Simply connecting two devices is not sufficient for them to be able to communicate, they must have a shared language.)

The nodes of a network are called hosts.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Network_hosts.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Network_hosts.html deleted file mode 100644 index b61c0e1..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Network_hosts.html +++ /dev/null @@ -1,50 +0,0 @@ -Network hosts - My Zettelkasten - - - - -

Network hosts

A network host or node is a single computing device attached to a network

Hosts can act as servers or clients, or both.

Server

A network server is a host that listens for inbound network connections and provides services to other hosts. Examples include web and email servers.

Client

A network client is a host that makes outbound connections and requests servcies from network servers.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Network_protocols.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Network_protocols.html deleted file mode 100644 index 0a78fc1..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Network_protocols.html +++ /dev/null @@ -1,50 +0,0 @@ -Network protocols - My Zettelkasten - - - - -

Network protocols

Protocols are agreed standards specifying and governing communication between nodes on a network.

Network protocols are typically layered. The implmentation of a network layer is a stack.

Stacks enshrine encapsulation: not every layer has to be directly concerned with every other layer. Only adjacent layers that interface with each other need to be in contact.

A prime example of a layered network stack is the internet_protocol_suite.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Network_requests_in_Python.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Network_requests_in_Python.html deleted file mode 100644 index 9146054..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Network_requests_in_Python.html +++ /dev/null @@ -1,93 +0,0 @@ -Making network requests in Python - My Zettelkasten - - - - -

Making network requests in Python

We can use the requests package to make API requests to RESTful resources and handle the data as JSON.

pip install requests

Here is a basic architecture for making a GET request in Python.

import requests
-
-def get_data(url):
-    response = requests.get(url)
-    if response.status_code == 200:
-        return response.json()
-    else:
-        raise Exception(
-            f"Failed to fetch data from API. Status code: {response.status_code}")
-
-def main():
-    url = "https://dummyjson.com/products/1"
-
-    try:
-        data = get_data(url)
-        print(data)
-
-    except Exception as e:
-        prin(e)
-
-if __name__ == "__main__":
-    main()

Parsing returned data

Running main returns:

{
-   "id":1,
-   "title":"iPhone 9",
-   "description":"An apple mobile which is nothing like apple",
-   "price":549,
-   "discountPercentage":12.96,
-   "rating":4.69,
-   "stock":94,
-   "brand":"Apple",
-   "category":"smartphones",
-   "thumbnail":"https://i.dummyjson.com/data/products/1/thumbnail.jpg",
-   "images":[
-      "https://i.dummyjson.com/data/products/1/1.jpg",
-      "https://i.dummyjson.com/data/products/1/2.jpg",
-      "https://i.dummyjson.com/data/products/1/3.jpg",
-      "https://i.dummyjson.com/data/products/1/4.jpg",
-      "https://i.dummyjson.com/data/products/1/thumbnail.jpg"
-   ]
-}

This is JSON but in Python is a dictionary

We can use standard dictionary methods to handle the data. For example, we’ll add to the existing try block:

example_key = "brand"  # Replace with the key you want to access from the JSON data
-    if example_key in data:
-        print(f"Value of '{example_key}':", data[example_key])
-    else:
-        print(f"'{example_key}' not found in the JSON data")

Which, if successful, outputs:

Value of 'brand': Apple
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Network_scanning.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Network_scanning.html deleted file mode 100644 index d0c817c..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Network_scanning.html +++ /dev/null @@ -1,53 +0,0 @@ -Network scanning - My Zettelkasten - - - - -

Network scanning

List all connected devices on local WiFi network

arp-scan --interface=wlan0 --localnet

Scan subnet for all connected devices (in case hiding)

nmap -sn 192.168.0.0/24

Check DNS resolution

dig google.com

Key output:

;; Query time: 6 msec
-;; SERVER: 192.168.0.4#53(192.168.0.4) (UDP)
-;; WHEN: Wed Jun 12 18:27:27 BST 2024
-;; MSG SIZE  rcvd: 55
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/NodeJS_scripts.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/NodeJS_scripts.html deleted file mode 100644 index 44fbced..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/NodeJS_scripts.html +++ /dev/null @@ -1,61 +0,0 @@ -NodeJS scripts - My Zettelkasten - - - - -

NodeJS scripts

If we want to use NodeJS as a scripting language without going to the trouble of setting up an NPM-based development environment, we can use the following architecture.

#!/usr/bin/env node
-
-const process = require("process");
-
-const actualScript = (firstParam, secondParam) => {
-  // Do something
-};
-
-if (require.main === module) {
-  const [, param1, param2] = process.argv;
-  actualScript(param1, param2).catch(console.error);
-}

Basically we have a function that contains the main actions of the script. This is then invoked within main in the manner of a Bash or Python script

This obviously requires the Node binary to be in your path and the script must be run with executable privileges.

If you use any module not in the Node core, you will need to have this installed globally for it to work. (There are ways around this for Node scripts you publish but for personal scripts this doesn’t matter.)

require.main

This construction checks that the script is being directy invoked via the ‘node’ command in the terminal rather than called by another module.

This is equivalent to the following construct in Python:

if __name__ == "__main__":
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Node_and_MySQL_db.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Node_and_MySQL_db.html deleted file mode 100644 index a311edc..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Node_and_MySQL_db.html +++ /dev/null @@ -1,193 +0,0 @@ -Docker example: NodeJS backend with MySQL database - My Zettelkasten - - - - -

Docker example: NodeJS backend with MySQL database

We will utilise Docker Compose to combine two containers:

  • A container for the NodeJS backend
  • A container for the MySQL database

We will only create a Dockerfile for the NodeJS part since the existing mysql image is sufficient for most needs and does not require a specific configuration.

Each of the files listed below would be saved to the same source directory which would then form the basis of the build context.

Docker Compose file

# docker-compose.yml
-version: "3.8"
-services:
-  db:
-    image: mysql:8.0
-    container_name: mysql_container
-    environment:
-      MYSQL_ROOT_PASSWORD: your_root_password
-      MYSQL_DATABASE: your_database_name
-      MYSQL_USER: your_database_user
-      MYSQL_PASSWORD: your_database_password
-    volumes:
-      - mysql-data:/var/lib/mysql
-    ports:
-      - "3306:3306"
-  app:
-    build: .
-    container_name: node_app
-    volumes:
-      - .:/usr/src/app
-    environment:
-      MYSQL_HOST: db
-      MYSQL_USER: your_database_user
-      MYSQL_PASSWORD: your_database_password
-      MYSQL_DB: your_database_name
-    depends_on:
-      - db
-    ports:
-      - "3000:3000"
-
-volumes:
-  mysql-data:

Dockerfile for the NodeJS backend

# Dockerfile
-FROM node:14
-
-WORKDIR /usr/src/app
-
-COPY package*.json ./
-
-RUN npm install
-
-COPY . .
-
-EXPOSE 3000
-
-CMD [ "node", "app.js" ]

NodeJS project setup

// package.json
-{
-  "name": "node-mysql-docker",
-  "version": "1.0.0",
-  "description": "Node.js and MySQL with Docker",
-  "main": "app.js",
-  "scripts": {
-    "start": "node app.js"
-  },
-  "dependencies": {
-    "express": "^4.17.1",
-    "mysql2": "^2.3.2"
-  }
-}
// app.js
-const express = require("express");
-const mysql = require("mysql2/promise");
-
-const app = express();
-
-const { MYSQL_HOST, MYSQL_USER, MYSQL_PASSWORD, MYSQL_DB } = process.env;
-
-const createConnection = async () => {
-  return await mysql.createConnection({
-    host: MYSQL_HOST,
-    user: MYSQL_USER,
-    password: MYSQL_PASSWORD,
-    database: MYSQL_DB,
-  });
-};
-
-app.get("/", async (req, res) => {
-  const connection = await createConnection();
-  const [rows] = await connection.query("SELECT 1 + 1 AS solution");
-  res.send(`Hello World! The solution is ${rows[0].solution}`);
-});
-
-const PORT = 3000;
-app.listen(PORT, () => {
-  console.log(`Server is running on port ${PORT}`);
-});

To start up the environment you would then run:

docker-compose -up

Environments

In the example, the database connection information in the Node source is coming from the process.env object, which itself is sourcing the values MYSQL_HOST, MYSQL_PASSWORD etc from the Docker compose file. Therefore these values are hardcoded there.

This is not good practice as it exposes sensitive information and make managing different deployment environments (development, stage, test etc.) difficult.

To get around this we would create an .env file in the project directory that is Git ignored:

# .env
-MYSQL_ROOT_PASSWORD=your_root_password
-MYSQL_DATABASE=your_database_name
-MYSQL_USER=your_database_user
-MYSQL_PASSWORD=your_database_password

Then the docker-compose.yml file can be updated to use these variables:

version: "3.8"
-services:
-  db:
-    image: mysql:8.0
-    container_name: mysql_container
-    environment:
-      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
-      MYSQL_DATABASE: ${MYSQL_DATABASE}
-      MYSQL_USER: ${MYSQL_USER}
-      MYSQL_PASSWORD: ${MYSQL_PASSWORD}
-    volumes:
-      - mysql-data:/var/lib/mysql
-    ports:
-      - "3306:3306"
-  app:
-    build: .
-    container_name: node_app
-    volumes:
-      - .:/usr/src/app
-    environment:
-      MYSQL_HOST: db
-      MYSQL_USER: ${MYSQL_USER}
-      MYSQL_PASSWORD: ${MYSQL_PASSWORD}
-      MYSQL_DB: ${MYSQL_DATABASE}
-    depends_on:
-      - db
-    ports:
-      - "3000:3000"
-
-volumes:
-  mysql-data:

${VARIABLE_NAME} syntax is used to reference environment variables from the .env file in the docker-compose.yml file. Docker Compose will automatically load the variables from the .env file when starting the services.

Development, staging, production environments

To specify different connection details for different environments you would create different .env files for each:

  • .env.development
  • .env.staging
  • .env.production

Each file will contain environment-specific variables, such as database credentials, API keys, and other configuration details.

For example, development and production:

# docker-compose.development.yml
-version: '3.8'
-services:
-  db:
-    ...
-  app:
-    ...
-    environment:
-      MYSQL_HOST: db
-      MYSQL_USER: ${MYSQL_USER}
-      MYSQL_PASSWORD: ${MYSQL_PASSWORD}
-      MYSQL_DB: ${MYSQL_DATABASE}
-      NODE_ENV: development
-
# docker-compose.production.yml
-version: '3.8'
-services:
-  db:
-    ...
-  app:
-    ...
-    environment:
-      MYSQL_HOST: db
-      MYSQL_USER: ${MYSQL_USER}
-      MYSQL_PASSWORD: ${MYSQL_PASSWORD}
-      MYSQL_DB: ${MYSQL_DATABASE}
-      NODE_ENV: production
-`

Then you would select the specific environment with your run command:

docker-compose -f docker-compose.development.yml up -d

Docker won’t know by default which .env file to use from that command however. Assuming all the files are in the same directory you can use Bash substitution to specify the source of the environment specific variables:

export $(cat .env.development | xargs) && docker-compose -f docker-compose.development.yml up -d
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Nodemon.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Nodemon.html deleted file mode 100644 index 3a80eaf..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Nodemon.html +++ /dev/null @@ -1,50 +0,0 @@ -Nodemon - My Zettelkasten - - - - -

Nodemon

We don’t want to have to restart the local server every time we make a change to our files. We can use nodemon instead of node when running our index.js file so that file-changes are immediately registered without the need for a restart.

This is a wrapper around the node command so it doesn’t require any configuration. Once installed, update your start script from node index.js to nodemon index.js.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Non_null_assertion_in_TypeScript.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Non_null_assertion_in_TypeScript.html deleted file mode 100644 index 3b0ae56..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Non_null_assertion_in_TypeScript.html +++ /dev/null @@ -1,52 +0,0 @@ -Non-null assertion - My Zettelkasten - - - - -

Non-null assertion

Oftentimes you will encounter errors of the form:

Property [property_name] does not exist on type [type_name].ts(2339)

This means the interpreter is not able to determine whether the property which you are seeking to change exists. It can’t be sure that you are not trying to update a property that is either null or undefined. This is good type checking but it means that in cases when you know the property either exists or will exist at runtime, you are going to face a code-breaking error.

To get around this you can use non-null assertion. Like the name suggests, here you are saying to TypeScript: thanks but I am sure this property exists. When you do this you get the value you are trying to change with null and undefined excluded from it.

This typically occurs when you are assigning a property to a value and TS doesn’t know whether the value will exist or be accessible at this point in the runtime. A good scenario would be dynamic data passed into a function:

function doSomethingWith(typeAlias: ITypeAlias) {
-  let x = typeAlias!.somePropertyEvidentAtRuntime;
-}

However it should be used carefully and sparingly because you are obviously turning off core type-checking and overuse nullifies the purpose of TypeScript.

One way to get around it is to use better Type_guarding_and_narrowing and conditionality and to cover cases where the value may be undefined.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/None_in_Python.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/None_in_Python.html deleted file mode 100644 index 83f8431..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/None_in_Python.html +++ /dev/null @@ -1,70 +0,0 @@ -None in Python - My Zettelkasten - - - - -

None in Python

None is not null, it is closer to undefined in JS. If you define a variable as None, the variable exists, it is just not yet defined.

Using None is a pattern similar to using let in JS to name a variable and definine it later on.

temperature = None

If we logged temperature it would give us None rather than a null pointer error.

With None we can use is None and is not None, special predicates for working with None only. This is a akin to using if (x !== undefined) in TypeScript

winner = None
-print('winner:', winner)
-# winner: None
-print('winner is None:', winner is None)
-# winner is None: True
-print('winner is not None:', winner is not None)
-# winner is not None: False
-print(type(winner))
-# <class 'NoneType'>
-# Now set winner to be True
-print('Set winner to True')
-# Set winner to True
-winner = True
-print('winner:', winner)
-# winner: True
-print('winner is None:', winner is None)
-# winner is None: False
-print('winner is not None:', winner is not None)
-# winner is not None: True
-print(type(winner))
-# <class 'bool'>
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Numbers_in_Python.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Numbers_in_Python.html deleted file mode 100644 index 4d29d1c..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Numbers_in_Python.html +++ /dev/null @@ -1,67 +0,0 @@ -Numbers in Python - My Zettelkasten - - - - -

Numbers in Python

Distinguishing int and float

  • In Python we have floats and integers and we can coerce one into the other
  • A // as an operator means float division. This obviously provides greater precision than int division /.
  • There is no increment (++) or decrement (--) operator in Python
# Integers and floats
-count = 1
-print(count)
-# 1
-print(type(count))
-# <class 'int'>
-
-exchange_rate = 1.83
-print(exchange_rate)
-# 1.83
-print(type(exchange_rate))
-# <class 'float'>
-
-print(float(count))
-# 1.0
-
-print(int(exchange_rate))
-# 1
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Object_language_and_meta_language.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Object_language_and_meta_language.html deleted file mode 100644 index 06b1c2a..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Object_language_and_meta_language.html +++ /dev/null @@ -1,50 +0,0 @@ -Object and metalanguages - My Zettelkasten - - - - -

Object and metalanguages

When we talk about a language we call that language the object language. A metalanguage is a language used to describe some object language.

When we are developing a formal logical language (which we may call SL or PL for ‘sentential’ and ‘propositional’ logic respectively), the formal language is the object language and natural language (e.g. English) is the metalanguage.

Demonstration

If we talk about German in English, German in the object language and English is the metalanguage.

Use and mention

There is an associated distinction: that of use and mention.

When we create an expression in a language we are said to use that language. When we remark upon said expression we are said to be mentioning the language. This distinction may correspond to the object and metalanguage difference above but doesn’t have to; use and mention can happen in the same language. For example:

'London' is the word that denotes the capital of the UK.

Metavariables

A metalinguistic variable (metavariable for short) is an expression in the metalanguage that is used to talk generally about expressions of the object language. The convention in these notes will be to embolden single letters when these letters are used as metavariables.

For example, instead of saying ‘P & Q’ is an expression comprising two atomic sentences and a conjunction we might say *P is an expression comprising two atomic sentences and a conjunction. In this instance P is a metavariable in the metalanguage mentioning the expression P & Q in the object language

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Observer_pattern.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Observer_pattern.html deleted file mode 100644 index cc15bd4..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Observer_pattern.html +++ /dev/null @@ -1,96 +0,0 @@ -Observer pattern - My Zettelkasten - - - - -

Observer pattern

The Observer design pattern is also known as the ‘publish/subscribe’ pattern.

The observer pattern is a software design pattern in which an object, called the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by calling one of their methods.

The observer pattern instantiates a one-to-many relationship between the subject and its observers: when one object updates, it notifies many other objects that it has been updated.

This is another design pattern that is useful when implementing a global state. When the subject updates its subjects must follow suit and adapt to its changes. Here the subject is the instrument for maintaining the global state.

Subject class

This class maintains a list of observers that will be notified when it is updated. It should have the following attributes:

  • array of existing observers
  • an addObserver method which pushes an observer onto the observers array
  • a removeObserver method that does the opposite
  • a notify method that broadcasts to the observers that a change has happened

Observer class

Observers must implement an update method that will be called by the subject’s notify method.

Example

class Subject {
-  observers = [];
-
-  getCurrentTime() {
-    var d = new Date();
-    return `${d.getHours()}:${d.getMinutes()}:${d.getSeconds()}`;
-  }
-
-  addObserver(...observer) {
-    for (const o of observer) {
-      this.observers.push(o);
-    }
-  }
-  removeObserver(observer) {
-    const match = this.observers.findIndex((element) => element === observer);
-    this.observers.splice(match, 1);
-  }
-  notify() {
-    for (const o of this.observers) {
-      o.update(`I was updated at ${this.getCurrentTime()}`);
-    }
-  }
-}
-
-class ObserverA {
-  state = "I am observer A";
-  update(newState) {
-    this.state = newState;
-  }
-}
-
-class ObserverB {
-  state = "I am observer B";
-
-  update(newState) {
-    this.state = newState;
-  }
-}
-
-let subjectInstance = new Subject();
-let obsAInstance = new ObserverA();
-let obsBInstance = new ObserverB();
-
-subjectInstance.addObserver(obsAInstance, obsBInstance);
-
-subjectInstance.notify();
-console.log(obsBInstance.state);
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Ohms_Law.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Ohms_Law.html deleted file mode 100644 index fc40b7c..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Ohms_Law.html +++ /dev/null @@ -1,54 +0,0 @@ -Ohm’s Law - My Zettelkasten - - - - -

Ohm’s Law

The relationship between current, voltage, and resistance is defined by Ohm’s Law:

The current flowing from one point to another is equal to the voltage accross these points divided by the resistance between them.

$$ -I = \frac{V}{R} -$$

As an application, consider a circuit with a 9V battery with a 10,000 \(\Omega\) resistor attached across its terminals.

The current flowing through the resistor can be calculated as follows:

$$ -\frac{9V} {10,000\Omega} = 0.0009 \textsf{A} (0.9 \textsf{mA}) -$$

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/OpenSearch.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/OpenSearch.html deleted file mode 100644 index a12e5ae..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/OpenSearch.html +++ /dev/null @@ -1,130 +0,0 @@ -OpenSearch - My Zettelkasten - - - - -

OpenSearch

Background

OpenSearch is the AWS implementation of the opean source Elasticsearch search engine. It was formally known as “AWS Elasticsearch”.

It has many features but the core usage is to create searchable indicies of a given content domain such as, for example, a website or content management system. This enables the quick search and retrieval of documents without using expensive database queries.

Key concepts

We will introduce the main concepts with the example of an internal intranet for which we want to create a searchable index. The intranet comprises hundreds of pages. Each page has the following metadata, conforming to the following example.

{
-  "title": "Internal News",
-  "author": "Jane Doe",
-  "published_date": "2023-11-01T00:00:00Z",
-  "tags": ["news", "internal"],
-  "categories": ["communication"],
-  "content": "Today's internal news and updates are..."
-}

Create domain

The OpenSearch domain is a managed environment which hosts OpenSearch clusters. It can contain one or more clusters.

The domain provides network endpoints you use to communicate and send requests. Typical requests:

  • ingest data
  • index data
  • run search query and return matches

Clusters and nodes

A cluster is the highest level of organisation within an OpensSearch domain that contains your indexed data. It processes all the search queries and handles tasks like indexing, searching, and managing documents.

A cluster comprises nodes. Nodes are individual servers that hold part of the cluster’s data. Each node participates in the indexing and searching of the cluster’s data.

  • This distributed architecture helps in balancing the load and ensuring high availability.
  • Data can be replicated accross nodes, making the system resiliant against data loss
  • You can add more nodes to the cluster to handle increased data and traffic, making the system adaptable to changing needs.

Define index and mappings

Assuming the domain has been created. The next step is to create an index for the data, say intranet_pages. An index is basically a collection where the data is stored, similar to a database. Each entry is a document in this collection.

Our index will store each webpage as a document.

We specify the data that we want to store using an index mapping. For instance we may not want to store all the metadata for each page, preferring only to index a subset of the properties. In this example we will store all the data. We would achieve this with the following:

{
-  "mappings": {
-    "properties": {
-      "title": { "type": "text" },
-      "author": { "type": "keyword" },
-      "published_date": { "type": "date" },
-      "tags": { "type": "keyword" },
-      "content": { "type": "text" }
-    }
-  }
-}

The mapping will be utilised in the following scenarios:

  • storing data:
    • when a new document is added to the intranet_pages index, it will adhere to the defined mappings
    • it will have to have the properties specified in the mapping in order to be added
  • searching data:
    • when executing searches, OpenSearch utilizes the mappings to understand the type of data in each field and optimizes search queries accordingly
  • assessing relevance:
    • proper mappings allow OpenSearch to accurately score and rank search results based on relevance.

Ingest data (bulk import and/or scraper)

In order to create the index that we previously defined with a mapping it is necessary to implement some sort of mechanism for collating the metadata that matches the mapping. This would be a crawler or scraper that might be implemented with a lambda. This is a key part of the ingestion process.

Alternatively the data could be bulk imported in a format that maps to the index.

Querying and searching

Having established the crawler (and some kind of search interface), we can now run queries against the OpenSearch domain.

A basic example of the structure of a query would be as follows:

GET /intranet_pages/_search
{
-  "query": {
-    "match": {
-      "content": "project"
-    }
-  }
-}

Here we search against the content mapping to find pages that contain the word “project”.

Example of the data returned:

{
-  "hits": {
-    "total": { "value": 100 },
-    "hits": [
-      {
-        "_index": "intranet_pages",
-        "_id": "1",
-        "_score": 1.2,
-        "_source": {
-          "title": "Project ABC Launch",
-          "author": "John Doe",
-          "published_date": "2023-01-01T00:00:00Z",
-          "tags": ["project", "launch"],
-          "content": "Details about the launch of Project ABC..."
-        }
-      }
-      // Additional results here
-    ]
-  }
-}

Search patterns

Below are further examples of commonly used search patterns.

Multiple conditions

Find documents that are authored by Jane Doe that contain the word “meeting”. must stands for boolean AND:

{
-  "query": {
-    "bool": {
-      "must": [
-        { "match": { "content": "meeting" } },
-        { "match": { "author": "Jane Doe" } }
-      ]
-    }
-  }
-}

Find documents that contain either the word “meeting” or the word “project” in their content. should stands for boolean OR:

{
-  "query": {
-    "bool": {
-      "should": [
-        { "match": { "content": "meeting" } },
-        { "match": { "content": "project" } }
-      ],
-      "minimum_should_match": 1
-    }
-  }
-}

minimum_should_match specifies the number of conditions that should match.

Query by date ranges

Find pages published after a certain date:

{
-  "query": {
-    "range": {
-      "published_date": {
-        "gte": "2023-01-01T00:00:00Z"
-      }
-    }
-  }
-}
{
-  "query": {
-    "bool": {
-      "should": [
-        { "match": { "fileId": "val" } },
-        { "match": { "programmeId": "val" } },
-        { "match": { "guid": "val" } }
-      ],
-      "minimum_should_match": 1
-    }
-  }
-}
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Operating_system_API.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Operating_system_API.html deleted file mode 100644 index 6761135..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Operating_system_API.html +++ /dev/null @@ -1,50 +0,0 @@ -Operating system API - My Zettelkasten - - - - -

Operating system API

A user can interact with the operating system either via the GUI or the shell. (Both ultimately access the OS via the shell since the UI is an abstraction layer of the shell.)

When programs interact with the operating system they use the operating system’s API directly. The GUI and shell also invoke the OS API but the access is mediated.

Every OS has an API. This specification details how a program should interact with the OS, exposing functions, properties and data types.

Whether using the GUI or a terminal emulator, the shell translates the user’s commands into API calls. The API the invokes internal operating system code to perform the action.

OS API diagram

Example: opening a file

A user can use a file explorer and the mouse to open a file. Or they can open the file by invoking it from the terminal.

A running application doesn’t have to do this. If it’s remit includes opening files, it can do so by calling the OS API.

On a Unix-like system the applicaton would use the open API function to open the file:

open("foo.txt", 0_WRONLY|0_CREAT)

This command makes the action write-only and creates the file because it does not yet exist. When the user opens a file in their File Explorer, the application translates their graphical actions into this API call.

Different OSs have different APIs

Unix-like and Linux operating systems use variations on the Portable Operating System Interface (POSIX) standard. This defines the OS API and also the rules for the shell’s behaviour and its included utilities.

Variations on this include Cocoa, macOS’s API and Android’s Android Platform API.

Windows has its own API called The Windows API. The original version was 16-bit called Win16, then when it moved to 32-bits it became Win32. When it moved to an x86 instruction_set_architecture it became Win64. Starting with Windows 10, it introduced the Universal Windows Platform which aims to make app development consistent accross different devices that run Windows.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Order_of_operations.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Order_of_operations.html deleted file mode 100644 index cc0c220..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Order_of_operations.html +++ /dev/null @@ -1,52 +0,0 @@ -Order of operations - My Zettelkasten - - - - -

Order of operations

  1. Evaluate expressions in parentheses
  2. Evaluate exponents
  3. Evaluate multiplications and divisions from left to right in the order that they appear
  4. Evaluate additions and subtractions from left to right in the order that they appear.

In the absence of grouping symbols, addition holds no precedence over subtraction and vice versa.

15 - 8 + 4 = 7 + 4
-					= 11
15 - 8 + 4 = 15 - 12
-					 = 3
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Package_management_in_NodeJS.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Package_management_in_NodeJS.html deleted file mode 100644 index b944475..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Package_management_in_NodeJS.html +++ /dev/null @@ -1,50 +0,0 @@ -Package management - My Zettelkasten - - - - -

Package management

List installed packages

npm list

This will return a recursive tree that lists dependencies, dependences of dependencies, … and so on. To limit the depth you can add the --depth= flag. For example to see only your installed packages and their versions use npm list --depth=0.

View package.json data for an installed package

We could go to the NPM registry and view details or we can quickly view the package.json for the dependency with the command npm view [package_name]

We can pinpoint specific dependencies in the package.json, e.g. npm view [package_name] dependencies

View outdated modules

See whether your dependency version is out of date use npm outdated. This gives us a table, for example:

Pasted image 20220411082627.png

  • Latest tells us the latest release available from the developers
  • Wanted tells us the version that our package.json rules target. To take the first dependency as an example. We must have set our SemVer syntax to ^0.4.x since it is telling us that there is a minor release that is more recent than the one we have installed but is not advising that we update to the latest major release.
  • Current tells us which version we currently have installed regardless of the version that our package.json is targeting or the most recent version available.

Updating

npm update only updates from current to wanted. In other words it only updates in accordance with your caret and tilde rules applied to semantic versioning.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Packet_switching_British_precursors.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Packet_switching_British_precursors.html deleted file mode 100644 index 23fed3b..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Packet_switching_British_precursors.html +++ /dev/null @@ -1,50 +0,0 @@ -Packet switching British precursors - My Zettelkasten - - - - -

Packet switching British precursors

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Pacman.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Pacman.html deleted file mode 100644 index 275f748..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Pacman.html +++ /dev/null @@ -1,50 +0,0 @@ -Pacman - My Zettelkasten - - - - -

Pacman

List all installed packages

pacman -Qe

List all packages installed by current user

pacman -Qqe

Uninstall, and list dependencies for package to be uninstalled

pacman -Rcns
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Passing_arguments_and_options_to_Bash_scripts.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Passing_arguments_and_options_to_Bash_scripts.html deleted file mode 100644 index 7128d04..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Passing_arguments_and_options_to_Bash_scripts.html +++ /dev/null @@ -1,78 +0,0 @@ -Passing arguments and options to Bash scripts - My Zettelkasten - - - - -

Passing arguments and options to Bash scripts

Relation between commands and programs

Whenever we issue a command in bash we are running an executable program that the command token references. This is why when we create our own bash scripts we must run chmod to make them executable. When we issue a command like ./do_something.sh we are running an executable program.

When we run a program like cd or npm we don’t have to type ./cd.sh or ./npm.sh. This is because a reference to the program file is already in our $PATH.

In the case of cd, this is an in-built program and as such it will be sourced from a binary and we have a reference to the binary in path. In the case of npm, this is not an in-built program however in order to run it we must already have it in our PATH.

Passing arguments

A script is really just a function that runs when you source it. As such there needs to be a way for you to pass data to the function so that it can actually act like a function and take arguments. When we use for example cd ./Desktop we are passing a directory name as an argument to the cd program. We can do the same thing with our custom bash scripts.

To pass an argument we simply add the values after the script in the command. For example:

./arguments.sh Thomas 33

We can use built-in variables to return information about the invocation of this script:

#!/bin/bash
-
-echo "File is called $0"
-echo "The arguments provided are $@"
-echo "The first argument is $1"
-echo "The second argument is $2"
-echo "Your name is $1 and you are $2 years old"
-echo "There were $# arguments"

This outputs:

File is called ./arguments.sh
-The arguments provided are Thomas 33
-The first argument is Thomas
-The second argument is 33
-Your name is Thomas and you are 33 years old
-There were 2 arguments.

Key points:

  • $0 designates the script or function that is being executed
  • $@ designates a list of all the arguments that are passed to the script
  • $1... designates each individual argument
  • $# gives us a count of the number of arguments

Passing options

Options differ from arguments in that they are prepended with - and they can be passed in any order. We use the getops program to parse the options that the user inputs with their command.

We can demonstrate this with a script that takes in a username and password as options.

We can handle an option-based input like:

some-program -u thomas -p password123

With the following construct:

while getopts u:p: option; do
-  case $option in
-    u) user=$OPTARG;;
-    p) pass=$OPTARG;;
-  esac
-done
-
-echo "user: $user / pass: $pass"

Which returns:

user: thomas / pass: password123

Here we set up a while loop against the getopts command to parse the options in the stdin and store each one in a option. We run each option through a case statement and individuate each one, storing them in dedicated local variables via the global $OPTARG variable

The role of the colons

Using a colon after each option means that the script will expect the given option to have a value. If we put a colon before each of the options we expect this will allow us to view any option the user provides in our option handler. This is useful when you are working with very many options, as with a command-line program.

This version demonstrates a more exhaustive use case:

while getopts :u:p: option; do
-  case $option in
-    u) user=$OPTARG;;
-    p) pass=$OPTARG;;
-    a) echo "got the 'a' flag";;
-    b) echo "got the 'b' flag";;
-    ?) echo "Don't know what $OPTARG is!"
-  esac
-done
-
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Passing_arguments_to_Python_scripts.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Passing_arguments_to_Python_scripts.html deleted file mode 100644 index eb28770..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Passing_arguments_to_Python_scripts.html +++ /dev/null @@ -1,60 +0,0 @@ -Passing arguments to Python scripts - My Zettelkasten - - - - -

Passing arguments to Python scripts

sys.argv is a list that contains the command-line arguments passed to a Python scripts.

  • sys.argv[0] = the name of script
  • sys.argv[1] = the first argument
  • sys.argv[2] = the second argument, and so on

Example invocation:

python3 ./my_script.py argument_one argument_two
-
import sys
-
-print(sys.argv[0])
-print(sys.arg)
-print(sys.argv[1])
-
-# my_script.py
-# ['my_script.py', 'argyment_one', 'argument_two']
-# argument_one
-
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Peer_to_peer_network.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Peer_to_peer_network.html deleted file mode 100644 index 4b0af14..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Peer_to_peer_network.html +++ /dev/null @@ -1,50 +0,0 @@ -Peer to peer network - My Zettelkasten - - - - -

Peer to peer network

A decentralised network model where each participant (peer) acts as both a client and a server.

Resources are shared directly between peers rather than being coordinated via a server.

Under a server architecture, multiple requests are made from different hosts for resources. The server manages this load and is in control of what is being shared, to whom, and when. With P2P there is no central authority equivalent to this. Each peer both shares and consumes resources and in this sense is both a client and a server.

A practical example of this is torrenting - an applicaton of P2P technology to file sharing.

Benefits

  • Decentralisation, no central authority, also means no single point of failure.
  • Scalable: the network capacity grows with the number of users (contrast servers)
  • Efficiency: idle resources of peers are put to use
  • Improved performance for popular content

Drawbacks

  • Security: potential for malicious peers and content
  • Inconsistent availability of resources
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Ports_in_NodeJS.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Ports_in_NodeJS.html deleted file mode 100644 index 8060539..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Ports_in_NodeJS.html +++ /dev/null @@ -1,50 +0,0 @@ -Ports - My Zettelkasten - - - - -

Ports

When working in development we are able to specify the specific port from which we want top serve our application. In production, we do not always have this control: the port will most likely be set by the provider of the server environment.

While we may not know the specific port, whatever it is, it will be accessible via the PORT environment variable. So we can use this when writing our event listeners:

const port = process.env.PORT || 3000;

This way, if a port is set by the provider it will use it. If not, it will fall back to 3000.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Practical_walkthrough_Lambda_creation_within_AWS.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Practical_walkthrough_Lambda_creation_within_AWS.html deleted file mode 100644 index 476ef77..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Practical_walkthrough_Lambda_creation_within_AWS.html +++ /dev/null @@ -1,64 +0,0 @@ -Practical walkthrough of creating a Lambda function via the AWS Management Console - My Zettelkasten - - - - -

Practical walkthrough of creating a Lambda function via the AWS Management Console

Basic set-up

First we name the function and accept the defaults:

This presents us with the function dashboard - a graphical representation of the Lambda showing triggers as an input and destination as an output:

Beneath this we have a code editor with the handler function with a basic boilerplate:

Adding a trigger

Next we need to add a trigger that execute the handler.

We will do this using AWS_API_Gateway. We select “Add trigger” from the dashboard view and input basic settings:

Now we see this step displayed in the dashboard:

With the endpoint and other settings displayed:

If we go to the endpoint URL (https://4kjqwbvd7g.execute-api.us-east-1.amazonaws.com/default/myFirstFunction), we will see the output: Hello from Lambda.

Handling parameters

We can make the example more realistic by expanding the handler to accept query parameters. We do this by accessing the value queryStringParameters on the event object:

exports.handler = async (event) => {
-  const name = event.queryStringParameters && event.queryStringParameters.name;
-
-  let message = "Hello Lambda";
-
-  if (name !== null) {
-    message = `Hello ${name}`;
-  }
-
-  const response {
-    statusCode: 200,
-    body: JSON.stringify(message)
-
-  }
-};

If we now access https://4kjqwbvd7g.execute-api.us-east-1.amazonaws.com/default/myFirstFunction?name=Thomas

We get Hello Thomas as output.

For a more advanced API with multiple endpoints and parameters, it’s easiest to use Postman:

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Prefixes_for_units_of_electrical_measurement.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Prefixes_for_units_of_electrical_measurement.html deleted file mode 100644 index ca739e9..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Prefixes_for_units_of_electrical_measurement.html +++ /dev/null @@ -1,50 +0,0 @@ -Prefixes for unit of electrical measurement - My Zettelkasten - - - - -

Prefixes for unit of electrical measurement

In electronics we are often dealing with units that are very large or very small, thus we rely on exponents for formal expression.

PrefixSymbolExpression as exponentExpression as decimal valueEnglish word
Terra-T\(10^{12}\)1,000,000,000,000trillion
Giga-G\(10^9\)1,000,000,000billion
Mega-M\(10^6\)1,000,000million
Kilo-k\(10^3\)1,000thousand
Centi-c\(10^{-2}\)0.01hundredth
Milli-m\(10^{-3}\)0.001thousandth
Micro-\(\mu\)\(10^{-6}\)0.0000001millionth
Nano-n\(10^{-9}\)0.0000000001billionth
Pico-p\(10^{-12}\)0.0000000000001trillionth

For example, with Amps we tend not to use 1 whole amp as this is far too large for most electronics. More common is the milliampere (mA) and the microampere (\(\mu\)A).

A mA is equal to one thousandth of an ampere: 0.001 A. It takes 1000 milliamperes to equal one ampere.

A \(\mu\)A is equal to one millionth of an ampere: 0.0000001 A. It takes one million micoramperes to equal one ampere.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Prime_factorization.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Prime_factorization.html deleted file mode 100644 index eaa488a..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Prime_factorization.html +++ /dev/null @@ -1,50 +0,0 @@ -Prime factorisation - My Zettelkasten - - - - -

Prime factorisation

Prime factorisation is the activity of expressing a composite number as the unique product of prime numbers. There are two main approaches to this:

    • factor* trees
  • repeated division by two

Factor trees: we take a number \(n\) and break it down into two factors of \(n\). We then repeat this process with the resulting factors working recursively until the numbers we are left with are primes.

Untitled Diagram-Page-1.drawio.png The prime factors of 27 are 2, 3, 3

it doesn’t matter which products we choose as the interim factors, we should always reach the same outcome: Untitled Diagram-Page-3.drawio 1.png

Untitled Diagram-Page-2.drawio.png

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Primes_and_composites.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Primes_and_composites.html deleted file mode 100644 index 9cd1a3f..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Primes_and_composites.html +++ /dev/null @@ -1,50 +0,0 @@ -Prime and composite numbers - My Zettelkasten - - - - -

Prime and composite numbers

Definition of a prime number:

For any whole number \(n\) where \(n \neq 1\), \(n\) is prime if and only if its sole factors are \(1\) and \(n\)

Definition of a composite number:

For any whole number \(n\), \(n\) is composite just if \(n\) is not prime

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Primitive_types.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Primitive_types.html deleted file mode 100644 index 467642b..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Primitive_types.html +++ /dev/null @@ -1,60 +0,0 @@ -Primitive types - My Zettelkasten - - - - -

Primitive types

The most basic type level is the one already present in JavaScript itself: the primitive data types: boolean, string and number . These are the types that would be returned from a typeof expression in ordinary JavaScript

Type inference

You can explicitly declare these data types yourself when you create a variable with var, const, or let if you like, but it is generally unnecessary since Typescript is intelligent enough to perform type inference and will know from what you write which type you mean.

const age: number = 32;
-const name: string = "Thomas";
-const one: boolean = true;
-const zero: boolean = false;

Arrays

With arrays that you directly define the type will also be inferred but it can be helpful to explicitly declare them. If you declare an empty array, it is necessary to assign empty brackets.

const store: number[] = [1, 2, 3]; // Populated array
-const store: string[] = []; // Empty array

Object

Object is a valid type declaration in TS but it is not particularly helpful since it becomes similar to using any given that most primitive types in JavaScripts prototypically inherit from an Object.

Generally, when you use objects in TypeScript you type them as custom types.

Array of (untyped) objects

If we just know that it is going to be an array of objects we can use:

const arrOfObj = {}[]

If we wish to define a particular shape but without defining a type:

const arrOfObj = { name: string, age: number }[]

But better for reusability to do:

type ArrayOfObj = {
-  name: string,
-  age: number
-}
-
-const arrOfObj: ArrayOfObj[] = [{}, ...]
-
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Printing_values_in_C.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Printing_values_in_C.html deleted file mode 100644 index a963262..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Printing_values_in_C.html +++ /dev/null @@ -1,52 +0,0 @@ -Printing values in C - My Zettelkasten - - - - -

Printing values in C

To print a literal

printf("hello world")

To print a variable

int age = 25
-print("%d", age)
-

The %d is an example of a format specifier. It is the decimal integer format specifier.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Process_module_in_NodeJS.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Process_module_in_NodeJS.html deleted file mode 100644 index c9de0d6..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Process_module_in_NodeJS.html +++ /dev/null @@ -1,82 +0,0 @@ -The process module in Node.js - My Zettelkasten - - - - -

The process module in Node.js

process is a core module and a global object accessible from anywhere in a Node.js application. It contains functionality that allows us to interact with information about the current process instance of Node.

For example, we can use it to get environment information, read environment variables, parse arguments that are passed to the run command, communicate with the terminal and exit the current process.

Managing runtime environments

See Managing Environments.

Accessing arguments: process.argv

We can use process.argv to return an array containing the command-line arguments passed when a Node process is launched. This could be a whole-app entrypoint (i.e. index.js) or a single file we are running.

For instance if we run the following file:

// process-demo.js
-console.log(3 + 3);
-console.log(process.argv);

We get:

6
-[
-  '/Users/thomasbishop/.nvm/versions/node/v16.10.0/bin/node',
-  '/Users/thomasbishop/prepos/testNode.js'
-]

The first item is the last executed process. The second is the array of arguments.

In the array, the first value is a reference to the Node runtime binary. The second is the file that was passed to Node.

If we passed in a parameter we would get that too:

node process-demo.js --fakeFlag

Gives us:

[
-  "/Users/thomasbishop/.nvm/versions/node/v16.10.0/bin/node",
-  "/Users/thomasbishop/prepos/testNode.js",
-  "--fake-flag",
-]

When writing Node CLI applications we can write functions that parse standard input. For example:

function parseStandardInput(flag) {
-  let indexAfterFlag = process.argv.indexOf(flag);
-  console.log(process.argv[indexAfterFlag]);
-}

Say we ran a program that took in a username:

node userName.js --user Thomas

Then parseStandardInput("--user") would give us "thomas"

Standard input and output

Below is the most basic use case: writing to the output.

// alpha.js
-process.stdout.write("Hello from file \n");
node alpha.js
-Hello from file

Typically we want to write and read data that the user provides. To do this we need to wait on that event. So we use Node’s asynchonous events. We wait on the data event:

process.stdin.on("data", (data) => {
-  process.stdout.write(data.toString().trim());
-});
-
-process.stdout.write("\n What is your name? \n");
-process.stdout.write(` \n > `);

This waits for whatever input is given and then echoes it.

Currently there is no way to end this process; it will just keep echoing the input.

So we add an exit clause:

process.stdin.on("data", (data) => {
-  process.stdout.write(data.toString().trim());
-  process.exit();
-});

We can also execute functionality on the exit event:

process.on("exit", () => {
-  // Do something
-});

Timings can also obviously be managed via the setTimeout and setInterval methods.

Additional useful methods

process.stdout.clearLine();
-process.stdout.cursorTo([int]);

readline

The core readline module simplifies the handling of standard input and output by providing a wrapper. It reads the input stream line by line. Basic usage:

var readline = require("readline");
-
-var rl = readline.createInterface(process.stdin, process.stdout);
-
-rl.question("What is your age? ", (age) => {
-  console.log("Your age is: " + age);
-});

Usage scenarios at: https://www.geeksforgeeks.org/node-js-readline-module/

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Processes.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Processes.html deleted file mode 100644 index 3a70986..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Processes.html +++ /dev/null @@ -1,53 +0,0 @@ -Processes - My Zettelkasten - - - - -

Processes

Programs are sequences of machine instructions stored in a file. However they do not work by themselves. Something needs to load the file’s intructions into memory, direct the CPU to run the program and manage it during runtime. The OS does this via processes.

A process is a running instance of a given program. It can be thought of as a container in which a program runs. This container includes:

  • a copy of the program code loaded into memory
  • a memory address
  • other information about the state of the process

Other than the init process started by the kernel (PID1) (see systemd), every process has a parent process that started it. This parent-child relationship creates a tree of processes.

It is possible that a parent process will terminate before one of its child processes. In this instance the child becomes an orphan. When this occurs in #Linux, the orphan process is adopted by init.

Below, I have used the pstree utility to list all the running processes on my machine hierarchically.

diagram of pstree output

Children are represented vertically and horizontally.

├─terminator─┬─zsh───tmux: client
-│            ├─zsh───pstree
-│            └─6*[{terminator}]
-

For instance here, terminator is a child of init, as are zsh and tmux but they are also children of terminator.pstree is a child of zsh and therefore also a child (grandchild) of terminator.

Each process has a unique identifier called a process identifier, a processID or just PID.

systemd

ps

Monitoring processes and resources

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Prop_types_in_React.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Prop_types_in_React.html deleted file mode 100644 index 451ec73..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Prop_types_in_React.html +++ /dev/null @@ -1,114 +0,0 @@ -Prop types - My Zettelkasten - - - - -

Prop types

The prop-types package allows us to introduce type-checking during the development runtime of a React application. With larger applications or those with complex data flows, this can help reduce errors and bugs during development. This is a bit like using TypeScript but on a more minimal level.

Install

npm install prop-types

Usage

import PropTypes from "prop-types";

Examples

Say we have a component with the following props:

function Page(props) {
-  const classes = useStyles();
-  return (
-    <React.Fragment>
-      <Typography className={classes.heading} variant="h1">
-        {props.h1}
-      </Typography>
-      {props.h2 !== "" && <Typography variant="h2">{props.h2}</Typography>}
-      {props.paras.map((paragraph, index) => (
-        <Typography
-          className={classes.paragraph}
-          key={index}
-          variant="body1"
-          gutterBottom
-        >
-          {paragraph}
-        </Typography>
-      ))}
-      {props.children}
-      <Button
-        className={classes.button}
-        variant="contained"
-        color="primary"
-        disableElevation
-        component={Link}
-        to={props.buttonLink}
-      >
-        {props.buttonText}
-      </Button>
-    </React.Fragment>
-  );
-}

Before the final export default statement, we would add a PropTypes object that specifies the data or reference type that is required by each prop cited in the component:

Page.propTypes = {
-  h1: PropTypes.string.isRequired, // should be string data type, must be present
-  h2: PropTypes.string, // as above but optional
-  paras: PropTypes.array, // should be array reference type
-  buttonLink: PropTypes.string,
-  buttonText: PropTypes.string,
-  children: PropTypes.node, // can be anything (element, type, JSX) that is rendered to the screen
-};

If one of these type checks failed you get a very semantic Warning in the console specifying which prop is not consistent with your prop type declaration.

Additional checks

Above are the most frequent and basic checks, but there are many other conditions you can check for:

// The full list of types
-[propName]: PropTypes.array,
-[propName]: PropTypes.bool,
-[propName]: PropTypes.func,
-[propName]: PropTypes.number,
-[propName]: PropTypes.object,
-[propName]: PropTypes.string,
-[propName]: PropTypes.symbol,
-
-// Anything that can be rendered: numbers, strings, elements or an arrayor fragment) containing these types.
-[propName]: PropTypes.node,
-
-// A function
-
-[propName]: PropTypes.func
-
-// An object that could be one of many types
-[objectProp]: PropTypes.oneOfType([
-    PropTypes.string,
-    PropTypes.number,
-  ]),
-
-// An array of a certain type
-[arrayProp]: PropTypes.arrayOf(PropTypes.number),
-
-// An object with property values of a certain type
-[objectProp]: PropTypes.objectOf(PropTypes.number),
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Proper_shebang_syntax.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Proper_shebang_syntax.html deleted file mode 100644 index 7b54f5e..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Proper_shebang_syntax.html +++ /dev/null @@ -1,50 +0,0 @@ -Proper shebang syntax - My Zettelkasten - - - - -

Proper shebang syntax

This is a more portable way of writing the shebang because the location of Bash on different systems can vary.

#!/usr/bin/env Bash

Rather than:

#!/bin/bash
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Props_in_React.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Props_in_React.html deleted file mode 100644 index ba29962..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Props_in_React.html +++ /dev/null @@ -1,104 +0,0 @@ -Props - My Zettelkasten - - - - -

Props

Types or interfaces?

They are mostly interchangeable but there are some specific differences

Interfaces

  • Classes and other interfaces can extend an interface but not a type

    interface Animal {
    -  name: string;
    -}
    -
    -interface Bear extends Animal {
    -  honey: boolean;
    -}
  • You can add properties to an interface without generating a double declaration error:

    interface Window {
    -    }
    -
    -interface Window {
    -  ts: TypeScriptAPI;
    -}

Types

You can create unions with types but not interfaces.

The consensus seems to be that interfaces should be used over types unless there are ocassions when you do not want a type to be extendable / redeclarable. Or when you want to use unions.

How we type props

The custom is to type props as an interface. This way we can easily type function prop types.

interface IProps {
-  people: {
-    name: string;
-    age: number;
-    note?: string;
-  }[];
-}
-
-const List: React.FC<IProps> = ({people}: IProps) => {
-    return()
-}
-
-// Note we say that the props into the func component are of type IProps
-// And we destructure the people key
-

Then in the parent:


-const [people, setPeople] = useState<IState['people']>({});
-
-<List props={people}>
-

Common types for props

Object with any number of properties

interface IProps {
-  obj: {};
-}

Array of objects

interface IProps {
-  val1: string;
-  val2: boolean;
-}
-[];

Functions


-// Function that doesn't receive or return anything
-interface IProps {
-    onClick: () => void;
-}[]
-
-// Function with named parameter
-interface IProps {
-    onClick: (id: number) => void;
-}[]
-
-// Function that takes an event
-onChange: (event: React.ChangeEvent<HTMLInputElement>) => void;

Other React components

interface IProps {
-  children: React.ReactNode;
-}
-
-interface IProps {
-  children: JSX.Element;
-}

React.ReactNode covers everything that React can render. This should be definitely used when the prop is a child component, otherwise JSX.element is ok.

Should I use type or interface? What is consensus?

-
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Prototypical_inheritance.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Prototypical_inheritance.html deleted file mode 100644 index a75ed45..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Prototypical_inheritance.html +++ /dev/null @@ -1,91 +0,0 @@ -Prototypical inheritance - My Zettelkasten - - - - -

Prototypical inheritance

Object oriented basis of JavaScript and nomenclature

As we know, everything in JS that isn’t a primitive (i.e. a primitive data type: string, number, boolean, null) is an object. Where an object is a data structure that consists in key:value pairs.

The key is always a string and the value can be: a primitive value, a method (function within an object), an array, another object etc.

In other object-oriented languages like C# and Java, functions are called methods however in JS the term method is reserved for function that exists as a property of an objects that contains it.

Lack of classes in JS

In contrast to more advanced object-oriented languages that are compiled (Java, C#), classes do not really exist in JavaScript. This is due to the prototype-based nature of JS (as we will see) however class-like functionality can be achieved through the use of functions.

Remember in JS that functions can be simple code blocks that execute when called (which is what we mean most of the time by ‘function’) or they can be constructor functions which create generic object types from which specific token instances can be generated as objects.

It is through these ‘generic object types’ that something akin to a class can be created in JavaScript. (These are sometimes called function-objects )

The following is a good account of the differences between prototypal and class-based languages:

JavaScript is a prototype-based language, meaning object properties and methods can be shared through generalized objects that have the ability to be cloned and extended. This is known as prototypical inheritance and differs from class inheritance. Among popular object-oriented programming languages, JavaScript is relatively unique, as other prominent languages such as PHP, Python, and Java are class-based languages, which instead define classes as blueprints for objects.

Example of a constructor function

In order to understand prototypes in a moment, it will be helpful to have an example of a constructor function that can be used to generate object instances:

/* Create constructor function: */
-function Band(mainAlbum, subgenre) {
-  // use Pascal for constructor function names
-  this.mainAlbum = mainAlbum;
-  this.subgenre = subgenre;
-}
-
-/* Then to create an object instance: */
-
-var slayer = new Band("Reign in Blood", "thrash metal");

Prototypes

Now that we know class-type functionality enters JS via constructor functions and we have an example, we can look at prototypes.

Prototypes are a special type of object that exist as a property within function-objects.

Whenever we create an instance-object from constructor function using new, the object is given a property with the key _proto_ . It’s value is the [[prototype]] property of the function that created, i.e the class of which the object is an instance:

{
-  _proto_: prototype;
-}

Note that we use the syntax [[prototype]] to indicate that whilst the value exists, it is not accessible via JavaScript code, in the manner of a normal object-literal or function-object, because it is the lower-level foundation of first-order JS code.

So how would this work for the slayer object we created above?

Slayer._proto_ === Band.prototype;

The thing is, you do not tend to see this prototype functionality and it is not possible to refer to it as a key:value directly. This is because it is something under-the-hood - it is a process that makes the object-oriented aspects of JS possible but it is not apparent on the first-order level of everyday coding.

The prototype is like a hidden hook that facilitates the generation of objects from class-like constructor functions. With our new awareness of it, we are in a position to understand how JavaScript works in foundational terms.

Every non-primitive data type in JS possesses the Object prototype

The title above indicates how and why JavaScript establishes its object-oriented data structure.

When we create an object literal (i.e an every day object not a class-like function), under-the-hood JS is making a new Object() call in much the same way as we are calling the function-object Band when we declare var slayer = new Band(...) .

All instance-objects in JavaScript (which, remember is the set of everything that is not a primitive) inherit from the Object keyword. And, to do this, prototypes are necessary. Now we see how integral prototypes are to JavaScript.

Examples

Here we create an object-literal and uncover how it has it’s basis in the overall Object constructor.

var slayerMembers = {
-  bassist: "Tom Araya",
-  guitarist: "Kerry King",
-  guitarist: "Jeff Hanneman",
-  drummer: "Dave Lombardo",
-};
-
-//  slayerMembers._proto_ === Object.prototype

Here we create an instance-object off of our Band constructor function and trace it back to Object

var deicide = new Band("Legion", "death metal");
-
-/* deicide object relies on Band prototype:
-		
-		deicide._proto_=== Band.prototype
-
-Band prototype in turn relies in turn on Object prototype: 
-
- Band.prototype._proto_=== Object.prototype
-
-*/

As the above examples show, ultimately all objects in JavaScript (whether variables, arrays, methods, or functions) eventually lead back to Object.prototype .

How the browser uses prototypes when interpreting code

When the browser interprets your code attempting to access a property or method of an object it runs through the following process:

  1. Search on the object itself. If fails →
  2. Search the object’s prototype. If fails →
  3. Search the prototype of the linked object. If fails→
  4. Keep going until Object.prototype is reached

Clearly with each step we are going to a lower level of abstraction, drawing the curtain back more and more until we got the point where JavaScript effectively stops because any lower would take you into its lower-level parent language (C/C++ depending on how the specific browser executes ECMAScript)

Note (3) is basically the prototype of the component itself. So if you started at (1) with a custom array. At (3) the browser would be querying Array.prototype i.e the basic foundational array object.

This explains why the full-name of certain methods on the global objects, includes reference to ‘prototype’, for instance:

  • toFixedNumber.prototype.toFixed()
  • .trimString.prototype.trim().

Using the function-object of Object to create an object literal

As a side-effect of uncovering the prototypical basis of Object() we can use it to create an object literal in another way.

Standardly to create a new, empty object literal we would use:

var slayerMembers = {...}

But now we could just as easily direct the code to Object() prototype and achieve the same outcome:

let slayerMembers = new Object();

Finding the [[Prototype]] of a JS object with getPrototypeOf()

We can find out the [[prototype]] of a given object in JavaScript with a special method applied to the object in question. The method we use is one of the inherent methods that belong to the Object() constructor function: getPrototypeOf() .

Here is an example:

console.log(Object.getPrototypeOf(slayer));
-
-/*
-
-Returns: 
-
-Object {constructor: , __defineGetter__: ,
- __defineSetter__: , hasOwnProperty: , __lookupGetter__: , …}
-
-*/

We could also use the following approach to get the same output however this is not recommended for production:

console.log(slayer.__prototype__);

The output we get when querying the prototype is the same in each instance.

But why bother using prototypes in your code?

It is informative to learn how prototypes are behind the object behaviour we observe at a high level in JavaScript and to know that there is a common, lower-level root but when would you actually need to use prototype methods?

The reason is mainly to do with performance and optimisation

When we create a deicide and slayer object using the constructor function Band() JS creates two copies of the constructor function, one for each generated object. This means there are two instances of mainAlbum for each object even though each do exactly the same thing. This wastes memory and performance time every time the script runs.

As a prototype object is an object, we can attach properties and methods to the prototype object. Thus, enabling all the objects created using the constructor function to share those properties and methods. However, the beauty is that the method is applied to the prototype, so it is only stored in the memory once, but every instance of the object has access to it.

/* So say I wanted to add an age property to the Band()constructor that all objects of this type have access to. I could do this without wasting memory and without the need to change the original constructor function by referring to the prototype: */
-
-Band.prototype.age = null;
-
-Slayer.age = 25;

Further steps

We are going to stop here for the time being since the primary aim of uncovering prototypes and understanding how they underly all objects and object methods in JS has been achieved.

However it is important to note that there is more that you can do with prototypes. The main additional thing is using the prototypical basis of constructor functions (i.e pseudo-classes) to add and remove key value pairs in the resulting objects. This is useful when you want to create behaviour that is much more like classes in compiled OOP languages.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Push_buttons.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Push_buttons.html deleted file mode 100644 index b52be03..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Push_buttons.html +++ /dev/null @@ -1,50 +0,0 @@ -Push buttons - My Zettelkasten - - - - -

Push buttons

Push buttons are push-to-make switches. This means that they are on when they pressed and off when they are not pressed. A classic example would be the switches on a keyboard.

Push buttons have four legs that are connected in signal-in and signal-out pairs.

To create a breakable circuit we would connect a signal-in cable to the top left at row 23 and a signal-out cable to the bottom-right at row 25.

Push button legs diagram

The correct use of a push button where the button breaks the circuit

To override the switch functionality and just have the button work as a connector we would connect the signal-in to the row 23 input and the row 23 output.

The push button being used as simple connector which does not break the circuit:

https://projects.raspberrypi.org/en/projects/button-switch-scratch-pi/1

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Python_application_structure.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Python_application_structure.html deleted file mode 100644 index 08e5d2a..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Python_application_structure.html +++ /dev/null @@ -1,82 +0,0 @@ -Python application structure - My Zettelkasten - - - - -

Python application structure

Directory layout

src/
-    cli.py OR app.py
-    constants.py
-    __init__.py
-tests/
-requirements.txt
-setup.py

requirements.txt

Dependencies used within the venv for the project, e.g:

google-auth==1.35.0
-google-auth-httplib2==0.1.0
-google-auth-oauthlib==0.4.6
-google-api-python-client==2.26.1
-gspread==3.7.0
-requests==2.25.1
-oauth2client==4.1.3

setup.py

The declaration file for the application, equivalent to package.json, e.g:

from setuptools import setup, find_packages
-
-setup(
-    name="eolas-db",
-    version="0.1",
-    packages=find_packages(where="src"),
-    package_dir={"": "src"},
-    install_requires=[
-        # List your project dependencies here
-    ],
-    entry_points={
-        "console_scripts": [
-            "eolas-db=cli:main",
-        ],
-    },
-)

The entry_points key is important. This is the first execution point of the application. Typically you would name your entry-point script as app.py or cli.py and then specify its main function.

E.g. in cli.py:

def main():
-    print('run the application')
-
-if __name__ == "__main__":
-    main()
-

__init__.py

See Python_modules_and_imports#distinguishing-_modules_-from-_packages_|Python modules]]

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Python_data_types.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Python_data_types.html deleted file mode 100644 index ed323b3..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Python_data_types.html +++ /dev/null @@ -1,76 +0,0 @@ -Python data-types - My Zettelkasten - - - - -

Python data-types

  • Python is dynamically typed rather than untyped. It updates the types on the fly as you are writing your code.
  • Type-hints in the editor like -> str mean “at the moment it is a string”. It doesn’t mean you can’t redefine the value as something else.
  • Each data type in Python inherits off of a built-in class, similar to prototypes in JS

The core data-types are as follows:

  • str
  • bool
  • float
  • double

We can identify types using the built-in type() function:

# Integer number
-my_variable = 422
-print(my_variable)
-print(type(my_variable))
-# <class 'int'>
-
-# String type
-my_variable = 'Natalia'
-print(my_variable)
-print(type(my_variable))
-# <class 'str'>
-
-# Boolean type
-my_variable = True
-print(my_variable)
-print(type(my_variable))
-# <class 'bool'>

Converting data-types

For every data-type there is a corresponding converter method, e.g:

a_string = '32'
-print(f'a_string {a_string} is {type(a_string)}')
-an_int = int(a_string)
-
-print(f'an_int {a_string} is {type(an_int)}')
-a_float = float(a_string)
-
-print(f'a_float {a_string} is {type(a_float)}')
-another_string = str(42)
-
-print(f'another_string {a_string} is {type(another_string)}')
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Python_execution.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Python_execution.html deleted file mode 100644 index 3a15d50..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Python_execution.html +++ /dev/null @@ -1,50 +0,0 @@ -Python execution - My Zettelkasten - - - - -

Python execution

For immediately executable scripts, we have to have a Python shebang at the top:

#! /usr/local/bin/python3

With programs we can just run the main file with python main.py.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Python_interpreter.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Python_interpreter.html deleted file mode 100644 index b6d6065..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Python_interpreter.html +++ /dev/null @@ -1,50 +0,0 @@ -Python interpreter - My Zettelkasten - - - - -

Python interpreter

What is an implementation of a programming language?

An implementation of Python:

means a program or environment which provides support for the execution of programs written in the Python language

As Python is interpreted, any implementation will perforce involve an interpreting language.

There are three main implementations:

  • CPython
    • The default implementation, written in C
  • Jython
    • Python implemented by Java and running on the JVM
  • PyPy
    • A subset of Python which is faster due to machine code compilation

CPython

In the standard implementation, the language which interprets Python code is C.

When Python runs in this implementation, code written in C converts it to bytecode (so-called because each instruction is 8-bits long). This is a lower-level transliteration of Python is not meant to be understood by the CPU (since it is not binary) but rather to be run in the Python virtual machine which is equipped to understand bytecode. The Python Virtual Machine is therefore also known as “bytecode interpreter” or the CPython VM. The VM then converts bytecode into machine-executable code.

The fact that Python does not compile to binary means that it can run on a greater variety of hardwares however it is slower than a language that compiles to machine code. PyPy is a solution for this because it is both interpreted and compiled to optimised machine code at run time.

Where CPython is the interpreter, Python extensions can be written in C.

PyPy

PyPy is an alternative implementation to CPython. The main difference is that it uses a JIT-compiler and doesn’t convert Python to the intermediary byte code. It is also written in Python itself, specifically RPython (‘restricted Python’). This is capable of converting Python directly to machine code without the CPython virtual machine.

Jython

Jython is an implementation of Python written in Java. Like CPython it converts Python to bytecode but this runs on the JVM. As it is written in Java, a Jython program can import and use any Java class.

Where Jython is the interpreter, Python extension can be written in Java.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Python_modules_and_imports.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Python_modules_and_imports.html deleted file mode 100644 index 2bc786c..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Python_modules_and_imports.html +++ /dev/null @@ -1,110 +0,0 @@ -Python modules - My Zettelkasten - - - - -

Python modules

Distinguishing modules from packages

Modules and packages in Python are very similar to modules in Node.js: a combination of several pieces of functionality (often written in a mix of different syntactic styles) bundled together to be used as a unit.

  • A module is basically just a script - a single Python file that you can import using the import statement
  • A package is a collection of modules

A package is a whole directory which has an __init__.py at its root which designates it as a package (this can be empty, but it is necessary to have this file for the interpreter to understand that the directory is a package).

Creating modules

Naming modules

The name of a module is the name of its file, e.g. utils.py defines the module utils. When we import a module we do not need to specify the extension.

Example module

Here is an example of a module.

"""utils module"""
-
-print('Hello I am the utils module')
-
-
-def printer(some_object):
-    print('printer')
-    print(some_object)
-    print('done')
-
-
-class Shape:
-
-    def __init__(self, id):
-        self.id = id
-
-    def __str__(self):
-        return 'Shape - ' + self.id
-
-
-default_shape = Shape('square')
-
-
-def _special_function():
-    print('Special function')
-

Importing modules

Whether we are importing our own local module, a third-party module or a built-in module native to Python, the syntax is the same.

  • If the module is in the same directory as the file you wish to import it into, you can just directly import with:
    import utils
    -utils.specialFunction
    -shape = utils.Shape('circle')
  • If the module you want to import is in a subdirectory, you will need to make that subdirectory a package in order to be able to import from it. This means adding an __init__.py. Then you can use the following import syntax:
    from subdir import utils
    -...

Different import syntax

  • If you don’t want to have to prepend the imported module’s name when using it (e.g. utils.specialFunction). You can import like so:

    from utils import *
    -specialFunction()
  • By default an import makes everything in the module available, however you can choose to import only a subset. E.g.:

    from utils import Shape
    -#  or with an alias:
    -from utils import Shape as lorem

__main__

The __main__ attribute is important in Python.

Usage in scripts/modules

When you run a script (module) Python assigns the string __main__ to the __name__ attribute to the script that is being executed.

If you run the script as an import into another script, the __name__ attribute of the imported module is set to the module name, not __main__. This is why, when we import we say import [module_name] and not import __main__.

When used with a module, __main__ indicates code that should be run straight away when the given script file is run. You won’t always want to execute everything in the module file on execution so you can put this stuff outside of __main__

Typically you will only want immediate execution to happen when the module is the entrypoint to the program.

We indicate this with __main__ as follows:

if __name__ == "__main__":
-    print("This runs only if the module is the main module")

Usage in packages

The only real difference with packages is that you can also define a __main__.py file in the root of the package directory.

This functions in the same manner as __main__ in an individual module however this time it is not the entry point for a single script but the entrypoint of the package as a whole.

When the package is run directly as a script, the code in __main__.py is executed, just like it would be if it were a standalone script. This allows a package to be run as a script, as well as letting it contain modules that can be imported separately.

You can of course still have individual entrypoints for the modules that comprise the package.

Running the package as a package

If you want to run the whole package at once, rather than individually importing the modules that belong to it. You can run the following from the command-line:

python -m package_name

With this, Python will try to locate the __main__.py file and execute it as though it were a standalone script.

Using a main() function

To ensure that certain code runs on initialisation we can define a special main function or class method that runs when the module or package is loaded.We would put the main set-up logic in main and coordinate the execution of the module or package through it.

def main():
-    printer(default_shape)
-    shape = Shape("circle")
-    printer(shape)
-
-if __name__ == "__main__":
-    main()

Example

'''palindrome module'''
-
-def is_palindrome(inp):
-    inp_list = list(inp)
-    inp_list_len = len(inp_list)
-    for i in range(inp_list_len):
-        if inp_list[i] != inp_list[inp_list_len - 1 - i]:
-            return False
-    return True
-
-
-def main():
-    palindrome_one = "soros"
-    palindrome_two = "torot"
-    not_palindrome = "chair"
-
-    print(is_palindrome(palindrome_one))
-    print(is_palindrome(palindrome_two))
-    print(is_palindrome(not_palindrome))
-
-
-if __name__ == '__main__':
-    main()
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Python_package_management.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Python_package_management.html deleted file mode 100644 index 988bb88..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Python_package_management.html +++ /dev/null @@ -1,54 +0,0 @@ -Package management - My Zettelkasten - - - - -

Package management

  • You can use conda (the package manager that comes with anaconda). This makes it easier to work with conflicting package libraries (a bit like a package lock).

  • The alternative is the native pip but you have to create virtual environments (venv) to manage packages at different versions.

To make use of virtual environments in pip you have to create the virtual environment before installing anything:

python3 -m venv venv

This will create a venv directory in your project that will manage the handling of modules.

This is especially important in ArchLinux since without a virtual environment it will ask you to install packages with pacman which is annoying for local packages.

You then activate the environment with:

source venv3/bin/activate

Now you can install packages:

pip [library_name]

requirements.txt

The requirements.txt file is similar to the package.json in Node projects.

Each line of the `requirements.txt`` file specifies a package that your project depends on and, optionally, the desired version of that package. When you share your project with others or move it between different environments (e.g., from development to production), this file makes it easy to set up your environment with the right dependencies.

Example

Flask==1.1.2
-requests>=2.24.0
-numpy~=1.19.2
-pandas

Generate requirements file

pip freeze > requirements.txt
-

Pypy

  • pypi.org is package registry like NPM
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Querying_a_Mongo_collection.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Querying_a_Mongo_collection.html deleted file mode 100644 index 3156f1b..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Querying_a_Mongo_collection.html +++ /dev/null @@ -1,117 +0,0 @@ -Query a Mongo collection with Mongoose - My Zettelkasten - - - - -

Query a Mongo collection with Mongoose

We now have the following entries in our courses collection:

{
-  name: 'Python Course',
-  author: 'Terry Ogleton',
-  tags: [ 'python', 'backend' ],
-  isPublished: true,
-  _id: new ObjectId("62f4e2527ac4aa2c30d41d23"),
-  date: 2022-08-11T11:04:50.750Z,
-  __v: 0
-}
-
-{
-  name: 'Javascript Course',
-  author: 'Tosh Gnomay',
-  tags: [ 'js', 'frontend' ],
-  isPublished: true,
-  _id: new ObjectId("62f4e2527ac4aa2c30d41d24"),
-  date: 2022-08-11T11:04:50.750Z,
-  __v: 0
-}
-

Now we will query the collection. This capability is provided via the Mongoose schema class we used to create the Course model. We have the following methods available to use from the schema:

  • find
  • findById
  • findByIdAndRemove
  • findByIdAndUpdate
  • findOne
  • findOneAndUpdate
  • findOneAndRemove

The various find methods return a value that is promisified.

Return values with find

async function getCourses() {
-  const courses = await Course.find();
-  console.log(courses);
-}

Filter values returned

This will return all the published courses where Tosh Gnomay is the author:

async function getCourses() {
-  const courses = await Course.find({
-    author: "Tosh Gnomay",
-    isPublished: true,
-  });
-  console.log(courses);
-}

This time we will filter by the same author but we will add additional parameters to distinguish:

  • only the first ten entries (using .limit(10))
  • sort ascending by name (using .sort({name: 1})) , to descend we would use -1)
  • only return the properties name and tags for the item in the collection (using .select({name: 1, tags: 1}))
async function getCourses() {
-  const courses = await Course.find({
-    author: "Tosh Gnomay",
-    isPublished: true,
-  })
-    .limit(10)
-    .sort({ name: 1 })
-    .select({ name: 1, tags: 1 });
-  console.log(courses);
-}

This returns:

[
-  {
-    _id: new ObjectId("62f4f07a875cff48827b8731"),
-    name: "Java Course",
-    tags: ["java", "backend"],
-  },
-  {
-    _id: new ObjectId("62f4e2527ac4aa2c30d41d24"),
-    name: "Javascript Course",
-    tags: ["js", "frontend"],
-  },
-];

Note that the UUID is always returned, whether we specify it or not.

Querying with operators

So far when filtering we have been doing so with reference to properties that exist on the document’s model (author, isPublished etc) and we have applied tranformations on the data returned (sorting, limiting the number or matches etc.). However we can also apply operators within our queries. Operators allow us to perform computations on the data, for example: for a given numerical property on an object, return the objects for which this value is within a certain range.

When we apply operators we use the $ symbol before the operator and pass the operator function as an object.

The schema:

Model.find( { property: { $operator: conditions } } )

Comparison operators

The following comparison operators are available in MongoDB:

OperatorFunction
eqEqual to
neNot equal to
gtGreater than
gteGreater than or less than
ltLess than
lteLess than or equal to
inIn
ninNot in

We can employ these comparators within a .find filter. For example let’s imagine that our courses instances have a property of price.

To filter course prices that are greater than or equal to 10 and less than or equal to 29:

Course.find({ price: { $gte: 10, $lte: 20 } });

To filter course prices that are either 10, 15 or 20:

Course.find({ price: { $in: [10, 15, 20] } });

Logical operators

When we apply logical operators, we do not apply the query within the main find method. We use a dedicated method that corresponds to the logical predicate.

For example to query by logical OR:

async function getCourses() {
-  const courses = await Course.find().or([
-    { author: "Tosh Gnomay" },
-    { isPublished: true },
-  ]);
-  console.log(courses);
-}

We write each disjunct as an object representing the conditions we are filtering for within an array that is passed to the .or() method.

The same syntax applies for conjunction.

Regular expressions

When filtering by strings we can use Regex for greater power.

Previously we filtered by the author name:

.find({author: "Tosh Gnomay"})

To demonstrate regex we could filter by names beginning with T:

.find({author: /^T*/})
async function getCourses() {
-  const courses = await Course.find()
-    .or([{ author: "Tosh Gnomay" }, { isPublished: true }])
-    .count();
-  console.log(courses);
-}

This will return a number.

Pagination

We previously used the limit() method to control how many matches we return from a query. We can extend this functionality by creating pagination. This allows us to meter the return values into set chunks. This is used frequently when interacting with a database through a mediating RESTful API. For example to return values from endpoints such as:

/api/courses?pageNumber=2&pageSize=10

To do this you pass two values as query parameters

const pageNumber = 2;
-const pageSize = 10;
-
-async function getCourses() {
-  const courses = await Course.find()
-    .skip(pageNumber - 1 * pageSize)
-    .limit(pageSize);
-  console.log(courses);
-}
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Queue.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Queue.html deleted file mode 100644 index d7dd9f4..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Queue.html +++ /dev/null @@ -1,60 +0,0 @@ -Queues - My Zettelkasten - - - - -

Queues

Visualization of the queue data structure

queue.svg

A queue is a sequential data structure and most similar to a stack

A queue is basically a stack inverted and can be visualised as a line of people waiting to be served. The person that is first into the queue is served first. The people who join the queue behind this person will be served after them.

As a result it can be summarised as ‘first in, first out’ or FIFO.

Just like a stack it is a sequential data structure without random access. You cannot access all the elements at one instant, you can only access the oldest element. If you wish to access the newest element, you have to move through all the others that are ahead of it first, at which point it becomes the oldest.

It differs from a stack in that a stack only has one point of transaction: the front or ‘top’ of the stack. With a stack you add and remove from the top or front. With a queue, you have two points of transaction: the front of the queue for removing elements and the back of the queue for adding elements.

We can however add a ‘peek’ method to see which is the next element in line to come out.

As we are removing the first element added, we use an array shift method to remove items from the front of the array.

Removing an element from the queue is called dequeuing. Adding an element to the queue is called enqueuing. In terms of the tail/head nomenclature, the end of the queue where elements are enqueued is the tail and front of the queue, where elements are removed is the head.

class Queue {
-  items = []; // array to store the elements comprising the queue
-  enqueue = (element) => this.items.push(element); // add element to back
-  dequeue = () => this.items.shift(); // remove element from the front
-
-  // Optional helper methods:
-  isEmpty = () => this.items.length === 0; // return true if the queue is empty
-  clear = () => (this.items.length = 0); // empty the queue
-  size = () => this.items.length; // count elements in queue
-  peek = () => (!this.isEmpty() ? this.items[0] : undefined); // check which element is next in line
-}

Use cases

  • A queue sequences data in the order that it was first received. Thus it is most beneficial in scenarios where receipt time is a factor. For example, imagine a service whereby tickets go on sale at a certain time for a limited period. You may want to prioritise those who sent their payment earliest over those who arrived later.
  • Serving requests on a single shared resource like a printer or CPU task scheduling.
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Quote_marks_in_Bash.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Quote_marks_in_Bash.html deleted file mode 100644 index 3534e45..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Quote_marks_in_Bash.html +++ /dev/null @@ -1,55 +0,0 @@ -Quote marks in Bash - My Zettelkasten - - - - -

Quote marks in Bash

Single-quotes (aka strong quotes)

Bash will interpret everything in the string as a literal:

echo 'The directory is $(pwd)'
-# The directory is $(pwd)

Double-quotes

Bash will interpret strings as strings but will interpret expansions and substitutions as executable processes:

$pointlessVar='directory'
-
-echo "The ${pointlessVar}"
-
-# The directory is /home/thomas

It is therefore generally best to use double quotes whenever we wish to return mixed values.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/RESTful_APIs.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/RESTful_APIs.html deleted file mode 100644 index d60f21d..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/RESTful_APIs.html +++ /dev/null @@ -1,50 +0,0 @@ -RESTful APIs - My Zettelkasten - - - - -

RESTful APIs

Definition of an API

An application programming interface (API) is a set of definitions and protocols for building and integrating application software. It can be thought of as a contract between an information provider and an informational consumer. The API is a mediator between the clients and the resources they wish to acquire from a server or database.

REST

REST stands for Representational State Transfer. It is a set of architectural constraints on the structure of an API rather than a fixed protocol. It is a particular way of implementing client-server interaction over HTTP.

When a request is made from a client to resources via RESTful API, the API transfers a representation of of the state of the resource to the requester or endpoint. The information is delivered via HTTP. The format can be of several types (HTML, XML, plaintext, Python, PHP etc) but is generally JSON because of its broad compatibility with multiple programming languages.

Key constraints

In order to qualify as RESTful, an API must meet the following constraints:

  1. Uniform interface: Possess a client-server architecture with request manage through HTTP
  2. Client-server decoupling : The client and server applications must be completely independent of one another. The only information the client should know about the server is the URI it uses to request the resource, it can’t interact with the server in any other way. Likewise, the server shouldn’t modify the client application in any way (contrast for example SSR) other than passing the requested data via HTTP.
  3. Statelessness Server applications should not be able to store any data related to a client request. The request alone should contain all the information necessary for processing it, without recourse to any specifics of the client application. For example, a specification of POST with a certain JSON body and header authentication will be all that is provided to the server.
  4. Cacheability Where possible, resources should be cacheable on the client or server side. Server responses must contain information about whether caching is allowed for the delivered resource (you see this in the headers in the DevTools console). The goal here is to improve performance on the client side whilst increasing scaleability on the server side.
  5. Layered system architecture It may be the case that the data flow between the client and the server is not direct. For instance the request may be funneled through middleware or another program before it is received by the server. Similarly there may be several steps before the client receives the requested data. Whilst one should not assume a direct correspondence, REST APIs need to be designed so that neither the client nor the server can tell whether it communicates with the end application or an intermediary.

Example

A basic example of a REST API would be a series of methods corresponding to the main HTTP request types.

HTTP request typeURIActionBody ?
GET/api/customersRetrieve customers as arrayNo
GET/api/customers/guidGet a specific customerNo, data comes from GUID
PUT/api/customers/guidUpdate an existing customerYes
DELETE/api/customers/1Delete a customerNo, data comes from GUID
POST/api/customersCreate a new customerYes

// Add: PATCH and explain differenct from PUT

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/ROM_versus_disk_loading.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/ROM_versus_disk_loading.html deleted file mode 100644 index c3b5092..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/ROM_versus_disk_loading.html +++ /dev/null @@ -1,50 +0,0 @@ -ROM versus disk loading - My Zettelkasten - - - - -

ROM versus disk loading

I will explore the concept via the practical examples of cartridge-based and disk-based video games console.

When you insert a disk into an Xbox, the game data is typically read from the disk and transferred into the console’s memory by the OS. If the game is installed to the hard drive, this initially involves transferring substantial amounts of data to speed up future access. When you insert a cartridge into a console like the SNES, the data is not transferred in the same way. Instead, the cartridge contains a ROM chip that, when inserted, integrates directly with the motherboard. From the operating system’s point of view, this ROM chip behaves as an extension of the system’s memory architecture.

The primary advantage of a ROM-based game is significantly reduced latency. The game data can be accessed as rapidly as any other data moving along the buses of the motherboard. With a disk, the data must first be read into a buffer and then transferred to a memory address where it can be accessed by the CPU.

With a ROM, while the console CPU still uses its own RAM to run the game (similar to disk-based systems), the game data on the ROM can be loaded into this RAM more quickly because it is directly attached to the motherboard. This makes the ROM cartridge effectively a fast, directly connected storage device.

However, despite its speed, the limitation of a ROM cartridge is its storage capacity—it can hold only as much data as the chip can accommodate. In contrast, a disk can store much more data. This larger storage capacity allows not just for bigger and more complex games but also for the possibility of expanding the game through additional data downloaded to the console’s hard drive. Such expansions or patches represent additional data from the console’s storage that, combined with the original disk data, are synthesized in memory at runtime for enhanced or updated gameplay experiences.

(Note however that modern cartridge-based consoles like the Nintendo Switch can also combine ROM-data with expanded data from the console HDD, sourced from the internet.)

Both disks and ROMs are forms of static storage in the context of a game console. While disks can technically be overwritten with new data, in practice, manufacturers implement various locks and protections to prevent this. Any changes or additions to the game, such as patches or expansions, are not written back to the original disk. Instead, these updates are stored on the console’s hard drive.

Therefore, if you download an expansion for a game on your Xbox, the original disk remains unchanged as when you first purchased it. Consequently, if you were to take that disk and load it on another Xbox, it would not include any of the expansions or updates. The game would function in its original form, as the additional content and updates reside solely on the hard drive of the first console where they were downloaded.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/React_Components.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/React_Components.html deleted file mode 100644 index 3f31646..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/React_Components.html +++ /dev/null @@ -1,55 +0,0 @@ -Components - My Zettelkasten - - - - -

Components

We write functional components in the manner of a normal function that take a props argument and return a JSX element.

interface IProps = {
-  message: string;
-};
-const App = ({message}: IProps): JSX.Element => <div>{message}</div>;

React.FunctionComponent / React.FC

It used to be the case that you would type a function component like so:

const App: React.FunctionComponent<{ message: string }> = ({ message }) => (
-  <div>{message}</div>
-);

This is now discouraged as it means the component can always accept children, even when you do not want this to be the case. There are several other minor drawerbacks but it’s generally best to leave out the declaration.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/React_errors.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/React_errors.html deleted file mode 100644 index f2a49b8..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/React_errors.html +++ /dev/null @@ -1,50 +0,0 @@ -Errors - My Zettelkasten - - - - -

Errors

State update on unmounted component

Can’t perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.

This typically happens when you have an API request running in the background. Once the data is returned, React tries to update the state but the component is unmounted.

As the warning suggests, this can be resolved using the cleanup parameter within React_useEffect.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/React_useContext.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/React_useContext.html deleted file mode 100644 index 46c2fa1..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/React_useContext.html +++ /dev/null @@ -1,72 +0,0 @@ -useContext - My Zettelkasten - - - - -

useContext

We use React’s Context API to enable us to easily share stateful data between all levels of an application without having to use repetitious ‘prop-drilling’ at a component level.

This works best with data that is global by definition, such as theme parameters or access authorisation. Context should not be used when standard and proximate compositional methods and prop-passing are sufficient.

Providers and consumers

The Context API preceded the introduction of hooks in React 16.8 and it still underpins context management in hooks, although the syntax is simplified.

The process is as follows:

  • Initiate a context
  • Create a parent Provider component that owns the data that will be passed down
  • Create child Consumer components that receive the data of the parent.

We will demonstrate using a set of styles as the context that we want to pass around our app.

const style = {
-  border: "2px solid dodgerblue",
-  background: "lightblue",
-  color: "dodgerblue",
-};

Le’s initiate a context:

const StyleContext = React.createContext();

Now that we have our data and have initialized a context, we can apply it to our app components:

<StyleContext.Provider value={style}>...</StyleContext.Provider>

This is the parent element of the context environment. This stores the contextual data as a prop. Next we need to make a component that acts as the consumer of this data. Let’s create this component and call it Child for simplicity:

const Child = () => {
-  return (
-    <StyleContext.Consumer>
-      {(value) => (
-        <div style={value}>
-          <p>
-            I'm a <b>child</b>. I <b>consume</b> of the data my parent provides.
-          </p>
-        </div>
-      )}
-    </StyleContext.Consumer>
-  );
-};

The contents of this component are wrapped in tags that reference the specific context (StyleContext) and the role that the component plays: Consumer.

We are taking the value prop owned by StyleContext.Provider and passing it to the wrapping component of Child as a style tag. This means that Child will display these styles.

The final step is just to insert our <Child /> components beneath the parent component, e.g.:

<StyleContext.Provider value={style}>
-  <Child />
-  <Child />
-</StyleContext.Provider>

useContext hook

The hook removes the need to explicitly declare Provider and Consumer components; their role becomes more implicit.

To demonstrate let’s use a different example. We are going to have a single integer as the data context, 42.

First invoke and intialize the Context API, just as before:

const NumberContext = React.createContext(42);

Next, we just need to create our provider component. We don’t have to worry about a consumer since this is handled implicitly by the invocation of the hook

const Context = () => {
-  const data = useContext(NumberContext);
-  return <Typography>{data}</Typography>;
-};

Then, in our code we just insert the Context component:

<Context>...</Context>

Updating context state

In the examples above we have only been consuming state that is owned by the provider however in most scenarios you will also want to update the state from a consumer. This is best achieved by combining useContext with a reducer and is detailed in Application state management.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/React_useEffect.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/React_useEffect.html deleted file mode 100644 index 3175d17..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/React_useEffect.html +++ /dev/null @@ -1,85 +0,0 @@ -useEffect - My Zettelkasten - - - - -

useEffect

useEffect should be used for any background process that does not arise as a result of a user interaction or standard state change. The canonical example would be dispatching a request to an API to retrieve data to display in a component’s initial render.

useEffect enshrines but also simplifies the lifecyle methods that are used with class-based React components.

Demonstration

const [workflowTitle, setWorkflowTitle] = useState("");
-const [loading, setLoading] = useState(false);
-
-useEffect(() => {
-  const fetchWorkflowTitle = () => {
-    axios
-      .post(`${process.env.REACT_APP_ENDPOINT}/load-workflows`, {
-        workflow_id: project_id,
-        user_id: isAuth?.userId,
-      })
-      .then((res) => {
-        setWorkflowTitle(res?.data?.meta.name);
-      })
-      .finally(() => setLoading(false))
-      .catch((err) => {
-        console.error(err);
-      });
-  };
-  setLoading(true);
-  fetchWorkflowTitle();
-}, [project_id, isAuth]);

In this example we fetch some data from a REST API and store the response value as state, which can then be accessed within our JSX template.

Function placement

In the example, the function is declared inside of the useEffect hook and then called. We do this to avoid adding the function to the dependency array, which we couldn’t do if we defined it outside of the hook, somewhere in the component. If we did this, the function would run on every render by default and would be recalled again because of its placement in the dependency array, which leads to the ‘too many rerenders’ error.

An alternative would be to define it outside of the component itself but this is difficult since it requires state from the component to run.

Dependency array

Note the array that is the second argument to useEffect. This is the dependency array and is how we manage the lifecycle of the side-effect.

  • After the initial call on render, the function within the useEffect block will run any time one of the dependencies update. The dependency array typically refers to variables that are defined within the hook but can also contain references to variables outside of it.

  • If you do not include the array, the effect runs on every render

  • If you pass an empty array, the effect will only run once on the initial render

Cleanup functions

The syntax of the useEffect hook also allows you to handle cleanup: something you want to do when the component unmounts (another example of how this hook recasts the traditional lifecycle methods) . In addition to running on unmount, the cleanup function will run before the effect runs again (i.e. when it runs in response to a change in one of the elements of the dependency araray). This is chiefly used to prevent memory leaks and the ‘update on unmounted component error’.

You do this by having a return clause after the main effect. Schematically:

useEffect(() => {
-  //  Run your effect;
-  return () => {
-    //   Put your cleanup function here
-  };
-}, [input]);

Here is an example of using a cleanup to cancel a subscription

useEffect(() => {
-  let isApiSubscribed = true;
-  axios.get(API).then((response) => {
-    if (isApiSubscribed) {
-      // handle success
-    }
-  });
-  return () => {
-    isApiSubscribed = false;
-  };
-}, []);

Resources

Understanding the React useEffect cleanup function

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/React_useReducer.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/React_useReducer.html deleted file mode 100644 index 23fba9d..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/React_useReducer.html +++ /dev/null @@ -1,88 +0,0 @@ -useReducer - My Zettelkasten - - - - -

useReducer

The useReducer hook is best used in scenarios where you are manipulating state in a way that is too complex for the trivial React_useState use case. useState is best employed when you are updating a single value or toggling a boolean. If you are updating the state of an object or more complex data structure, it is often more efficient to employ useReducer.

This makes the code more manageable and also helps with separating state management from rendering.

Syntax

const [state, dispatch] = useReducer(reducer, initialState);
  • initialState
    • The starting state, typically an object
  • reducer
    • A pure function that accepts two parameters:
      • The current state
      • An action object
    • The reducer function must update the current state (immutably) and return the new state
    • We can think of the reducer as working in the same manner as state/setState in the useState hook. The functional role is the same, it is just that the reducer offers more than one type of update.

Example reducer

function reducer(state, action) {
-  let newState;
-  switch (action.type) {
-    case "increase":
-      newState = { counter: state.counter + 1 };
-      break;
-    case "descrease":
-      newState = { counter: state.counter - 1 };
-      break;
-    default:
-      throw new Error();
-  }
-  return newState;
-}

In this example we are updating an object with the following shape:

{
-    counter: 0,
-}

This would be the initialState that we pass to the useReducer hook along with a reference to reducer above.

To update the state we would invoke the dispatch function which applies one of the actions defined in the reducer. For example the following dispatch increments the counter by one:

dispatch({ type: "increase" });

To view the updated value:

console.log(state.counter);

Refining the syntax

Because React doesn’t mutate state, the reducer doesn’t directly modify the current state in the state variable, it creates a new instance of the state object on each update.

In the reducer example above this is achieved by declaring a variable newState that is updated by each action type and then returned. There is a more elegant way of doing this using spread syntax:

function reducer(state, action) {
-  switch (action.type) {
-    case "increase":
-      return { ...state, counter: state.counter + 1 };
-      break;
-    case "decrease":
-      return { ...state, counter: state.counter - 1 };
-      break;
-    default:
-      throw new Error();
-  }
-}

Including payloads

In the examples so far, we have updated the the state directly via the action type however it is also possible to pass data along with the action.type as action.payload.

For example:

dispatch(
-  {
-    type: 'increase_by_payload'
-    payload: 3,
-  });

Then we would update our reducer to handle this case:

function reducer(state, action) {
-  switch (action.type) {
-    ...
-    case 'increase_by_payload':
-    return {...state, counter: state.counter + action.payload}
-    default:
-      throw new Error();
-  }
-}
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/React_useState.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/React_useState.html deleted file mode 100644 index d731400..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/React_useState.html +++ /dev/null @@ -1,61 +0,0 @@ -useState - My Zettelkasten - - - - -

useState

useState is the primary way in which React updates the application state based on user interaction.

  • useState receives: the initial state as an argument
  • useState returns: the current state and a function that updates it

The two items that are returned are returned as an array. We could refer to them with array syntax (i.e with [0] and [1] ) but it is more concise to use the destructuring syntax. But all that’s happening is that a method belonging to the React library (i.e. useState ) is taking an argument (the initial state) and returning two values as an array of two elements. The first of these values is a variable, the second is a function.

(1) const [count, setCount] = useState(0);
-(2) const handleClick = () => { setCount(count + 1) };
-
-(3) <span>{count}</span>
-(4) <button onClick={handleClick)>Add one</button>
  • At line 1 we initialise the useState hook.
    • We use destructuring syntax to declare two variables
    • The first variable stores our initial state. The value of the initial state is an argument passed to useState , i.e. 0. Do not confuse the variable with the value it refers to.
    • The second variable is a method that mutates the state referred to by the first variable into some new value, i.e. from 0 to a different integer
  • At line 3, which in reality, will be within your JSX and part of the render() block of the function, we render the initial state in the React DOM. This will change and be re-rendered in accordance with the state logic
  • At line 4 we have a user interface that executes the function on line 2. This function applies the state change represented by the second variable in the destructuring assignment at line 1 (setCount ): it mutates the initial state (0) by the value of `1’.

You can utilise as many useState declarations as your component requires.

Passing variables as initial state

We don’t always have to declare the data types within the destructuring assignment. We can store them in variables and pass the variables to the destructuring assignment on useState . Below we do this for a function that mutates a string value:

const hi = "hello";
-const bye = "goodbye";
-
-const [initText, changeText] = useState(hi);
-
-<p>{initText}</p>
-<button onClick={()=>changeText(bye)}>ChangeText</button>

Lazily setting initial state

Although you will typically use a literal value or variable as your initial state, React provides a way for you to set this value through a function. This will only run once at the first render so as not to interfere with the second update parameter of useState. This is called lazy initialisation

const getInitialState = () => Number(window.localStorage.getItem("count"));
-const [count, setCount] = React.useState(getInitialState);

Accessing previous state

It is also possible to access the previous state via the useState hook. We can access this as a callback on the updater function.

Let’s say we have a simple counter set up like so:

const [count, setCount] = useState(0);

We can access the prior value of count with:

const getPrevValue = () => setCount((prev) => console.log(prev));

Naming best practise

When destructuring the two variables from useState, React follows uses the following semantics: [something, setSomething] . This isn’t required but it helps to keep everything clear, particularly the fact that the first thing destructured is a variable and the second is a function.

https://stackoverflow.com/questions/54807454/what-is-prevstate-in-reactjs

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Read_command__in_Bash.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Read_command__in_Bash.html deleted file mode 100644 index 6e8cd14..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Read_command__in_Bash.html +++ /dev/null @@ -1,66 +0,0 @@ -read - My Zettelkasten - - - - -

read

The primary use of read is to capture user input from stdin. It can also be used to parse strings or files that are redirected to it (with < and <<) or piped to it. In each case, what is read is stored as a variable.

read will parse line by line using a space (\n) as the default delimiter. You can use IFS to parse by other characters and/or split the contents into an array.

Example of capturing user input

When we use read to gather user input, the script will pause until the input is provided.

echo "What is your name?"
-read name
-
-echo "What is your password?"
-read -s pass
-
-read
-

If you don’t specify variables, read will automatically parse using whitespace

Example of piping to read

Here we use find to collate the files in the current directory and then pipe them to read.

find -type -f  -not -path "./.git/" | read $fname

Example of parsing a file

We will typically read from a source and then do something with each variable that read returns, e.g:

while read line; do
-  if [ var == 'something' ]; then
-    # do something
-done < './input-file.txt

$REPLY

If you do not assign a variable name to store the value that read reads a default ($REPLY) is applied. You can reference this value in your code.

For example the following loop does something if $REPLY is equal to an empty string:

while read;
-do
-    ((count++))
-    if [[ -z "$REPLY" ]]; then
-        echo "$count"
-    fi
-done < "$input
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Reciprocals.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Reciprocals.html deleted file mode 100644 index 03ec62a..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Reciprocals.html +++ /dev/null @@ -1,55 +0,0 @@ -Recipricols - My Zettelkasten - - - - -

Recipricols

The Property of Multiplicative Identity applies to fractions as well as to whole numbers:

$$ -\frac{a}{b} \cdot 1 = \frac{a}{b} -$$

With fractions there is a related property: the Multiplicative Inverse.

If \(\frac{a}{b}\) is any fraction, the fraction \(\frac{b}{a}\) is called the multiplicative inverse or reciprocol of \(\frac{a}{b}\). The product of a fraction multiplied by its reciprocol will always be 1. $$ \frac{a}{b} \cdot -\frac{b}{a} = 1$$

For example:

$$ -\frac{3}{4} \cdot \frac{4}{3} = \frac{12}{12} = 1 -$$

In this case \(\frac{4}{3}\) is the reciprocol or multiplicative inverse of \(\frac{3}{4}\).

This accords with what we know a fraction to be: a representation of an amount that is less than one whole. When we multiply a fraction by its reciprocol, we demonstrate that it makes up one whole.

This also means that whenever we have a whole number \(n\), we can represent it fractionally by expressing it as \(\frac{n}{1}\)

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Recursion.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Recursion.html deleted file mode 100644 index fa798a6..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Recursion.html +++ /dev/null @@ -1,94 +0,0 @@ -Recursion - My Zettelkasten - - - - -

Recursion

A recursive function is a function that calls itself in its definition.

More generally recursion means when a thing is defined in terms of itself. There are visual analogues that help to represent the idea such as the Droste effect where an image contains a version of itself within itself. The ouroboros is another example. Also fractals display recursive properties.

Schema

The general structure of a recursive function is as follows: javascript-recursion.png

Why use recursive functions?

Recursion is made for solving problems that can be broken down into smaller, repetitive problems. It is especially good for working on things that have many possible branches but are too complex for an iterative approach or too costly in terms of memory and time complexity.

Recursive programming differs from iterative programming but both have similar use cases. Looping is a canonical example of working iteratively.

Base condition

Once a condition is met, the function stops calling itself. This is called a base condition.

Because recursion has the potential for infinity, to use it, we must specify a point at which it ends. However as we are not using an iterative approach we cannot rely on while or foreach to specify the boundaries of its operation. We call this the base condition and this will typically be specified using conditional logic.

The schema for a recursive function with a base condition is:

function recurse() {
-  if (condition) {
-    recurse();
-  } else {
-    // stop calling recurse()
-  }
-}
-
-recurse();

Demonstrations

Countdown

// program to count down numbers to 1
-function countDown(number) {
-  // display the number
-  console.log(number);
-
-  // decrease the number value
-  let newNumber = number - 1;
-
-  // base case
-  if (newNumber > 0) {
-    countDown(newNumber);
-  }
-}
-
-countDown(4);
  • This code takes 4 as it’s input and then outputs a countdown returning: 4, 3, 2, 1
  • In each iteration, the number value is decreased by 1
  • The base condition is newNumber > 0 . This breaks the recursive loop once the output reaches 1 and stops it continuing into negative integers.

Each stage in the process is noted below:

countDown(4) prints 4 and calls countDown(3)
-countDown(3) prints 3 and calls countDown(2)
-countDown(2) prints 2 and calls countDown(1)
-countDown(1) prints 1 and calls countDown(0)

Finding factorials

The factorial of a positive integer n is the product of all the positive integers less than or equal to n.

To arrive at the factorial of n you subtract 1 from n and multiply the result of the subtraction by n. You repeat until the subtractive process runs out of positive integers. For example, if 4 is n, the factorial of n is 24:

$$ 4 _ 3 _ 2 \*1 $$

4 multiplied by 3 gives you 12, 12 multiplied by 2 gives you 24. 24 multiplied by 1 is 24.

This is clearly a process that could be implemented with a recursive function:

// program to find the factorial of a number
-function factorial(x) {
-  // if number is 0
-  if (x === 0) {
-    return 1;
-  }
-
-  // if number is positive
-  else {
-    return x * factorial(x - 1);
-  }
-}
-
-let num = 3;
-
-// calling factorial() if num is non-negative
-if (num > 0) {
-  let result = factorial(num);
-  console.log(`The factorial of ${num} is ${result}`);
-}

javascript-factorial 1.png

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Redirect_to_dev_null.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Redirect_to_dev_null.html deleted file mode 100644 index 3b060df..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Redirect_to_dev_null.html +++ /dev/null @@ -1,50 +0,0 @@ -Redirecting to /dev/null - My Zettelkasten - - - - -

Redirecting to /dev/null

You’ll see the following a lot when reading shell scripts:

[some_command] > /dev/null 2>&1

This is a redirection statement. It is redirecting data to the null device on Unix systems. Basically to a black hole or shredder where you can’t access it because you don’t want it to be output to stdout.

The 2>&1 argument is the content: any errors that the program may generate and try to show in stout. Notice we are using the File_descriptors_and_redirection 1 and 2.

If you just want the errors regardless of whether they appear in stdout you do:

[some_command] > /dev/null 2>

Example

I have used this in my Mongo start-up script:

mongodb-compass > /dev/null 2>&1

Here, I just want the MongoDB Compass application to start, I don’t care if it wants to output complaints to the stout.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Redirection_in_Bash.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Redirection_in_Bash.html deleted file mode 100644 index 2b7380f..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Redirection_in_Bash.html +++ /dev/null @@ -1,50 +0,0 @@ -Redirection - My Zettelkasten - - - - -

Redirection

Redirecting outputs

The symbol > is called the redirection operator because it redirects stdout to another program or file. You most frequently use this when you want to save contents to a file rather than standard output.

ls | grep d* > result.txt

Combining redirection with file escriptors

It is common practice to combine redirection with the file descriptors to redirect the output of stdout and stderr. A common case is to redirect error output to /dev/null.

Redirection defaults to interpreting > as the redirection of stdout (1);

Redirecting inputs

We can also switch the direction of the redirection symbol and pass in a file to a command rather than command ouput to a file:

sql-processing-program < data.sql

We can redirect a string with three carets:

program <<< "this is a string input"

Appending

We use >> to append contents on the next available line of a pre-existing file. Continuing on from the example above:

echo 'These are the files I just grepped' >> result.txt
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Reducing_fractions.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Reducing_fractions.html deleted file mode 100644 index 52f9631..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Reducing_fractions.html +++ /dev/null @@ -1,81 +0,0 @@ -Reducing fractions to their lowest terms - My Zettelkasten - - - - -

Reducing fractions to their lowest terms

A fraction is said to be reduced to its lowest terms if the greatest common divisor of the numerator and the denominator is $1$.

Whenever we reduce a fraction, the resultant fraction will always be equivalent to the fraction we started with.

Thus the fraction \(\frac{2}{3}\) is reduced to its lowest terms because the greatest common divisor is 1. Neither the numerator or the denominator can be reduced to any lower terms. In contrast, the fraction \(\frac{4}{6}\) is not reduced to its lowest terms because the greatest common divisor of both 4 and 6 is 2, not 1.

1. Reducing with repeated application of divisors

The following demonstrates the process of reducing a fraction to its lowest terms in a series of steps:

$$ -\\frac{18}{24} = \frac{18/2}{24/2} = \frac{9}{12} = \frac{9/3}{12/3} = \frac{3}{4} -$$

_Once we get to \(\frac{3}{4}\) the greatest common divisor is 1, therefore \(\frac{18}{24}\) has been reduced to its lowest terms _.

2. Reducing in one step with the highest common divisor

In the previous example the reduction took two steps: first we divided by two and then we divided by three. There is a more efficient way: find the highest common divisor of the numerator and denominator and then use this as the basis for the reduction. With this method, the reduction can be completed in a single step.

The greatest common divisor of 18 and 24 is 6, thus:

$$ -\frac{18}{24} = \frac{18/6}{24/6} = \frac{3}{4} -$$

Note how our earlier two divisors 2 and 3 are factors of 6, showing the consistency between the two methods.

3. Reducing with factors and cancellation

The two methods above are not very systematic and are quite heuristic. The third approach is more systematic and relies on the interchangeability of factors and divisors.

Instead of thinking asking what is the greatest common divisor of 18 and 24 we could ask: which single number can we multiply by to get 18 and 24? Obviously both numbers are in the six times table. This is therefore to say that 6 is a factor of both: we can multiply some number by 6 to arrive at both 18 and 24. The numbers are 3 and 4 respectively:

$$ -\\begin{split} -3 \cdot 6 = 18 \\ -4 \cdot 6 = 24 -\\end{split} -$$

Here, 3 and 4 are the multiplicands of the factor 6. As \(\frac{3}{4}\) doesn’t have a lower common factor, it is therefore defined in its lowest terms.

Once we have reached this point, we no longer need the common factor 6, we can therefore cancel it out, leaving the multiplicands as the reduced fraction:

$$ -\\begin{split} -3 \cancel{\cdot6= 18}\\ -4 \cancel{\cdot6= 24} -\\end{split} -$$

4. Reducing with prime factorisation

This is still a bit long-winded however particularly when finding the factors of larger numbers because we have to go through the factors of both numbers to find the largest held in common.

A better method is to utilise prime factorization combined with the canceling technique.

First we find the prime factors of both the numerator and denominator: drawio-Page-7.drawio.png

This gives us:

$$ -\\frac{18}{24} = \frac{2 \cdot 3 \cdot 3}{2 \cdot 2 \cdot 2 \cdot 3} -$$

We then cancel out the factors held in common between the numerator and denominator:

$$ -\\frac{\cancel{2} \cdot \cancel{3} \cdot 3}{\cancel{2} \cdot 2 \cdot 2 \cdot \cancel{3}} -$$

This gives us:

$$ -\\frac{3}{2 \cdot 2} -$$

We then simplify the fraction as normal to its lowest term (conducting any multiplications required by what is left from the prime factorization):

$$ -\\frac{3}{4} -$$

Reducing fractions that contain variables

Superficially this looks to be more difficult but in fact we can apply the same prime factorization method to get the result.

Demonstration

Reduce the following fraction to its lowest terms: $$\frac{25a^3b}{40a^2b^3}$$

The prime factors of the numerator and denominator:

$$ -\\begin{split} -25 = {5, 5} \\ -40 = {2,2,2,5} -\\end{split} -$$

Now we apply canceling but we include the variable parts, treating them exactly the same as the coefficients. We break them out of their exponents however.

$$\frac{25a^3b}{40a^2b^3} =\frac{5 \cdot 5 \cdot a \cdot a \cdot a \cdot b}{2 \cdot 2 \cdot 2 \cdot 5 \cdot a \cdot a \cdot b \cdot b \cdot b }$$

Canceled:

$$\frac{\cancel{5} \cdot 5 \cdot \cancel{a} \cdot \cancel{a} \cdot a \cdot \cancel{b}}{2 \cdot 2 \cdot 2 \cdot \cancel{5} \cdot \cancel{a} \cdot \cancel{a} \cdot \cancel{b} \cdot b \cdot b }$$

Which gives us:

$$ -\\frac{5 \cdot a}{2 \cdot 2 \cdot 2 \cdot b \cdot b} = \frac{5a}{8b^2} -$$

Reducing fractions that contain negative values

Reduce the following fraction to its lowest terms: $$\frac{14y^5}{-35y^3}$$

  • This fraction is an instance of a fraction with unlike terms.

  • Apply Prime factorization:

    draw.io-Page-8.drawio.png

  • Cancel the coefficients and variable parts

    $$ -\\frac{14y^5}{-35y^3}=\frac{5 \cdot 7 \cdot 2 \cdot y \cdot y \cdot y \cdot y \cdot y}{-5 \cdot 7 \cdot y \cdot y \cdot y} = - \frac{2y^2}{5} -$$

Reduce the following fraction to its lowest terms: $$\frac{- 12xy^2}{ - 18xy^2}$$

draw.io-Page-8.drawio 1.png

  • Cancel the coefficients and variable parts

    $$

    • \frac{12xy^2}{18xy^2}=\frac{3 \cdot 2 \cdot 2 \cdot x \cdot y \cdot y}{3 \cdot 7 \cdot 3 \cdot 2 \cdot x \cdot x \cdot y} = - \frac{2y}{3x} $$
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Register_and_cache_memory.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Register_and_cache_memory.html deleted file mode 100644 index c7c5e0f..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Register_and_cache_memory.html +++ /dev/null @@ -1,50 +0,0 @@ -Register and cache memory - My Zettelkasten - - - - -

Register and cache memory

The CPU has its own memory devices in the form of registers and cache memory.

Registers are a form of memory that are positioned on the same chip as the CPU. They are very fast but can only store a small amount of data. They are used to store the results of calculations and the addresses of the next instructions to be processed.

The cache is SRAM memory that is separate from the DRAM memory which comprises the main memory. It exists in order to boost perfomance when executing the read/request cycles of the steps detailed above.

There are two types of cache memory:

  • L1 cache
    • Situated on the CPU chip itself
    • Fastest to access but stores less
  • L2 cache
    • Situated outside of the CPU on its own chip
    • Slower to access than L1 but can store more data

The L1 cache is the fastest since the data has less distance to travel when moving to and from the CPU. This said, the L2 cache is still very fast when compared to the main memory, both because it is SRAM rather than DRAM and because it is closer to the processor than the main memory.

Cache controllers use complex algorithms to determine what should go into the cache to facilitate the best performance, but generally they work on the principle that what has been previously used by the CPU will be requested again soon. If the CPU has just asked for an instruction at memory location 555 it’s very likely that it will next ask for the one at 556, and after that the one at 557 and so on. The cache’s controller circuits therefore go ahead and fetch these from slow DRAM to fast SRAM.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Regular_expressions_in_SQL.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Regular_expressions_in_SQL.html deleted file mode 100644 index 76e1e22..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Regular_expressions_in_SQL.html +++ /dev/null @@ -1,54 +0,0 @@ -Regular expressions in SQL - My Zettelkasten - - - - -

Regular expressions in SQL

SELECT name FROM country WHERE name RLIKE '[xy][ai]' ORDER BY name;
-
-Guyana
-Mexico
-Myanmar
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Reiteration.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Reiteration.html deleted file mode 100644 index 7bac183..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Reiteration.html +++ /dev/null @@ -1,50 +0,0 @@ -Reiteration - My Zettelkasten - - - - -

Reiteration

Reiteration (R) allows us to restate any proposition already in the proof within the main proof or a more deeply nested sub-proof. Reiteration allows us to reuse any assumptions, or propositions derived from assumptions, without having to introduce a new dependency with another assumption.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Relation_between_kernel_and_CPU.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Relation_between_kernel_and_CPU.html deleted file mode 100644 index 10164f6..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Relation_between_kernel_and_CPU.html +++ /dev/null @@ -1,50 +0,0 @@ -Relation between the kernel and CPU - My Zettelkasten - - - - -

Relation between the kernel and CPU

It can be confusing to understand how the kernel and CPU interact with one another. Whilst it is true to say the kernel mediates between the hardware and user processes, this led me to think that the kernel was somehow ‘over and above’ the actions of the CPU. This is wrong and if you think about it, how could this be since any process, kernel included, requires the processor? The kernel is executed by and loaded into the CPU just like any other instruction in the fetch, decode, execute cycle of the CPU.

However as a process, the kernel is the ‘first amongst equals’ given that it is the core embodiment of the operating system. At boot time, the kernel is injected into memory and at this point the CPU looks to this address in memory in order to source its first instruction. That’s how the kernel gets going. It is the first instruction that the CPU fetches and this is what allows the kernel to play its mediatory role. However most of the fetch, decode, execute cycles of the CPU take place independently of the kernel.

Fetch decode and execute refer to processor pipeline stages. They occur automatically as part of normal processor operation, the kernel doesn’t generally have any direct control over how that happens…When the boot loader loads the kernel, it points the CPU’s program counter to an entry point in the kernel’s code. From there, the CPU will continue executing (fetching decoding and executing) kernel code until you point the program counter to a userspace program, where it will continue executing userspace code until an interrupt points the program counter back into kernel code. That’s basically what the CPU will be doing from boot up to shut down; switching between executing kernel code and executing userspace code (Reddit)

This is because of context switching, when the CPU is running its cycle, the kernel is idle waiting for it to complete. Once control switches back to the kernel it can then run its next duty which will be either process, memory or device management or system calls. Then it will hand control over to either the processor or user space.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Relational_database_architecture.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Relational_database_architecture.html deleted file mode 100644 index b7250dd..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Relational_database_architecture.html +++ /dev/null @@ -1,50 +0,0 @@ -Relational database architecture - My Zettelkasten - - - - -

Relational database architecture

Tables, fields and records are the basic building blocks of databases

Table

A group of similar data with rows for records and columns for each field.

Record

A horizontal row: a collection of items which may be of different data types all relating to the individual or object that the record describes. A single entry in the table. Sometimes called row interchangeably.

Field

A vertical column: stores a single particular unit of data for each record. Each field must use the same data type. Sometimes called field interchangeably.

Each individual field has properties: such as the data type, length or the total memory allocation.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Relays.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Relays.html deleted file mode 100644 index 4bf4af2..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Relays.html +++ /dev/null @@ -1,50 +0,0 @@ -Relays - My Zettelkasten - - - - -

Relays

A relay is an electrically operated switch.

It uses an electromagnet to mechancially operate a switch. A switch in one circuit can be used the trigger the operation of another circuit.

Core components

  • electromagnet
    • a coil of wire around an iron core
  • armature
    • a movable magnetic strip
  • contacts
    • electrical connections that can be open or closed
  • spring
    • returns the armature to its resting position when not energised

Operation

Operation of a relay

Current flows through the electromagnet which creates a magnetic field. This field attracts the armature which then moves to open or close the contacts. When the current stops, this returns the armature to its original position.

Usage

During the electro-mechanical era of computing they were used as precursors to vacuum tubes (and later, transistors) to implement logic gates. While they were superseded in this domain, they are still used in industrial control systems and automobiles.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Remote_tracking_branches.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Remote_tracking_branches.html deleted file mode 100644 index a8a6ae7..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Remote_tracking_branches.html +++ /dev/null @@ -1,50 +0,0 @@ -Remote tracking branches - My Zettelkasten - - - - -

Remote tracking branches

A remote tracking branch is a local snapshot or reference to the state of a branch on a remote repository.

When you clone a remote repository, Git automatically creates remote tracking branches for all the branches on the remote repository.

The remote tracking branches have the prefix origin/ followed by the name of the remote branch. For example, if you clone a repository with a branch named develop, Git creates a remote tracking branch named origin/develop.

When you use commands like git fetch and git pull, you are interacting with the remote repository and having it reflected in the remote tracking branches.

For instance, git fetch makes the remote tracking branch reflect the remote changes so that you have a local copy.

The remote tracking branch is not the same as a local branch. A local branch is a branch that may or may not exist on the remote. Once it has been pushed to the remote repository, a remote tracking branch will be created for its remote version. When you make local changes, the snapshot of the remote tracking branch will no longer be up to date: your local branch will be “ahead” of it. Once you push, the remote tracking branch snapshot is update and reflects the local state of the branch and the two are in sync again.

The same is true of remote branches. When you checkout a remote branch, your local version of it reflects a remote tracking version of it. This goes out of sync with your local version when changes are made on the remote.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Rename_a_branch.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Rename_a_branch.html deleted file mode 100644 index 1549de9..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Rename_a_branch.html +++ /dev/null @@ -1,50 +0,0 @@ -Rename a branch - My Zettelkasten - - - - -

Rename a branch

In local development

git branch -m <old_name> <new_name>

Update the remote

git push origin -u <new_name>
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Reset_to_remote_version.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Reset_to_remote_version.html deleted file mode 100644 index 847775e..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Reset_to_remote_version.html +++ /dev/null @@ -1,51 +0,0 @@ -Reset to remote version of a branch - My Zettelkasten - - - - -

Reset to remote version of a branch

The scenario: your local Git history has become corrupted in some way and you want a clean history based on the current state of the remote. We will demonstrate with main.

git fetch origin
-git reset --hard origin/main
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Resistance.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Resistance.html deleted file mode 100644 index c62ddad..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Resistance.html +++ /dev/null @@ -1,50 +0,0 @@ -Resistance - My Zettelkasten - - - - -

Resistance

  • Resistance is opposition to the flow of current.

  • Different materials have different levels of resistance. For example glass and rubber are excellent resistors whereas silver and copper offer little resistance to current flow.

  • We utilise resistors to control the flow of current in a circuit.

Relationship between resistance and insulation

Resistance and insulation are not the same thing although they relate to the same natural phenomena.

Resistance is a property of an electrical circuit whereas insularity is a property of substances found in the world.

Similarly, insulators are naturally occuring materials that resist the flow of current to different degrees whereas a resistor is a man-made electrical component that is used to control the flow of current in a circuit.

Factors affecting resistance

  • The larger the diameter of an electric wire, the lower the electrical resistance to the current flow. (If we use the analogy of electricity as water-flow: the wider the pipe, the more water that can flow.)
  • As a conductor heats up (e.g. copper, aluminium wire), its overall resistance increases.

Notation and scientific expression

Resistance

  • We use \(R\) to represent resistance
  • The unit of resistance is ohms (\(\Omega\))

One ohm is the resistance of a circuit or circuit element that permits a steady current flow of one amp (one coulomb/second) when one volt is applied to the circuit.

Conductance

  • We use \(G\) to represent conductance
  • The unit of conductance is Mho (ohm spelled backwards) (\(\mho\))

Conductance is the ability of a material to pass electrons

Given that resistance is the opposite of conductance, the relation between the two quantities can be expressed via a recipricol: \(R = 1/G\) and \(G = 1/R\)

Ohm’s Law

The relationship between current, resistance and voltage is expressed in Ohm’s Law.

Resistors

A resistor is an electrical component that can be used in circuits to introduce specific amounts to resistance where needed. This is typically done in order to temper the total voltage and so keep the current flowing within certain set parameters.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Restructure_URLs_lambda.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Restructure_URLs_lambda.html deleted file mode 100644 index 296680f..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Restructure_URLs_lambda.html +++ /dev/null @@ -1,65 +0,0 @@ -AWS Lambda examples - My Zettelkasten - - - - -

AWS Lambda examples

Reconstruct CloudFront URLs

exports.handler = (event, context, callback) => {
-  // Extract the request from the CloudFront event that is sent to Lambda@Edge
-  var request = event.Records[0].cf.request;
-
-  // Extract the URI from the request
-  var olduri = request.uri;
-
-  // Match any '/' that occurs at the end of a URI. Replace it with a default index
-  var newuri = olduri.replace(/\/$/, "/index.html");
-
-  // Replace the received URI with the URI that includes the index page
-  request.uri = newuri;
-
-  // Return to CloudFront
-  return callback(null, request);
-};

Let’s walk through the above example making reference to the general structure of the AWS Lambda handler function:

  1. The event parameter is invoked to gain access to the event that triggered the function. This is a CloudFront request event which is targetted with event.Records[0].cf.request
  2. We classify this request as the olduri since it doesn’t have the form we want.
  3. We mutate the original request by replacing / with /index.html
  4. We then re-assign the request.uri value to the value of the new URI.
  5. Finally we invoke the callback parameter to signal the completion of the transformation and return the new request as the return value.
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Retrieve_data_from_SQL_table.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Retrieve_data_from_SQL_table.html deleted file mode 100644 index 37b3fad..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Retrieve_data_from_SQL_table.html +++ /dev/null @@ -1,56 +0,0 @@ -Retrieve data from table with SQL SELECT statement - My Zettelkasten - - - - -

Retrieve data from table with SQL SELECT statement

Select data from the database. The data returned is stored in a result table called the result-set.

A table named models:

modelIdnamecoresreleaseDate
2Raspberry Pi Model B22022-11-19
3Raspberry Pi Model C42022-11-25
4MacBook Pro M292022-03-18

Basic usage

SELECT name FROM models

We can pass in a comma-separated list of fields:

SELECT name, releaseDate FROM models

With parameters

WHERE

The WHERE clause specifies a search criterion. The WHERE clause should always be last in the syntax. The clauses are always written in this order: FROM followed by WHERE

SELECT name FROM models WHERE cores > 3

Compound statements

Compound statements allow you to apply more filters to your clauses within an SQL statement. SQL allows you to build complex, combinatorial WHERE clauses by using Boolean and mathematical operators (i.e AND , OR , > , < , != , <= …)

Multiple clauses:

SELECT name, ram, release_date
-FROM model
-WHERE release_date > '2018-01-01' AND ram > 512;

More complex logic achieve with parentheses:

SELECT name, cores, release_date
-FROM model
-WHERE (manufacturer_id = 1 OR manufacturer_id = 2) AND cores >= 2;

Transform returned data

We can apply ordering to the return data

SELECT name FROM models ORDER BY name, cores
-SELECT name FROM models ORDER BY name, cores DESC

ORDER BY always comes last, after the selection and any filtering clauses but before a WHERE clause

Paginate

We can break our returned data into blocks with LIMIT

LIMIT 5 -- Return first five items
-LIMIT 5,5 -- Return first five items from the sixth row
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Role_of_memory_in_computation.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Role_of_memory_in_computation.html deleted file mode 100644 index 8dd6550..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Role_of_memory_in_computation.html +++ /dev/null @@ -1,50 +0,0 @@ -The role of memory in computation - My Zettelkasten - - - - -

The role of memory in computation

The following steps outline the way in which memory interacts with the processor during computational cycles, once the bootstrapping process has completed and the OS kernel is itself loaded into memory.

  1. A file is loaded from the harddisk into memory.
  2. The instruction at the first address is sent to the CPU, travelling accross the data bus part of the system bus.
  3. The CPU processes this instruction and then sends a request accross the address bus part of the system bus for the next instruction to the memory controller within the chipset.
  4. The chipset finds where this instruction is stored within the DRAM and issues a request to have it read out and send to the CPU over the data bus.

This is a simplified account; it is not the case that only single requests are passed back and forth. This would be inefficient and time-wasting. The kernel sends to the CPU not just the first instruction in the requested file but also a number of instructions that immediately follow it.

Memory flow diagram

Every part of the above process - the journey accross the bus, the lookup in the controller, the operations on the DRAM, the journey back accross the bus - takes multiple CPU clock cycles.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Role_of_unique_key_in_relational_databases.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Role_of_unique_key_in_relational_databases.html deleted file mode 100644 index 1657fe9..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Role_of_unique_key_in_relational_databases.html +++ /dev/null @@ -1,50 +0,0 @@ -Unique key - My Zettelkasten - - - - -

Unique key

Every table in a relational database should have a unique key. A unique key is one field that uniquely identifies each record.

This is essential for carrying out operations across database tables and for creating and deleting database entires in accordance with the ACID_principle. It is also a safeguard: it means you can always identify a record by itself and don’t have to rely on generic queries to identify it.

Sometimes you will have a dedicated field such as UNIQUE_ID for the unique key. Other times you can use an existing field to fulfil that function. When an existing, visible column is used as the unique key it is called the primary key. Other times the unique key can be hidden from the table.

In both cases the following constraints must be met:

  1. No two records can have the same primary key data
  2. The primary key value should never be reused. Thus, if a record is deleted from the table, it should not be re-allocated to a new record.
  3. A primary key value must not be modified once it has been created
  4. A primary key must have a value; it cannot be null
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Routing_on_link_click_in_React.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Routing_on_link_click_in_React.html deleted file mode 100644 index c9a9b39..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Routing_on_link_click_in_React.html +++ /dev/null @@ -1,78 +0,0 @@ -Test: Routing on link click - My Zettelkasten - - - - -

Test: Routing on link click

Component

const CertificateHtmlLink = () => {
-  return (
-    <div className="certificate-html-link html-version-message">
-      <Link className="btn btn-primary ml-2" to="/some-location">
-        View HTML version
-      </Link>
-    </div>
-  );
-};

Test

import { render, fireEvent } from "@testing-library/react";
-import { Router } from "react-router-dom";
-
-describe("<CertificateHtmlLink", () => {
-  it("should link to dynamic HTML certificate page URL on click event", () => {
-    // Arrange:
-    const history = createMemoryHistory({ initialEntries: ["/"] });
-
-    // Act:
-    const { getByText } = render(
-      <Router history={history}>
-        <CertificateHtmlLink to="/certificate/123" />
-      </Router>
-    );
-
-    // Assert:
-    expect(history.location.pathname).toBe("/");
-    fireEvent.click(getByText("View HTML version"));
-    expect(history.location.pathname).toBe("/certificate/123");
-  });
-});
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Rules_for_operations_on_like_and_unlike_terms.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Rules_for_operations_on_like_and_unlike_terms.html deleted file mode 100644 index 96467e8..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Rules_for_operations_on_like_and_unlike_terms.html +++ /dev/null @@ -1,91 +0,0 @@ -Rules for operations on like and unlike terms - My Zettelkasten - - - - -

Rules for operations on like and unlike terms

Addition

Like terms

Sum the absolute values and add the negative sign afterwards.

$$ -\\begin{split} --4 + -3 -\\ = 4 + 3 -\\ = -7 -\\end{split} -$$

Unlike terms

Subtract smaller from larger amount and then affix the sign of the larger amount to the sum.

Negative plus positive

$$ -\\begin{split} --8 + 5 -\\ = 8 - 5 -\\ = 3 -\\ = -3 -\\end{split} -$$

Positive plus negative

$$ -\\begin{split} -4 + -1 -\\ = 4 - 1 -\\ = 3 -\\end{split} -$$

Subtraction

Like terms

Turn the operator and second negative into a plus sign and execute as an addition.

$$ -\\begin{split} --4 - -3 = -\\ = -4 + 3 -\\ = -1 -\\end{split} -$$

Unlike terms

Positive subtract negative

Turn the negative after the operator to a positive. (Same as previous.)

$$ -\\begin{split} -2 - -3 = -\\ = 2 + 3 -\\ = 5 -\\end{split} -$$

Negative subtract positive

Start at the negative value and count backwards on the number-line

$$ --2 - 3 = -5 -$$

Multiplication

Like terms

The product of two negative numbers will always be a positive number.

$$ --15 \cdot -3 = 45 -$$

Unlike terms

The product of a positive and a negative number will always be a negative number.

$$ --3 \cdot 5 = -15 -$$

Division

Division follows the same rules as multiplication.

Like terms

The quotient of two negative numbers will always be a positive number.

$$ --15 / -3 = 5 -$$

Unlike terms

The quotient of a positive and a negative number will always be a negative number.

$$ --15 / 3 = -5 -$$

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/S3.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/S3.html deleted file mode 100644 index 34c70ac..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/S3.html +++ /dev/null @@ -1,50 +0,0 @@ -S3 - My Zettelkasten - - - - -

S3

You can think of S3 as an external mounted harddrive for storing raw binary data (images, soundfiles, documents etc).

Your use of the S3 service is divided up into buckets. Buckets contain files and resources. These are just resource names in an online container, the data doesn’t have any structure beyond that.

The primary use of S3 is to store resources that an application needs and/or to facilitate the uploading and downloading of resources to and from an application.

You can set access and authentication conditions for buckets, making the data public or restricted.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/SAM.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/SAM.html deleted file mode 100644 index da65ed6..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/SAM.html +++ /dev/null @@ -1,111 +0,0 @@ -AWS SAM - My Zettelkasten - - - - -

AWS SAM

SAM stands for serverless application model. It is a framework developed by AWS to simplify the process of building, deploying and managing serverless applications. It provides a concise syntax for defining the components of a serverless application, such as Lambda functions, API gateway and database tables.

The SAM infrastructure is defined in a YAML file which is then deployed to AWS. SAM syntax gets transformed into CloudFormation during the deployment process. (CloudFormation is a broader and more robust AWS tool for large, highly scaleable infrastructures).

Key features of SAM

  • Single deployment configuration
  • Integration with development tools
  • Local testing and debugging
  • Built on AWS CloudFormation

Main technologies required

Docker

Whilst SAM can be used to create a deployable file for AWS it can also be run as a container for local development with Docker.

AWS CLI

This is installed using Python and allows you to interact directly with AWS via the command-line.

AWS SAM CLI

See https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/install-sam-cli.html

Setting up credentials for the AWS CLI

You require an access key for the given IAM user. You should create an IAM account specific to the project with bounded permissions.

aws configure
-AWS Access Key ID [None]: AK*******
-AWS Secret Access Key [None]: ukp******
-Default region name [None]:
-Default output format [None]:

This information can be found in the Security Credentials section of the given IAM user:

Switching between credentials

You should set up a different IAM user for each project.

You can do this with:

aws configure --profile <profile-name>

This will then ask you to add the credentials for the user.

You can switch between different credentials for the user as follows:

AWS_PROFILE=<profile-name> sam build
-

Starting a SAM project

First create a directory for your project which will serve as the repository:

mkdir aws-sam-learning
-cd aws-sam-learning

Then we can use the sam cli to bootstrap the project:

sam init --runtime nodejs16.x

We can just click through and accept the basic HelloWorld Lambda.

This will create the Lambda as well as an API Gateway trigger URL.

template.yaml

This is autogenerated and details the main constituents of the project. There are lots of fields but the most important are the following:

HelloWorldFunction:
-  Type: AWS::Serverless::Function
-  Properties:
-    CodeUri: hello-world/
-    Handler: app.lambdaHandler
-    Runtime: nodejs16.x
-    Architectures:
-      - x86_64
-    Events:
-      HelloWorld:
-        Type: Api
-        Properties:
-          Path: /hello
-          Method: get

This details the location of the handler function which is contained at the path hello-world/app.js:

exports.lambdaHandler = async (event, context) => {
-  try {
-    // const ret = await axios(url);
-    response = {
-      statusCode: 200,
-      body: JSON.stringify({
-        message: "hello world",
-        // location: ret.data.trim()
-      }),
-    };
-  } catch (err) {
-    console.log(err);
-    return err;
-  }
-
-  return response;
-};

It also lists the get event that we can use to call API Gateway and trigger the Lambda.

The full template is below:

Adding our own code

We will create our own function and API Gateway trigger.

We will place our function after the existing HelloWorldFunction

ClockFunction:
-  Type: AWS::Serverless::Function
-  Properties:
-    CodeUri: clock/
-    Handler: handler.clock
-    Runtime: nodejs16.x
-  Events:
-    ClockApi:
-      Type: Api
-      Properties:
-        Path: /clock
-        Method: get

We can test the syntax with:

sam validate

Just like with HelloWorld, we will create a directory for this function: clock and we will initialise it as an npm project.

mkdir clock
-cd clock
-npm init

We will use handler.js as our root, handler function.

We have said in the template file that our Handler: handler.clock, therefore the main function in the handler module should be clock:

const moment = require("moment");
-
-exports.clock = async (event) => {
-  console.log("Clock function run");
-  const message = moment().format();
-  const response = {
-    statusCode: 200,
-    body: JSON.stringify(message),
-  };
-  return response;
-};

The directory structure is as follows:

When we call the API Gateway path /clock with GET, our function will be triggered.

Deploying the project

We will now deploy our project to AWS from the local environment.

The process is as follows:

  1. Build
  2. Package
  3. Deploy

Build

We need to install the runtime dependencies for the function. We do this by running sam build. This ignores test files and development dependencies and installs the project dependencies and source files to a temporary subdirectory.

The build directory is .aws-sam/build/. There will be a subdirectory for each of our files.

Package

As noted, CloudFront handles the deployment of the application. It can only receive one file as an input. The packaging process consists in creating that single file.

The packaging proces will first archive all of the project artefacts into a zip file and then upload that to S3. A reference to this S3 entity is then provided to CloudFormation.

The command is as follows:

sam package
-  --template-file template.yaml
-  --output-template-file pkg.yml
-  --region eu-west-1

This will automatically create a hashed bucket name for you in S3 (I have tried to add my own naming but it doesn’t comply.)

Local development with Docker

In order to work with your application locally without actually sending requests to AWS and using credit, you can run a local instance.

See Local AWS Development with SAM.

Deploy

Once you have packaged the app you can deploy with sam deploy --guided. This will talk you through the defaults and will deploy the package to CloudFormation. In CloudFormation each individual project is called a stack.

If we then go to Cloud Formation we will see the deployed application.

Call the endpoint

If we now go to the Lambda console, we will see our function listed, and the API Gateway endpoint under triggers:

We can then call this from Postman to check everything is working as it should:

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Save_readonly_Vim_file.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Save_readonly_Vim_file.html deleted file mode 100644 index bce4527..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Save_readonly_Vim_file.html +++ /dev/null @@ -1,50 +0,0 @@ -Save read only Vim file - My Zettelkasten - - - - -

Save read only Vim file

 :w !sudo tee % >/dev/null
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Schema_Definition_Language_in_GraphQL.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Schema_Definition_Language_in_GraphQL.html deleted file mode 100644 index 007a4c9..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Schema_Definition_Language_in_GraphQL.html +++ /dev/null @@ -1,72 +0,0 @@ -Schema Definition Language - My Zettelkasten - - - - -

Schema Definition Language

SDL is the formal name for the syntax of GraphQL schemas.

Types

A schema is a collection of object types that contain fields. Each field has a type of its own. A field’s type can be a primitive/scalar value (such as an Int or a String), or it can be another object type (just like a custom type in TS).

A schema’s type can be non-nullable which is to say, a required field. We indicate this with !.

A type for a field can be a collection/array of a given type.

The following example indicates these properties:

type Person {
-  age: Int
-  name: String
-  pets: [Pet]!
-}
-
-type Pet {
-  species: String
-  name: String
-  age: Int
-}

Queries

A query is also a schema type but of a special sort.

The fields of this type are entry points into the rest of the schema. These are the top-level fields that the client can query for.

For example if we had this type:

type Track {
-  id: ID!
-    author: Author!
-  thumbnail: String
-  length: Int
-  modulesCount: Int
-}

We could define a type to access a give Track as follows:

type Query {
-  tracksForHomePage: [Track!]!
-}

Then use this type as the basis for a query:

Descriptions

Descriptions are comments that allow you to document your Schema

Single line:

"Single line comment"
"""
-Multi
-line
-comment
-"""
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Secrets_or_env_vars_in_AWS.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Secrets_or_env_vars_in_AWS.html deleted file mode 100644 index 53b082a..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Secrets_or_env_vars_in_AWS.html +++ /dev/null @@ -1,50 +0,0 @@ -Secrets or environment variables? - My Zettelkasten - - - - -

Secrets or environment variables?

Choosing between environment variables and AWS Secrets Manager hinges on factors such as use case, security needs, and the data type. Environment variables are easier to use, free, and offer fast access but are less secure and lack features like versioning. On the other hand, AWS Secrets Manager provides robust security through encryption, access control, audit trails, and supports secret versioning and rotation. However, it comes with additional costs and can introduce latency and rate limits.

General recommendations suggest using AWS Secrets Manager for storing sensitive data like API keys and passwords, due to its enhanced security features. For less sensitive, non-critical data such as feature flags or environment-specific URLs, environment variables are often adequate. Cost-conscious users who don’t need advanced features may find environment variables more economical. Ultimately, the best choice depends on your specific requirements and limitations.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Semantic_versioning.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Semantic_versioning.html deleted file mode 100644 index 48afda4..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Semantic_versioning.html +++ /dev/null @@ -1,50 +0,0 @@ -Semantic versioning - My Zettelkasten - - - - -

Semantic versioning

3.4.1 === major.minor.patch
  • Major

    • New feature which may potentially cause breaking changes to applications dependent on the previous major version.
  • Minor

    • New features that do not break the existing API
  • Patch

    • Bug fixes for the current minor version

Glob patterns for versioning

Caret

Interested in any version so long as the major version remains at \(n\). E.g if we are at ^4.2.1 and we upgrade, we are ok with 4.5.3 or 4.8.2. We are not bothered about the minor or patch version.

This is equivalent to 4.x

Tilde

Interested in any patch version within set major and minor parameters. For example ~1.8.3 means you don’t mind any patch version so long as it is a patch for 1.8. This is equivalent to 1.8.x.

No tilde or caret

Use the exact version specified

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Set_DNS_settings.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Set_DNS_settings.html deleted file mode 100644 index 0087e06..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Set_DNS_settings.html +++ /dev/null @@ -1,77 +0,0 @@ -Set DNS settings - My Zettelkasten - - - - -

Set DNS settings

Change the default DNS server

On Arch and most modern Linux distributions domain name resolution is handled via the systemd-resolved #systemd configuration.

Within the system systemd files this will be handled in /etc/systemd/network/wired.network or /etc/systemd/network/wlan.network files etc.

In the file below I have turned of DHCP routing and specified the address of my Pi-Hole device to handle domain name resolution:

#wlan.network
-
-[Match]
-Name=wl*
-
-[Link]
-RequiredForOnline=routable
-
-[Network]
-DHCP=yes
-DNS=192.168.0.4
-MulticastDNS=yes
-
-[DHCPv4]
-UseDNS=no
-RouteMetric=600
-
-[IPv6AcceptRA]
-RouteMetric=600
-

This stops it using the default DNS server of my router and runs the resolutions against Pi-Hole.

This should automatically update the two resolv.conf files (which should be in syc), viz:

# File: /run/NetworkManager/resolv.conf
-# Generated by NetworkManager
-nameserver 192.168.0.4
-nameserver fded:2060:8671:0:681:9bff:fe9b:37f0
-
# File: /etc/resolv.conf
-# Generated by NetworkManager
-nameserver 192.168.0.4
-nameserver fded:2060:8671:0:681:9bff:fe9b:37f0
-

Network scanning Network debugging

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Sets_in_Python.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Sets_in_Python.html deleted file mode 100644 index 17dbf5f..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Sets_in_Python.html +++ /dev/null @@ -1,88 +0,0 @@ -Sets in Python - My Zettelkasten - - - - -

Sets in Python

  • They are unordered
  • You can increase/decrease their length by adding/removing new members
  • They do not allow duplicate members
  • Can only hold immutable objects

Sets are denoted with {...}

Basic usage

basket = {'apple', 'orange', 'apple', 'pear', 'orange', 'banana'}
-print(basket)  # show that duplicates have been removed
-print(len(basket))
-# {'apple', 'pear', 'banana', 'orange'}
-# 4

Looping through sets

for item in basket:
-    print(item)
-
-"""
-apple
-pear
-banana
-orange
-"""

Check for membership

basket = {'apple', 'orange', 'apple', 'pear', 'orange', 'banana'}
-print('apple' in basket)
-# True

Remove items from set

remove will raise an error if the specified item does not exist, discard will not

basket.remove('apple')
-basket.discard('apricot')
-print(basket)
-# {'pear', 'banana', 'orange'}
-
-basket.clear()
-print(basket)
-#set
-

Add items to a set

basket.add('apricot')
-print(basket)
-# {'apricot', 'pear', 'banana', 'orange'}

Start with empty set

To declare an empty set you cannot just do:

my_set = {}

You have to use a constructor:

my_set = set()

Apply unions and intersections

s1 = {'apple', 'orange', 'banana'}
-s2 = {'grapefruit', 'lime', 'banana'}
-print('Union:', s1 | s2)
-# Union: {'apple', 'orange', 'grapefruit', 'lime', 'banana'}
-
-print('Intersection:', s1 & s2)
-# Intersection: {'banana'}
-
-
-print('Difference:', s1 - s2)
-# Difference: {'orange', 'apple'}
-
-print('Symmetric Difference:', s1 ^ s2)
-#Symmetric Difference: {'apple', 'orange', 'grapefruit', 'lime'}
-
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Setting_up_and_configuring_TypeScript.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Setting_up_and_configuring_TypeScript.html deleted file mode 100644 index aebbfd1..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Setting_up_and_configuring_TypeScript.html +++ /dev/null @@ -1,71 +0,0 @@ -Setup and configuration - My Zettelkasten - - - - -

Setup and configuration

Installation and configuration

TypeScript offers custom installations for most modern JS-based frameworks including Webpack, React.js and Vue.js. The instructions below cover minimal TS set-up outside of a specific framework. TypeScript adds an additional step to any build process since your code must compile to JS before any bundling and transpilation can occur.

Installation

mkdir typescript-project
-cd typescript-project
-npm i typescript --save-dev

Initialise project

npx tsc --init

Basic configuration

"compilerOptions": {
-	"target" : "es2020", //es2015 for prod
-	"module" : "es2020",
-  	"allowJs": true,
-  	"checkJs": true,
-  	"strict": true,
-  	"esModuleInterop": true
-}

Specify output paths (for production code)

"compilerOptions": {
-	...
-	"outDir": "dist",
-	"sourceMap": true,
-}

Compile-time commands

tsc --noEmit
tsc --noEmit --watch

Global requirements

npm install -g typescript
-npm install -g ts-node

ts-node allows you to run TS files the way you would with standard JS, i.e. node [filename], you just use ts-node filename .

This is a convenience that saves you compiling from TS → JS and then running Node against the compiled JS. Which is useful for debugging and checking values as you work.

Imports and exports

You may wish to define your custom types outside of their application, for instance in a /types/ directory. The custom type or types can then be imported using standard ES6 imports:

export type Article = {
-		price: number,
-}
-
-export type AnotherType = {
-...
-}
import { Article, AnotherType } from "./types/allTypes.js";
-import Article from "./types/allTypes.js";

TypeScript also provides a specific import keyword type so that you can distinguish type imports from other module imports. This is handy when you have multiple components in the one file:

import type { Article } from "./types/allTypes.js";
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Shell_sessions.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Shell_sessions.html deleted file mode 100644 index 1f3339f..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Shell_sessions.html +++ /dev/null @@ -1,50 +0,0 @@ -Shell sessions - My Zettelkasten - - - - -

Shell sessions

Types of shell session

Shell sessions can be one of or several instances of the following types:

  • login shell
    • A session that must be authenticated such as when you access remote resources using SSH
  • non-login shell
    • Not the above
  • interactive shell
    • A shell session that runs in the terminal and thus that the user can interact with
  • non-interactive shell
    • A shell session that runs without a terminal

If you are working with a remote server you will be in an interactive login shell. If you run a script from the command line you will be in a non-interactive non-login shell.

Shell sessions and access

The type of shell session that you are currently in affects the Environmental-and-shell-variables-04d5ec7e8e2b486a93f002bf686e4bbb that you can access. This is because the order in which configuration files are read on initialisation differs depending on the type of shell.

  • a session defined as a non-login shell will read /etc/bash.bashrc and then the user-specific ~/.bashrc file to build its environment.
  • A session started as a login session will read configuration details from the /etc/profile file first. It will then look for the first login shell configuration file in the user’s home directory to get user-specific configuration details.

In Linux, if you want the environmental variable to be accessible from both login and non-login shells, you must put them in ~/.bashrc

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Signed_and_unsigned_numbers.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Signed_and_unsigned_numbers.html deleted file mode 100644 index 5305947..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Signed_and_unsigned_numbers.html +++ /dev/null @@ -1,50 +0,0 @@ -Signed and unsigned numbers - My Zettelkasten - - - - -

Signed and unsigned numbers

Summary

  • To represent negative integers in binary we use signed numbers.Signed binary includes negative integers, unsigned binary does not.

  • There are different methods of implementing the encoding of signed numbers. Two prominant approaches are two’s complement and signed magnitude representation.

Two’s complement, Binary encoding, Signed magnitude representation

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Signed_magnitude_representation.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Signed_magnitude_representation.html deleted file mode 100644 index dad1979..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Signed_magnitude_representation.html +++ /dev/null @@ -1,50 +0,0 @@ -Signed magnitude representation - My Zettelkasten - - - - -

Signed magnitude representation

Summary

Detail

The concept behind SMR is similar to how we designate positive and negative integers in denary mathematics: we use a dedicated symbol (-) to signpost that the integer is negative. In the binary application the dedicated symbol is one of the binary digits that comprise the number.

Typically 0 is used to indicate an unsigned (positive) integer and 1 to indicate a signed (negative) number. The rest of the bits are the magnitude (the actual numerical value).

We can demonstrate with an 8-bit binary system, encoding 5: 0000 0101. Here the furthest bit (aka. the “most significant bit” (MSB)) at the \(2^8\) position is 0, designating that the number is unsigned. The signed equivalent is 1000 0101, with the MSB being 1 designating the number as signed. When we are working with signed numbers, the MSB is known as the signed bit.

Advantages

Limitations

Applications

signed_and_unsigned_numbers

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Single_file_Python_scripts.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Single_file_Python_scripts.html deleted file mode 100644 index ce87af1..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Single_file_Python_scripts.html +++ /dev/null @@ -1,64 +0,0 @@ -Single file Python scripts - My Zettelkasten - - - - -

Single file Python scripts

Basic architecture

#! /usr/local/bin/python3
-
-import sys
-
-if __name__ == "__main__":
-    all_args = sys.argv
-    specific_arg = sys.argv[0]
-    # Main functionality...

When you run a script (module) Python assigns the string __main__ to the __name__ attribute to the script that is being executed.

If you run the script as an import into another script, the __name__ attribute of the imported module is set to the module name, not __main__.

Everything can go under the __main__ conditional, or, for better readability, you can define a main function that is then invoked, e.g:


-def main():
-    # Do some stuff
-
-
-if __name__ == "__main__":
-    main()
-

Python modules and imports

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Singleton_pattern.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Singleton_pattern.html deleted file mode 100644 index 8e15f1e..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Singleton_pattern.html +++ /dev/null @@ -1,92 +0,0 @@ -Singleton pattern - My Zettelkasten - - - - -

Singleton pattern

As the name suggests, the Singleton pattern is best used in scenarios where you only want to use a single, unique instance of a class. This is for functionality that should only be executed once in the lifecycle of an application. The canonical case would be some kind of bootstrapping process required at initialisation, or initial configuration for an app.

Use-cases

  • Establishing connection to backend database
  • API connection (managing tokens so that you are not sending multiple unnecessary calls)
  • Configuration settings for an app
  • Global state stores in Redux and the React Context API

With this pattern only one instance of the class can exist. If no instance of the singleton class exists then a new instance is created and returned, but if an instance already exists, then the reference to the existing instance is returned. A singleton should be immutable by the consuming code, and there should be no danger of instantiating more than one of them.

Implementation

This pattern can be implemented either with a object or a class.

In the example below, a global store for a modern JS application is created using an object.

Using an object

We ensure singularity by:

  • using const for the object so that it cannot be reassigned
  • using Object.freeze so that the fields cannot be overwritten, deleted, or additional fields added
const _data = [];
-
-// Methods to add and retrieve data from the store
-const UserStore = {
-  add: (item) => _data.push(item),
-  get: (id) => _data.find((d) => d.id === id),
-};
-
-Object.freeze(UserStore);
-export default UserStore;

Using a class

The same process can be created using classes:

class UserStore {
-  constructor() {
-    this._data = [];
-  }
-
-  add(item) {
-    this._data.push(item);
-  }
-
-  get(id) {
-    return this._data.find((d) => d.id === id);
-  }
-}
-
-const instance = new UserStore();
-Object.freeze(instance);
-
-export default instance;

Bear in mind that this is really just an ES6 module with freeze applied. The only real difference between a singleton and a module is that there should only be one instance of it.

With classes, there is a further step that can be taken to prevent more than once instance of the class being created. This is necessary if you want to be really strict because it is of course possible for a well motivated person to get around the safeguards we established above. We do this by having the class itself check whether there is already an instance of itself. If so, it just returns the already existing instance. We do this by using the self-reference inherent in this :

class UserStore {
-  constructor() {
-    if (!UserStore.instance) {
-      this._data = [];
-      UserStore.instance = this;
-    }
-
-    return UserStore.instance;
-  }
-
-  //rest is the same code as preceding example
-}
-
-const instance = new UserStore();
-Object.freeze(instance);
-
-export default instance;
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Sliding_window.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Sliding_window.html deleted file mode 100644 index 19cbd2f..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Sliding_window.html +++ /dev/null @@ -1,76 +0,0 @@ -Sliding window - My Zettelkasten - - - - -

Sliding window

Whereas the multiple pointer pattern works by keeping two array indices running at once and comparing their values on each iteration, the sliding window has a running value (the ‘window’) that is updated at each iteration and which compares itself against its most recent previous value.

This is what makes it ‘sliding’: the value isn’t constant, it changes (or doesn’t) based on what it was previously.

Example: maximum sum of sub-array

We create a function that takes an array and a sub-array length n. The objective is to find the maximum value that can be created by summing n elements of the array. It moves through the array, summing by n keeping track of the highest sum value so far and the current sum value. At the end it should return the highest possible sum value.

Here we do this for a sub-array of length 2:

function maxSubarraySum(arr, subArrLength) {
-  let maxSum = 0; // Largest sum value so far
-  let tempSum = 0; // Current sum value
-
-  //  Establish the first 'maxSum'
-  // At the beginning this will just be the sum of the first two array elements
-  for (let i = 0; i < subArrLength; i++) {
-    maxSum += arr[i];
-  }
-
-  // Map temporary sum to maxSum
-  // Accordingly, as we have only mapped the first sub-array, the max sum will be the same
-  // as the current sum
-  tempSum = maxSum;
-
-  // Move through the array one element at a time (`i++`) via a window starting from the element that is equal to `subArrLength`
-  // The first sum calculation is already taken care of in the earlier loop and stored in `maxSum`, so we don't have to worry about missing the elements in indices less than subArrLength
-  for (let i = subArrLength; i < arr.length; i++) {
-    // Temp sum becomes a moveable window value equal to the subtraction of the previous element and the addition of next element in line
-    tempSum = tempSum - arr[i - subArrLength] + arr[i];
-    // Max sum is redefined as the largest subArrLengthber between the previous highest and the current value of tempSum
-    maxSum = Math.max(maxSum, tempSum);
-  }
-  return maxSum;
-}
-
-console.log(maxSubarraySum([100, 200, 300, 400], 2)); // 700
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Solving_equations.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Solving_equations.html deleted file mode 100644 index fb59805..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Solving_equations.html +++ /dev/null @@ -1,50 +0,0 @@ -Solving equations - My Zettelkasten - - - - -

Solving equations

Use inversion of operators

When solving equations we frequently make use of the operator inversion rules to find the solutions.

Example: inversion of addition

For example, the equation \(9 = 3 + x\) has the solution \(6\) (\(x\) is equal to \(6\)). To arrive at this, we can use the inverse of the main operator in the equation (addition): \(9-3 = 6\).

Example: inversion of subtraction

Now consider \(19 = x - 3\). The solution to this equation is \(22\) (\(x\) is equal to \(22\)). To arrive at this, we can use the inverse of the main operator in the equation (subtraction): \(19 + 3 = 22\).

Example: inversion of division

The equation we want to solve: $$\frac{x}{6} = 4$$

Now we invert it by multiplying the denominator by the quotient: \(6\cdot 4 = 24\). Therefore: $$ \frac{24}{6} = 4$$ The solution is \(24\)

Example: inversion of multiplication

The equation we want to solve: $$4x = 36$$ Now we invert it by dividing the product by the coefficient: !Add link to ‘coefficient’

$$\frac{36}{4} = 9$$

Therefore the solution is \(9\): $$ 4(9) = 36$$

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Sorting_lists_in_Python.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Sorting_lists_in_Python.html deleted file mode 100644 index e438f2b..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Sorting_lists_in_Python.html +++ /dev/null @@ -1,58 +0,0 @@ -Sorting lists in Python - My Zettelkasten - - - - -

Sorting lists in Python

Using sorted() Function:

The built-in sorted() function returns a new list containing all the elements of the original list sorted in the specified order (either ascending, which is default, or descending).

my_list = [3, 1, 4, 1, 5, 9, 2, 6, 5]
-sorted_list = sorted(my_list)
-print(sorted_list)  # Output: [1, 1, 2, 3, 4, 5, 5, 6, 9]

For sorting in descending order, you can use the reverse=True argument:

sorted_list_desc = sorted(my_list, reverse=True)
-print(sorted_list_desc)  # Output: [9, 6, 5, 5, 4, 3, 2, 1, 1]

Using .sort() Method:

The .sort() method sorts the elements of a list in-place and returns None. This modifies the original list.

my_list = [3, 1, 4, 1, 5, 9, 2, 6, 5]
-my_list.sort()
-print(my_list)  # Output: [1, 1, 2, 3, 4, 5, 5, 6, 9]

For sorting in descending order:

my_list.sort(reverse=True)
-print(my_list)  # Output: [9, 6, 5, 5, 4, 3, 2, 1, 1]

Using a Custom Key Function:

Both sorted() and .sort() accept a key parameter that allows you to specify a function to determine the sorting order. The function should take a single argument and return a value that will be used for sorting purposes.

For example, if you have a list of strings and you want to sort them by their length:

my_str_list = ["apple", "banana", "cherry", "date"]
-sorted_by_length = sorted(my_str_list, key=len)
-print(sorted_by_length)  # Output: ['date', 'apple', 'cherry', 'banana']
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Soundness.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Soundness.html deleted file mode 100644 index a0e56a8..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Soundness.html +++ /dev/null @@ -1,63 +0,0 @@ -Soundness - My Zettelkasten - - - - -

Soundness

Recall that in the definition of deductive validity we do not say: an argument is valid iff if the premises are true and the conclusion is true. We say if it is possible for the premises to be true. This is important: we are not interested in the actual truth of the premises or the conclusion.

Demonstration

Therefore this argument is valid:

(P1) Oranges are the same colour as bananas.
-(P2) Bananas are yellow.
-____________________________________________
-(C) Oranges are yellow.

Of course oranges are not yellow but were (P1) true, then given (P2), the conclusion must also be true.

This argument is also valid:

(P1) Oranges are the same colour as carrots.
-(P2) Carrots are orange.
-____________________________________________
-(C) Oranges are orange in colour.

The difference here is that the premises happen to be true and, given that the argument is valid, the conclusion must also be true. What we have defined here is soundness: the argument is said to be sound as well as valid. This is an additional and stronger criterion of evaluation.

An argument is sound if and only if it is deductively valid and all its premises are true.

We must not forget that truth alone is not the sole condition for soundness. We can have arguments whose conclusion and premises are all true without the argument being sound:

(P1) London is the capital of the United Kingdom
-(P2) The capital of the United Kingdom is in the southern part of the United Kingdom.
-(P3) Cambridge is not the capital of the United Kingdom
-____________________________________________
-(C) London is south of Cambridge

All propositions are true here but the argument is not deductively valid: the premises are all true but the conclusion is false.

We can also have arguments which are valid but which are not sound:

(P1) Vitamin C prevents colds.
-(P2) Vitamin C does not prevent colds.
-____________________________________________
-(C) Vitamin C is harmless

This argument is valid because we cannot consistently assert the premises and deny the conclusion. In either case, the conclusion can be said to follow from the premises. The problem is that we cannot consistently assert both premises: it is not possible for both propositions to be true at the same time.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Split_into_array_in_Bash.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Split_into_array_in_Bash.html deleted file mode 100644 index bf1e8c5..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Split_into_array_in_Bash.html +++ /dev/null @@ -1,78 +0,0 @@ -Splitting input into an array - My Zettelkasten - - - - -

Splitting input into an array

readarray

readarray makes it really easy to split input into an array based on new lines. Say we have this file as input:

123
-456
-789

Then we can split like so:

readarray -t name_for_array < ./input.text
-
-# Print all elements
-echo "${name_for_array[@]}"
-
-# Print element by index
-
-echo "${name_for_array[1]}"
-456

If we want to read a string directly:

readarray -t new_name_for_array <<< "here
-is
-some
-text"
-
-echo "${new_name_for_array[1]}"
-is

The -t flag removes the trailing newline

See more: https://linuxhint.com/split-string-array-bash/

read

For delimiters other than a space we have to use read, combined with IFS the Internal Field Separator.

For example, to split by comma:

# comma-input.txt
-something,something else,something more
IFS=',' read -a arr < ./comma_inputs.txt

We use the -a flag to signal that we want each item read returned as an element in an array

mapfile

We can use mapfile to read the lines of a input file in set segments.

For the following file:

line one
-line two
-line three
-line four

We could generate the following output:

-----SNIP-----
-line one
-line two
------SNIP-----
-line three
-line four

With:

while mapfile -t -n 2 ary && ((${#ary[@]})); do
-  printf '%s\n' "${ary[@]}"
-  printf -- '--- SNIP ---\n'
- done < $testInput

So, while there are input lines, map each line into an array and return it in groups of 2.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Stack_memory.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Stack_memory.html deleted file mode 100644 index a83245a..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Stack_memory.html +++ /dev/null @@ -1,50 +0,0 @@ -Stack memory - My Zettelkasten - - - - -

Stack memory

Summary

  • Along with heap memory heap memory, programs make use of stack memory during runtime.

  • Best suited for small-sized singular values that are temporary/ephemeral rather than large or complex data types that need to persist for a longer time.

  • Specifically used to keep track of memory used during function executions within a given scope: control flow, local variables, returned value.

  • Uses a LIFO data-structure

Similarly to the stack data structure, it works on the basis of LIFO: the last item put on the stack is the first item to be withdrawn.

Note, this doesn’t mean that the data at the memory addresses that comprise the stack can only be accessed in a LIFO manner. Any item currently on the stack can be accessed (be read or modified) at any time. LIFO applies when it is is time to clear memory from the stack: the most recent addition is cleared first from the top down.

Stack pointer

A stack pointer is used to manage the items in the stack. This value is stored in a register and its value is the memory address of the item currently on the top of the stack. Note: not the value itself, the address of the value.

When a new value is added to the top of the stack, the pointer’s value is adjusted to increase the size of the stack and make room for the new value. So this will be a new memory address for the latest item. When an item is removed, the reverse happens. The previously top address is cleared and the pointer points to the new top item.

Threads

For every thread that a program spawns, it gets its own stack or “stack frame”. Stack memory within the thread can only be accessed by processes within that thread which is what makes it well suited for managing scoped function memory.

Role in program execution

  1. Function call management: a stack records the key information pertaining to the execution of a function: parameters, local variables, the location of the address for the returned value.

  2. Local variable storage: storing the variables local to a function’s scope and removing them once the function returns, avoiding memory leaks

  3. Control flow: record from where a function is called and where its return value should be stored, meaning the right value is always returned no matter how nested it is.

  4. Recursion: individuating each call of a function that calls itself and its given step to avoid infinite loops

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Stacks.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Stacks.html deleted file mode 100644 index e5537b1..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Stacks.html +++ /dev/null @@ -1,77 +0,0 @@ -Stacks - My Zettelkasten - - - - -

Stacks

A stack visualised vertically stack2.svg

A stack visualised horizontally stack1.svg

A stack is a linear data structure that observes LIFO

Think of a stack like a pile of books: the last book that you add is the nearest to the top and therefore the first one that you can remove.

If you want to get a book that is not at the top, you have to first remove the books that are above it to get to it.

This type of data structure is linear and only allows sequential, not random, access. It is an example of ‘last one in first one out’.

We can build a stack from an array

A stack is an example of a data structure that can be built by adapting an array. If you think about it, all that is needed is an array to store the data, an array push method to add elements to the ‘end’ or the ‘bottom’ of the stack and an array pop method to remove the element at the top.

Demonstration

Below we create a stack constructor, using a class. An object created from this template will have the following properties and methods:

  • items[] → an array to store the data
  • push() → a method to add an element to the end of the stack
  • pop() → a method to remove an element from the front

In addition we have the following helpers, which allow us to check the status of the stack and retrieve information about it:

  • isEmpty() → check if the stack is populated or not
  • clear() → empty the stack of its content (therefore making isEmpty() return true)
  • size → a property corresponding to the stack’s length
class Stack {
-  items = []; // the array that will store the elements that comprise the stack
-  push = (element) => this.items.push(element); // add an element to the end of the stack
-  pop = () => this.items.pop(); // remove and return the last element from the stack
-
-  // We can add some useful helper methods, that return info about the state of the stack:
-  isEmpty = () => this.items.length === 0; // return true if the stack is empty
-  clear = () => (this.items.length = 0); // empty the stack
-  size = () => this.items.length; // count elements in stack
-}

Run through

let stack = new Stack();
-test.push(1); // Add some elements to the stack
-test.push(2);
-test.push(3);
-
-// Stack now looks like:
-console.log(stack.items); // [1, 2, 3]
-
-// Let's try removing the last element
-stack.pop(); // 3 -> this was the last element we added, so it's the first one that comes out
-
-// Now the stack looks like this:
-// [1,2]
-
-// Let's add a new element
-test.push(true);
-
-// Now the stack looks like:
-// [1,2, true]

Practical applications

  • Any application that wants to got ‘back in time’ must utilise a stack. For example, the ‘undo’ function in most software is a function of a stack. The most recent action is at the top, and under that is the second most recent and so on all the way back to the first action.
  • Recursive functions: a function that calls itself repeatedly until a boundary condition is met is using a stack structure. As you drill down through the function calls you start from the most recent down to the last.
  • Balancing parentheses. Say you want to check if the following string is balanced [()] . Every time you find an opening parentheses. You push that to the front of a stack. You then compare the closing parentheses with the order of the stack. The same could be done when seeking to find palindromes. This sort of thing could be a code challenge so build an example.
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Stale_branches_and_pruning.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Stale_branches_and_pruning.html deleted file mode 100644 index 291acd3..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Stale_branches_and_pruning.html +++ /dev/null @@ -1,54 +0,0 @@ -Stale branches and pruning - My Zettelkasten - - - - -

Stale branches and pruning

A stale branch is a remote tracking branch that no longer tracks anything because the actual branch on the remote has been deleted.

If you delete the remote branch, the remote tracking branch will also be deleted. However if a collaborator deletes the remote branch, your remote tracking branch will remain, becoming a stale branch.

In order to get rid of it, we need to manually remove it. We can do this with the general prune command:

git remote prune origin
-
-# or run a preview of the action
-
-git remote prune origin --dry-run
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Step_functions_and_state_machines.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Step_functions_and_state_machines.html deleted file mode 100644 index 4d8a7cc..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Step_functions_and_state_machines.html +++ /dev/null @@ -1,50 +0,0 @@ -AWS Step functions and state machines - My Zettelkasten - - - - -

AWS Step functions and state machines

AWS Step Functions is an AWS service that allows you to coordinate distributed applications and microservices by creating workflows.

Workflows are made up of a series of steps and are known as state machines. A state machine defines:

  • the states of the workflow
  • the transitions between states
  • the inputs and outputs of each state

State machines are defined via a JSON object which specifies the states and the transitions between them. It also includes error catchers and retry logic.

At the beginning you define a StartAt state which is the entrypoint of the state machine. This can be manually triggered, or more likely, triggered by another AWS service such as a Lambda, an AWS_API_Gateway request or a messaging/queue event.

The state machine ultimately ends at an end state. In between are various intermediary states which can include:

  • Task states (do something)
  • Choice states (do something based on conditions)
  • Wait states
  • Success states (if preceding state succeeds do X)
  • Fail states (if preceding state fails do Y)
  • Parallel states

The diagram below shows the definition of a given state machine. On the left is the JSON specification. On the right is a diagramatic representation that shows the control flow and all possible steps that comprise a given pathway / state:

For each execution of the state machine (each time it is triggered) you can review the runtime. The flow diagram will highlight green to show the given pathway, and you can also see the inputs and outputs for each step and any errors:

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Strategies_for_constructing_proofs.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Strategies_for_constructing_proofs.html deleted file mode 100644 index c20875d..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Strategies_for_constructing_proofs.html +++ /dev/null @@ -1,52 +0,0 @@ -Strategies for constructing proofs in propositional logic - My Zettelkasten - - - - -

Strategies for constructing proofs in propositional logic

General strategy

  • Break complex propositions into simpler sentences by using the elimination rules
  • Recombine simple propositions into complex propositions using the introduction rules.

Goal analysis

The approach above describes the general form of a proof but of course it will not always work and there will be cases where the route to the desired derivation is more circuitous. In these instances it is to best to combine this general top level strategy with goal analysis.

Goal analysis is a recursive strategy which proceeds by using a ‘goal’ proposition to guide the construction of intermediary derivations.

Assume that we want to show that an argument is valid. Then our ultimate goal is to derive the conclusion from the premises we are given. We first ask ourselves: which propositions if we could derive them, would allow us to easily derive the conclusion? (For example, these propositions might be two simple propositions that when combined with Conjunction Introduction give us the conclusion.) Deriving these propositions then becomes the new intermediate goal.

If arriving at these propositions is not trivial, we then ask ourselves the question again: which propositions would permit us to derive the intermediary propositions we need? You keep working back in this manner until you reach a base level. Then it is just a matter or working upwards from each set of derived intermediary propositions until you reach the ultimate goal.

Demonstration

Let’s say we want to prove \((L \lor A) \land D\) from the propositions \(\lnot N\) and \(((\lnot N \rightarrow L) \land (D \leftrightarrow \lnot N))\).

First, we consider what is the easiest possible way of achieving the proposition \((L \lor A) \land D\). Clearly it is to separately derive each disjunct (\(L \lor A\) and \(D\)) and then combine them with Conjunction Introduction. This provides us with our first goal: to derive each of the separate conjuncts.

Let’s start with \(D\): where does it occur in the assumptions? It occurs in the compound \((\lnot N \rightarrow L) \land (D \leftrightarrow \lnot N)\), but only in the first conjunct. We can get this simply but applying Conjunction Elimination.

So far we have:

Now we just need to get \(D\) from the proposition at line 3. This is easy since we already have access to the consequent of the biconditional at line 1. Therefore we can apply Biconditional Elimination) at line 3 to get \(D\). We are now halfway there:

Next we need to turn our attention to deriving \(L \lor A\). How can we obtain \(L\) ? Well it is contained within the first conjunct of the assumption on line 2. Again, we can get this through the application of Conjunction Elimination. Now, how do we get \(L\) from \((\lnot N \rightarrow L)\)? Well, we already have the antecedent \(\lnot N\) as an assumption on the first line, so we can use Conditional Elimination to derive \(L\). These two steps give us:

Now we need to get from \(L\) to \(L \lor A\). This is really straightforward because by using Disjunction Introduction) we can get from any sentence to a disjunction. Finally, having assembled all the constituent parts of the conjunction that is the conclusion, we can combine them with Conjunction Introduction as we had planned at the outset.

A further example

We will seek to prove the following:

$$ -\{ \lnot L \leftrightarrow [X \land (\lnot S \lor B) ], (E \land C) \rightarrow \lnot L, (E \land R) \land C \} \vdash X \land (\lnot S \lor B) -$$

The requirements here could easily mislead us. We see that the target proposition is a conjunction so we might think that the best strategy is to seek to derive each conjunct and then combine them via Conjunction Introduction).

Actually, if we look more closely, there is a better approach. The target proposition is contained in the first premise as the consequent to the biconditional (\(\lnot L \leftrightarrow [X \land (\lnot S \lor B)]\)). A better approach is therefore to seek to derive the antecedent (\(\lnot L\)) and then use Biconditional Elimination to extract the target sentence which is the consequent.

proof.png

Proving theorems

When we are proving theorems we do not have a set of assumptions to work from when constructing the proof. We must derive the target sentence from the ‘empty set’ which is the target sentence itself. It is therefore like a process of reverse engineering.

Demonstration

Prove: \(\vdash (U \land Y) \rightarrow [L \rightarrow (U \land L)]\)

Our strategy here is to identify the main connective in the proposition we want to derive (the material conditional). We then assume the antecedent and attempt to derive the consequent from it.

A complex theorem proof

Prove \(\vdash (\lnot A \lor \lnot B) \leftrightarrow \lnot(A \land B)\)

Walkthrough

Lines 1-12

  • Our auxiliary goal is to prove \(\lnot (A \lor B) \rightarrow \lnot (A \land B)\).

  • Our starting assumption is to a disjunction. Thus we can apply Disjunction Elimination to show that our goal sentence \(\lnot(A \land B)\) follows from each of the disjuncts (\(\lnot A\) and \(\lnot B\)) in dedicated sub-proofs. If we can do this, we have the right to derive \(\lnot (A \land B)\).

  • In both cases(\(\lnot A \vdash \lnot (A \land B)\)) and (\(\lnot B \vdash \lnot (A \land B)\) we require another sub-proof to reach the target as there is no easy path available. So we derive a negation from \(A \land B\) so that we can negate it as \(\lnot (A \land B)\).

  • Having done this, we can discharge the Disjunction Elimination sub-proofs and derive \(\lnot (A \land B)\) from \(\lnot A \lor \lnot B\)

Lines 13-26

  • Our auxiliary goal is to prove \(\lnot (A \land B) \rightarrow \lnot A \lor \lnot B\). This will require a different approach to the above because we are not working from a disjunction anymore, we have a negated conjunction.
  • We will do this by assuming the negation of what we want to prove (\(\lnot (\lnot A \lor \lnot B)\)) and then apply Negation Elimination to get \(\lnot A \lor \lnot B\).
  • This requires us to derive a contradiction. We get this on lines 23 and 24. This requires as previous steps that we have two sub-proofs that use Negation Elimination to release \(A\) and \(B\)
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Streams_in_NodeJS.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Streams_in_NodeJS.html deleted file mode 100644 index 6e4a29a..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Streams_in_NodeJS.html +++ /dev/null @@ -1,75 +0,0 @@ -Handling streams with fs - My Zettelkasten - - - - -

Handling streams with fs

When reading from a file, the fs.readFile() method waits until the entire file has been read before executing the callback. It’s obvious why this might not be ideal in certain cases. If the file is very large you are utilising a lot of Memory for a single process. Additionally, the data you need might appear early in the file, in which case, once you find the data you want, there is no need to read to the end of the file.

An example of this in practice is watching a Netflix film: we don’t have to wait for the whole film to download, we can start watching it immediately because it is passed to us in chunks.

Reading streams

This is why the ability to read files and data as streams exists in Node.js. Streams promote memory and time efficiency. As you are not necessarily reading the whole file, you can extract the data you need quickly and you are not putting the whole file in memory.

When read as a stream, the file is broken up into smaller chunks. Readable streams raise data events and pass the chunks to our callbacks. Hence we don’t have to wait for the whole file before registering data chunks.

Implementation

Instead of, e.g :

fs.readFile("./lorem.md", "UTF-8", function (err, fileContents) {
-  console.log(fileContents);
-});

We would:

let stream = fs.createReadStream("./lorem.md", "UTF-8");
-
-let data;
-
-stream.once("data", (chunk) => {
-  console.log("read stream started");
-});
-
-stream.on("data", (chunk) => {
-  data += chunk;
-  console.log(data);
-});
-
-stream.on("end", () => console.log("stream ends"));

We use once to do something at the moment the stream starts to be read.

We use on to target the "data" and "end" events. We use this to log the chunks via the data variable.

Writing streams

When we write as a stream, we break data up and pass this to a reader as a stream. It is what creates a stream in the first place.

For example we could create a stream that handles stdin and writes this to a file in chunks:

var stream = fs.createWriteStream("lorem.txt")
-
-process.stdin.once("data", (data) => {
-    stream.write(data, function() => {
-        // data is now written.
-    })
-})
-
-process.on("exit", function () {
-    stream.close()
-})

Note that we always have to close the stream on exit

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Strings_in_Bash.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Strings_in_Bash.html deleted file mode 100644 index 8b4f694..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Strings_in_Bash.html +++ /dev/null @@ -1,57 +0,0 @@ -Strings in bash - My Zettelkasten - - - - -

Strings in bash

Return a substring by index

myString="hello"
-substring=${myString:0:3}
-# hel

This is often used when looping through each character in a string.

Loop through each character in a string

str="hallelujah"
-stringLength=$(expr length str)
-
-for (( i=0; i<=${stringLength}; i++ )); do
-    echo "${str:$i:1}"
-done
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Strings_in_Python.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Strings_in_Python.html deleted file mode 100644 index 334715b..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Strings_in_Python.html +++ /dev/null @@ -1,129 +0,0 @@ -Strings in Python - My Zettelkasten - - - - -

Strings in Python

Generally, anything that changes a string will be a method on the str class, rather than a built-in function like len(), as such it will use dot notation

  • Strings are immutable: string operations produce a new string.
# Working with Strings
-
-my_variable = 'Bob'
-print(my_variable)
-# Bob
-
-my_variable = "Eloise"
-print(my_variable)
-# Eloise
-
-# A multi line string
-my_variable = """
-Hello
-  World
-"""
-print(my_variable)
-"""
-Hello
-  World
-"""
-
-my_string = 'Hello World'
-print(len(my_string))
-# 11
-
-string_1 = 'Good'
-string_2 = " day"
-string_3 = string_1 + string_2
-print(string_3)
-# Good day
-
-msg = 'Hello Lloyd you are ' + str(21)
-print(msg)
-# Hello Lloyd you are 21
-
-# Range of String operations
-msg = 'Hello World'
-print(msg.replace("Hello", "Goodbye"))
-# Goodbye World
-
-print('Edward Alan Rawlings'.find('Alan'))
-# 7
-
-print('Edward John Rawlings'.find('Alan'))
-# -1
-
-print('James' == 'James') # prints True
-print('James' != 'John') # prints True
-
-print("msg.startswith('H')", msg.startswith('H'))
-# msg.startswith('H') True
-
-print("msg.endswith('d')", msg.endswith('d'))
-# msg.endswith('d') TRUE
-
-print('some_string.upper()', msg.upper())
-# some_string.upper() HELLO WORLD
-
-print('sub string: ', 'Hello-World'[1:5])
-# sub string: ello
-
-# String interpolation
-user_age = input("Please enter your age: ")
-print(f'You are {user_age}')

str.split()

The split() function in Python is used to divide a string into multiple parts at the occurrence of a given separator. This function returns a list of substrings.

General syntax

str.split(separator, maxsplit)
  • The separator is optional. It specifies the separator to use when splitting the string. If no separator is provided, it will default to using whitespace.

  • maxsplit is also optional and specifies how many splits to do. Default value is -1, which is “all occurrences”.

Examples


-text = "Hello world, how are you?"
-
-# Default usage:
-x = text.split()
-print(x)
-# ['Hello', 'world', 'how', 'are', 'you?']
-
-# Using a specific separator
-x = text.split(",")
-print(x)
-# ['Hello', 'world how are you?']
-
-# Specifiying a maxplit value
-x = text.split(" ", 1)
-print(x)
-# ['Hello']
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Structuring_Express_applications.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Structuring_Express_applications.html deleted file mode 100644 index fe47f4f..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Structuring_Express_applications.html +++ /dev/null @@ -1,57 +0,0 @@ -Structuring Express applications - My Zettelkasten - - - - -

Structuring Express applications

In general, the following application structure works well:

\
-    routes\
-    models\
-    middlewear\
-    config\
-    public\
-  index.js
-
  • routes/

    • This should house all our RESTful API endpoints for a given resource which we define as a module. For instance if we are handling API requests to /api/courses/ we would have a module at /routes/courses.js
  • models/

    • Here we define our database schemas: definitions for the structure of the data objects we want to return from the database.
    • In the case of Mongo we would have a file for each of our Mongoose models which will belong to an overall collection of which there are document instances.
    • Our model files should map onto our route modules; there should generally be at least one model file for each module. The model stands as an abstract representation of the data that we will be handling with our request paths in the routes file.
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Substrings_in_Bash.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Substrings_in_Bash.html deleted file mode 100644 index b6e5ac0..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Substrings_in_Bash.html +++ /dev/null @@ -1,50 +0,0 @@ -Substrings in Bash - My Zettelkasten - - - - -

Substrings in Bash

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Swap_space.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Swap_space.html deleted file mode 100644 index 4f59b89..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Swap_space.html +++ /dev/null @@ -1,53 +0,0 @@ -Swap space - My Zettelkasten - - - - -

Swap space

A swap partition is a partition on a disk that is not intended to be used as a filesystem. Instead, it is a part of the disk that is used to augment the main memory.

If you run out of memory and have set up a swap partition, the OS will be able to move pieces of memory to and from disk storage. This is called swapping because pieces of idle programs are swapped to the disk in exchange for active pieces residing on the disk.

View current swap usage

If you have a swap space established, the command free will show current usage:

free
-               total        used        free      shared  buff/cache   available
-Mem:        16099420     3031572    10157652     1153144     2910196    11605820
-Swap:        3145724           0     3145724

Create a swap partition

To use an existing disk partition as a swap you can run the command mkswap [device] and then swapon [device] to register the space with the kernel.

Add to fstab

You will want the swap to be activated every time the OS boots so add the following line to the fstab, where /sda3 is used as the example partition:

/dev/sda3e none swap sw 0 0

Create a swap file

// Add info here

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Switch_between_Python_vers.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Switch_between_Python_vers.html deleted file mode 100644 index b8a8c34..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Switch_between_Python_vers.html +++ /dev/null @@ -1,50 +0,0 @@ -Switch between Python versions locally - My Zettelkasten - - - - -

Switch between Python versions locally

pyenv local 3.8
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Syllogism.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Syllogism.html deleted file mode 100644 index 437aa57..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Syllogism.html +++ /dev/null @@ -1,53 +0,0 @@ -Syllogism - My Zettelkasten - - - - -

Syllogism

In order to make assertions about the relative consistency or inconsistency of a set of propositions we advance arguments. Consider everyday life: if we are having an argument with someone, we believe that they are wrong. A more logical way to say this is that we believe that their beliefs are inconsistent. In order to change their viewpoint or point out why they are wrong we advance an argument intended to show that belief A conflicts with belief B. Or if C is true, then you cannot believe that D.

In formal terms an argument is a set of propositions comprising one or more premises and a conclusion. The conclusion is taken to be supported by the premises.

The terms argument and syllogism are used interchangeably in logic to describe the above feature of a set of propositions.

Demonstration

(P1) All men are mortal.
-(P2) Socrates is a man.
-_____________________
-(C) Socrates is mortal
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Symlinks.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Symlinks.html deleted file mode 100644 index ed0c5d9..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Symlinks.html +++ /dev/null @@ -1,50 +0,0 @@ -Symlinks - My Zettelkasten - - - - -

Symlinks

A symbolic link, also termed a soft link, is a special kind of file that points to another file. Unlike a hard link, a symbolic link does not contain the data in the target file. It simply points to another entry somewhere in the file system.

Syntax

ln -s -f ~/[existing_file] ~/.[file_you_want_to_symbolise]

Real example:

ln -s -f ~/dotfiles/.vimrc ~/.vimrc
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Syntax_of_propositional_logic.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Syntax_of_propositional_logic.html deleted file mode 100644 index a521585..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Syntax_of_propositional_logic.html +++ /dev/null @@ -1,56 +0,0 @@ -Syntax of propositional logic - My Zettelkasten - - - - -

Syntax of propositional logic

Syntax of formal languages versus semantics

The syntactical study of a language is the study of the expressions of the language and the relations among them without regard to the possible interpretations or ‘meaning’ of these expressions.

Syntax is talking about the order and placement of propositions relative to connectives and what constitutes a well-formed expression in these terms. Semantics is about what the connectives mean, in other words: truth-functions and truth-values and not just placement and order.

Formal specification of the syntax of the language of Sentential Logic

Vocabulary

Propositions in SL are capitalised Roman letters (non-bold) with or without natural number subscripts. We may call these proposition letters. For example:

$$ -P, Q, R,... P_{1}, Q_{1}, R_{1}, ... -$$

The connectives of SL are the five truth-functional connectives:

$$ -\lnot, \land, \lor, \rightarrow, \leftrightarrow -$$

The punctuation marks of SL consist in the left and right parentheses:

$$ -( ) -$$

Grammar

  1. Every letter in a statement is a proposition.
  2. If \(P\) is a proposition then \(\lnot P\) is a proposition.
  3. If \(P\) and \(Q\) are propositions, then \(P \land Q\) is a proposition
  4. If \(P\) and \(Q\) are propositions, then \(P \lor Q\) is a proposition
  5. If \(P\) and \(Q\) are propositions, then \(P \rightarrow Q\) is a proposition
  6. If \(P\) and \(Q\) are propositions, then \(P \leftrightarrow Q\) is a proposition
  7. Nothing is a proposition unless it can be formed by repeated application of rules 1-6

Additional syntactic concepts

We also distinguish:

  • the main connective
  • immediate sentential components
  • sentential components
  • atomic components

These definitions provide a formal specification of the concepts of atomic and molecular propositions introduced previously.

  1. If \(P\) is an atomic proposition, \(P\) contains no connectives and hence does not have a main connective. \(P\) has no immediate propositional components.
  2. If \(P\) is of the form \(\lnot Q\) where \(Q\) is a proposition, then the main connective of \(P\) is the negation symbol that occurs before \(Q\) and \(Q\) is the immediate propositional component of \(P\)
  3. If P is of the form:
    1. \(Q \land R\)
    2. \(Q \lor R\)
    3. \(Q \rightarrow R\)
    4. \(Q \leftrightarrow R\)

where \(Q\) and \(R\) are propositions, then the main connective of \(P\) is the connective that occurs between \(Q\) and \(R\) and \(Q\) and \(R\) are the immediate propositional components of \(P\).

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Tags_in_Git.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Tags_in_Git.html deleted file mode 100644 index 5f2a865..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Tags_in_Git.html +++ /dev/null @@ -1,56 +0,0 @@ -Tags in Git - My Zettelkasten - - - - -

Tags in Git

Tags exist to reference specific commits in a more meaningful way than using a SHA reference. They are a named reference to a commit. As they refer to a singular commit they do not update but are a fixed point in the Git history.

Tags do not care about branches. They are an objective reference to a commit regardless of which branch it occured on. You can reference a tag without needing to be in the branch where the tagging originally took place.

Tags are frequently used to mark software release versions. But they can also be used for other designations such as the addition of a key feature or bug.

Creating a tag

git tag -am "Version 1.0" v1.0 dd5c4539a0

am is for “annotated + message”. The actual tag name is v1.0

Now you can refer to that commit with v1.0 rather than use the SHA

Deleting a tag

git tag -d v1.0

When you delete the tag you are only deleting the tag reference not the commit that it refers to.

Listing tags

git tag --list

Examples of use

git show v1.1
-
-git diff v1.0..v1.1

Pushing tags to a remote

In the examples so far, all the tags have been local tags. They only exist in our local workflow and are not accessible to our collaborators. If we do a git push, this doesn’t transfer our local tags. You have to do:

git push origin [tag-name]

Push all tags:

git push origin --tags
-
-# Delete remote tag
-
-git push -d origin [tag-name]

Getting tags from the remote

git fetch

This automatically fetches tags too.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Test_values_in_Bash.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Test_values_in_Bash.html deleted file mode 100644 index 380993f..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Test_values_in_Bash.html +++ /dev/null @@ -1,71 +0,0 @@ -Test values in Bash - My Zettelkasten - - - - -

Test values in Bash

test is a built-in command that is used to compare values or determine whether something is the case.

We can use the command test but it is more common to test a condition implicity by using square brackets. The square brackets are an alias for test. We use this alias when we use IF logic.

When we run a test the result we get back is a return status of a 0 or a 1. 0 indicates that the test was a success and 1 means failure. (Bear in mind this is in contrast to most all other programming languages.)

If we run a test in the command line we won’t get a 0 or a 1 or back, there will just be silence from the shell. We can explicitly invoke the return value with variable $?, e.g:

[ -d ~ ] # is the home directory a directory?
-echo $?
-0   # yes
-
-[ -d /bin/zsh ] # is this binary a directory?
-echo $
-1  # no

Test structures

Many tests can be run with flags as a shorthand like we saw above:

File operators

-a FILE        True if file exists.
--d FILE        True if file is a directory.
--e FILE        True if file exists.
--h FILE        True if file is a symbolic link
--s FILE        True if file exists and is not empty.
--N FILE        True if the file has been modified since it was last read.

String operators

-z STRING      True if string is empty.
--n STRING      True if string is not empty.

Differences between comparing numbers and strings

  • = is reserved for comparing strings
  • For numbers we use, e.g, [ 4 -lt 5 ]

Negation

We can negate a test condition with !:

[ ! 4 -lt 3 ]; echo $?
-0

Running process if test succeeds or fails

We can use the following structure to run a process if a test condition obtains:

[[ -d ~ ]] && echo "/home is a directory"

Extended test: [[...]]

When we use double brackets we are using extended test.

The extended test supports the standard test comparisons and adds other features:

  • The use of Boolean operators:
    [[ -d ~ || -a /bin/mash ]]; echo $?

Using regular expressions

Extended test also allows us to use regular expressions as part of our test conditions. In order to test against a regular expression we use =~ as the comparison operator.

[[ "thomas" =~ t.* ]]; echo $?

Here the test succeeds because “thomas” begins with “t” followed by any other character.

Further examples

Test if a character exists in two strings

string1="hello"
-string2="world"
-char="l"
-
-if [[ "$string1" == *"$char"* ]] && [[ "$string2" == *"$char"* ]]; then
-    echo "Character '$char' exists in both strings."
-else
-    echo "Character '$char' does not exist in both strings."
-fi

Note: this syntax can also be used to test if a given element exists in an array.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Testing_Python_code.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Testing_Python_code.html deleted file mode 100644 index 289efcb..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Testing_Python_code.html +++ /dev/null @@ -1,181 +0,0 @@ -Testing Python code - My Zettelkasten - - - - -

Testing Python code

pytest

Pytest is the most popular testing library for Python. It is not included with the Python standard library so it must be installed with pip. While it does not include a declaration library, it is robust enough to handle most scenarios having a rich and expressive set of constructs and decorators that let you declare what your tests should do, under what conditions they should run, and how they should interact with the rest of your system.

Using pytest

  • Pytest will automatically detect test files so long as they are named appropriately. E.g. for a module called lorem, it will detzect the unit test files lorem_test.py and test_lorem.py.
  • In order to detect tests it should be run from a directory level above them

Examples

Here is a basic example of using pytest for a local module callled palindrome:

import palindrome
-
-def test_is_palindrome():
-    assert palindrome.is_palindrome('soros')
-    assert palindrome.is_palindrome('torot')
-    assert not palindrome.is_palindrome('chair')

Mocking

patch() and Mock enable us to mock objects whilst testing (classes, functions, methods and properties belonging). They are used in combination.

The @patch decorator temporarily replaces a specified object in your code with a mock object and restores the original object after the test is complete

A Mock object simulates the object it replaces so that the object behaves as expected during testing. For example, if your code calls some_function.some_method(), and some_method is mocked, calling some_method will not execute real logic but will interact with the Mock object instead. Mock objects record details about how they have been used, like what methods have been called, with what arguments, etc., allowing you to make assertions about how they have been used.

@patch and Mock work together because a patch is used to replace an object or attribute with a Mock object. Mock handles the simulated functionality, and @patch designates the real value we are replacing with the mock.

Example case

I will use the following example from one my projects:

# get_articles.py
-def get_articles(article_type: str) -> Optional[Dict[str, Any]]:
-    """Retrieve articles from Pocket API"""
-
-    if POCKET_LAMBDA_ENDPOINT is None:
-        logging.error("Error: POCKET_LAMBDA_ENDPOINT envinronment variable is not set")
-        return None
-    else:
-        # Interpolate the article_type into the Pocket request URL
-        endpoint = POCKET_LAMBDA_ENDPOINT.format(article_type=article_type)
-
-    try:
-        response = requests.get(endpoint)
-        response.raise_for_status()
-        return response.json()
-
-    except RequestException as e:
-        print(f"An error occurred: {e}")
-        return None

This function: sources a URL from an environment variable, interpolates a query string into the URL (which comes in as a parameter), makes a request to the URL, and returns the response as JSON.

It has some safeguards in place:

  • It checks that the environment variable is set
  • It checks that the request was successful

In the example we could use a Mock object to simulate the response from the Pocket API. This would allow us to test the function without having to make a real request to the API:

def test_successful_request():
-    # Replace the requests.get function with a Mock object (mock_get)
-    with patch("requests.get") as mock_get:
-        # Specify the return value of the mock_get object)
-        mock_get.return_value = Mock(ok=true)
-        mock_get.return_value.json.return_value = {"value": "test"}
-
-        # Call the function under test
-        result = get_articles("gaby")
-
-    # Assert expected outcomes
-    mock_get.assert_called_once_with(endpoint)
-    assert result == mock_json_response

The example above follows the Arrange, Act, Assert pattern:

StageAction
ArrangeReplace the requests.get function with patch and set properties with Mock
ActCall the function under test
AssertAssert that the function under test behaved as expected

Alternative mock syntax

The with patch(...) as mock_name syntax is fine for small-scale mocking but can become cumbersome when you are mocking several dependencies.

There is another syntax (which I actually find clearer). Say we have a function with three dependencies: update_worksheet, process_articles, get_articles. We could mock like so:

@patch("app.update_worksheet")
-@patch("app.process_articles")
-@patch("app.get_articles")
-def test_success(
-    mock_get_articles, mock_process_articles, mock_update_worksheet
-):
-    mock_get_articles.return_value = [1, 2, 3]

Here the patching is done by the decorator and the mocks are defined as parameters to the test function (always in reverse order)

Mock assertion lexicon

return_value

State what the mock should return

my_mocked_function.return_value = ['one', 'two', 'three']

call_count

Test how many times a dependent function is called

assert my_mocked_function.call_count = 3

assert_any_call()

Test that a given mock is called at least once during the execution of the function under test

my_mocked_function.assert_any_call(some_mocked_return_value)

When the output of one function is used as a parameter to another, and we don’t particularly care about the details of what is concerned we can just pass the executed function, e.g:

my_mocked_function.assert_any_call(preceding_function())

call_args_list

Get a list of all the arguments that a mock object was called with during the test.

call_args_list is useful when you want to check the arguments that a mock object was called with during the test, especially if the mock object was called multiple times with different arguments. You can use it to inspect the arguments of each call and make assertions based on them.

second_my_mocked_function_call = my_mocked_function.call_args_list[1]
-
-# check the first argument of the second call:
-
-assert second_my_mocked_function_call[0][0] == "expected arg"

side_effect

Use to trigger a side effect when returning a value from a mock. Most useful for mocking exceptions.

my_mocked_function.side_effect = Exception("Some exception raised")

Testing exceptions with raises

Testing exceptions is quite straightforward. You can use the raises helper provided by pytest, and combine this with excinfo (“exception info”) to inspect the exception message.

if POCKET_LAMBDA_ENDPOINT is None:
-    raise ValueError(
-        "Error: POCKET_LAMBDA_ENDPOINT environment variable is not set"
-    )

Then to test this, we would use pytest’s excinfo fixture along with raises:

 with pytest.raises(ValueError) as excinfo:  # Watch for the ValueError
-    get_articles("some_type")
-
-    assert "Error: POCKET_LAMBDA_ENDPOINT environment variable is not set" in str(
-        excinfo.value
-    )

We could actually simplify the above test by using the match parameter with raise. This way we do not need the separate assertion:

with pytest.raises(ValueError, match="Error: POCKET_LAMBDA_ENDPOINT environment variable is not set"):
-    get_articles("some_type")

Note that excinfo is best used for testing the exception text that you the developer explicitly raise. For exceptions tha may occur naturaly in the code you are testing, you should use caplog or capsys (see below).

Before-each and after-each

When testing functions, we achieve this in Python using setup_function and teardown_function methods. These methods are called before and after each test method respectively.

To apply a “before each” to every test just put your setup function and/or teardown function at the top level of your test module.

For example, below we set and remove an env var before and after each test:

@pytest.fixture(scope="function") # specify that this fixture should be run before each function test
-def setup_function():
-    print("Setting up test environment...")
-    os.environ["POCKET_LAMBDA_ENDPOINT"] = "https://some_endpoint.com/{article_type}"
-
-
-def teardown_function():
-    print("Tearing down test environment...")
-    del os.environ["POCKET_LAMBDA_ENDPOINT"]

If the setup/teardown should only be applied to a subset of tests, just pass the name of the fixture as a parameter to the test function:

def some_function(setup_function):
-    # setup_function will be run before this test

You don’t need to use the names setup_function and teardown_function so long as you are passing the fixture as a parameter.

You can also use yield to combine the setup and teardown into a single function:

@pytest.fixture(scope="function")
-def setup_function():
-    os.environ["POCKET_LAMBDA_ENDPOINT"] = "https://some_endpoint.com/{article_type}"
-    yield
-    del os.environ["POCKET_LAMBDA_ENDPOINT"]

Another example:

The following test suite uses the same three mocked functions in every test. The following set-up assigns the mocks before each test and resets after each individual test has run:

@pytest.fixture(scope="function")
-def setup_function():
-    with patch("app.get_articles") as mock_get_articles, patch(
-        "app.process_articles"
-    ) as mock_process_articles, patch("app.update_worksheet") as mock_update_worksheet:
-        yield mock_get_articles, mock_process_articles, mock_update_worksheet

Then to use:

def individual_test(setup_function):
-    mock_get_articles, mock_process_articles, mock_update_worksheet = setup_function
-    # Now each mock can be referenced using the vars above
-

Parameterized tests

For a sequence of tests that are repetitive, to avoid repeating the same code over and over again, we can use parameterized tests. This is where we pass in a list of parameters to the test function and the test function is run once for each parameter.

For example, in the function below I am handling numerous possible Exceptions that could be raised by the requests.get method:

    try:
-        response = requests.get(endpoint)
-        response.raise_for_status()
-        return response.json()
-
-    except HTTPError as http_err:
-        logging.error(f"HTTP Error occurred: {http_err}")
-
-    except ConnectionError as conn_err:
-        logging.error(f"Connection Error occurred: {conn_err}")
-
-    except Timeout as timeout_err:
-        logging.error(f"Timeout Error occurred: {timeout_err}")
-
-    except RequestException as e:
-        logging.error(f"Request Exception occurred: {e}")
-
-    return None

Instead of writing something like the following for each of the four exceptions:


- def test_exception_generic(caplog):
-    with patch("requests.get", side_effect=RequestException("Some error")):
-        result = get_articles("some_type")
-
-    assert "Request Exception occurred" in caplog.text
-    assert result is None

I could parameterize like so:

@pytest.mark.parametrize(
-    "exception_type, log_message",
-    [
-        (RequestException, "Request Exception occurred: "),
-        (HTTPError, "HTTP Error occurred: "),
-        (Timeout, "Timeout Error occurred: "),
-        (ConnectionError, "Connection Error occurred: "),
-    ],
-)
-def test_exceptions(caplog, exception_type, log_message):
-    with patch("requests.get", side_effect=exception_type("Some error")):
-        result = get_articles("some_type")
-
-    assert log_message in caplog.text
-    assert result is None

Caplog, syslog, excinfo

caplog and capsys are built-in pytest fixtures. caplog lets you test log messages. capsys lets you test stdout and stderr. As such they are very useful when testing that error messages are logged correctly.

caplog

In our example, if the endpoing environment is not set, we log an error message. We can test that this message is logged correctly using caplog:

def test_no_endpoint_env_var(caplog):
-    os.environ.pop("POCKET_LAMBDA_ENDPOINT", None)  # Remove env variable if it exists
-
-    with caplog.at_level(logging.ERROR):
-        result = get_articles("some_type")
-
-    assert (
-        "Error: POCKET_LAMBDA_ENDPOINT environment variable is not set" in caplog.text
-    )
-    assert result is None

Note tha we pass in caplog as a parameter to the test function. This is how pytest knows to use it as a fixture.

capsys

In our example, if the request is unsuccessful, we log an error message with print rather than logging. We can test that this message is printed correctly using capsys to check the stdout:

def test_http_error(capsys):
-    with patch("requests.get") as mock_get:
-        mock_get.return_value = Mock(ok=False, status_code=404)
-
-        # Raise an HTTP error when raise_for_status is called
-        mock_get.return_value.raise_for_status.side_effect = RequestException()
-
-        result = get_articles("some_type")
-
-    captured = capsys.readouterr()
-    assert "An error occurred" in captured.out

excinfo

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Testing_with_Jest.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Testing_with_Jest.html deleted file mode 100644 index cd95827..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Testing_with_Jest.html +++ /dev/null @@ -1,316 +0,0 @@ -Testing with Jest - My Zettelkasten - - - - -

Testing with Jest

Mocking classes/modules

Classes

Let’ say we have this class:

// database.js
-class Database {
-  connect() {}
-  save(data) {}
-}

Then to mock:

import Database from "./database";
-
-// This will mock the whole Database class, replacing all methods with jest mock functions.
-jest.mock("./database");
-
-test("should use mocked save method", () => {
-  const dbInstance = new Database();
-
-  // Mocking the save method with a specific return value
-  dbInstance.save.mockReturnValue(true);
-
-  const result = dbInstance.save({ key: "value" });
-
-  expect(result).toBe(true);
-  expect(dbInstance.save).toHaveBeenCalledWith({ key: "value" });
-
-  // The connect method is still a mock function (but without a specific behavior).
-  dbInstance.connect();
-  expect(dbInstance.connect).toHaveBeenCalled();
-});

Modules

Say we have the following module file:

// utils.js
-export const doSomething = () => {
-  // ...
-};
-
-export const fetchUserData = async (userId) => {
-  const response = await axios.get(`/api/users/${userId}`);
-  return response.data;
-};

Mocked:

jest.mock("./utils", () => {
-  return {
-    doSomething: jest.fn(() => "mocked doSomething"),
-    fetchUserData: jest.fn((userId) =>
-      Promise.resolve({ id: userId, name: "Mock User" })
-    ),
-  };
-});
-
-test("should use mocked module functions", () => {
-  expect(utils.doSomething()).toBe("mocked doSomething");
-  expect(utils.doSomething).toHaveBeenCalled();
-
-  const result = await utils.fetchUserData(123);
-
-  expect(result).toEqual({ id: 123, name: "Mock User" });
-  expect(utils.fetchUserData).toHaveBeenCalledWith(123);
-
-});

Inline mocking versus “per test” mocking

There are two different architectures that we can use when mocking modules and classes: inline and per test mocking.

Here is the inline case:

jest.mock("./some_module.js", () => {
-  return {
-    someFunction: jest.fn(() => "value"),
-    someFunctionWithParam: jest.fn((param) => ({
-      property: param,
-    })),
-    someAsyncFunction: jest.fn(() => Promise.resolve("value")),
-  };
-});

Here is the per test case:

import { someModule } from "./some_module.js";
-
-let someModuleMock;
-
-someModuleMock = {
-  someFunction: jest.fn(() => "value"),
-  someFunctionWithParam: jest.fn((param) => ({
-    property: param,
-  })),
-  someAsyncFunction: jest.fn(() => Promise.resolve("value")),
-};
-
-someModule.mockImplementation(() => someModuleMock);
-
-it("should do something", () => {
-  const newValue = "new value";
-  someModule.someFunction.mockReturnValue(newValue);
-});

The benefits of inline:

  • Inline is good because everything is set up in one place
  • Inline keeps consistency accross tests: every test case in the file will use the same mocked function unless overwritten within a test
  • It lends itself to being a global mock that can be used accross test files in a __mocks__/ directory

The benefits of per-test:

  • You can very mock implementations within the file, providing more granular control. You can redefine someModuleMock or parts of it (someModule.someFunction) throughout your test file to accomodate varied requirements between tests
  • It’s beneficial when your tests have divergent requirements, as you can perform more detailed setups and overrides for each individual test case or suite, ensuring mocks are configured exactly as required.

Overriding inline mocks

Per test mocking makes it straightforward to change the test parameters of the mocked module or class but you can also override inline mocks.

If we were using the someModule inline mock and we wanted to override the someFunction function that we have defined inline, we would first import the someFunction function and then use mockImplementation against it:

import { someFunction } from "./some_module.js";
-someFunction.mockImplementation(() => "custom value");
-expect(someFunction()).toBe("custom value");
-
-// Optional: Restore the original mock implementation after the test
-someFunction.mockRestore();

Note: although we are importing someFunction we are not actually importing the real function tha belongs to the module. Because Jest mocks all of its properties and methods with the inline syntax, we are actually just importing that which Jest has aready mocked, but the syntax is a bit misleading.

Applied to classes

The same approaches (with minor differences) can be used with classes:

Using inline (where the class is not the default export):

jest.mock("./SomeClass", () => {
-  return {
-    SomeClass: jest.fn().mockImplementation(() => {
-      return {
-        someFunction: jest.fn(() => "value"),
-        someFunctionWithParam: jest.fn((param) => ({ property: param })),
-        someAsyncFunction: jest.fn(() => Promise.resolve("value")),
-        someOtherFunctionThatResolves: jest.fn().mockResolvedValue("some data"),
-      };
-    }),
-  };
-});

Using per test:

import SomeClass from "./someClass";
-
-jest.mock("./someClass");
-
-let someClassMock = {
-  someFunction: jest.fn(() => "value"),
-  someFunctionWithParam: jest.fn((param) => ({ property: param })),
-  someAsyncFunction: jest.fn(() => Promise.resolve("value")),
-};
-
-// Mock class implementation
-SomeClass.mockImplementation(() => someClassMock);
-
-it("should do something", () => {
-  const newValue = "new value";
-  someClassMock.someFunction.mockReturnValue(newValue);
-});

Check that a function has been called within another function

function toBeCalledFunction() {
-  console.log("Original function called");
-}
-
-function callerFunction() {
-  toBeCalledFunction();
-}
test("spy on toBeCalledFunction", () => {
-  const spy = jest.spyOn(global, "toBeCalledFunction"); // Replace `global` with the appropriate object/context if the function is not global
-  callerFunction();
-  expect(spy).toHaveBeenCalled();
-  spy.mockRestore(); // Restore the original function after spying
-});

Mock a function that needs to resolve to something within another function

We have two functions, one that gets data and another that processes it. We want to mock the function that gets data and return a value that the processing function can use.

async function getData() {
-  // ... Fetch some data from an API or database
-  return fetchedData;
-}
-
-async function processData() {
-  const data = await getData();
-  // ... Process the data
-  return processedData;
-}

The mocking part:

const mockData = { key: "value" }; // Mocked data
-
-jest.mock("./path-to-file-where-getData-is", () => ({
-  getData: jest.fn().mockResolvedValue(mockData),
-}));
-
-test("test processData function", async () => {
-  const result = await processData();
-  // Now, result contains the processed version of mockData
-  expect(result).toEqual(/* expected processed data based on mockData */);
-});

We could also combine the above with a spy to check that the getData function was called:

const getDataSpy = jest
-  .spyOn(moduleContainingGetData, "getData")
-  .mockResolvedValue(mockData);
-
-const result = await processData();
-expect(getDataSpy).toHaveBeenCalled();
-expect(result).toEqual(/* expected processed data based on mockData */);
-getDataSpy.mockRestore();

Mock a function that takes arguments

function addPrefix(str) {
-  return `prefix-${str}`;
-}
test("dynamic mock for addPrefix function", () => {
-  const mockFunction = jest.fn((str) => `mock-${str}`);
-
-  // Example usage of mockFunction
-  const result1 = mockFunction("test");
-  const result2 = mockFunction("example");
-
-  expect(result1).toBe("mock-test");
-  expect(result2).toBe("mock-example");
-});

Mocking network requests

Mocking Axios

jest.mock("axios", () => ({
-  get: jest.fn().mockResolvedValue(mockData),
-  post: jest.fn().mockResolvedValue(mockData),
-}));

Or we could implement this way:

jest.mock("axios");
-axios.get.mockResolvedValue({ data: "mockedData" });
-axios.post.mockResolvedValue({ data: "mockedData" });

Then we can use the mocked axios functions in our tests:

const result = await fetchData(); // the function that uses Axios `get``
-expect(result).toBe("mockedGetData");
-
-const result = await sendData({ key: "value" }); // the function tha uses Axios `post`
-expect(result).toBe("mockedPostData");

mockImplementation

For more configurable cases we can use mockImplementation:

it("sends data", async () => {
-  // Mock axios.post using mockImplementation
-  axios.post.mockImplementation((url, data) => {
-    if (data.key === "value") {
-      return Promise.resolve({ data: "mockedPostData" });
-    } else {
-      return Promise.reject({ error: "An error occurred" });
-    }
-  });
-
-  const result = await sendData({ key: "value" });
-
-  expect(result).toBe("mockedPostData");
-});

If we want to change the get and post values in different tests, we can do so by using mockImplementation:

Mocking exceptions

Again we use mockImplementation:

Say we have the following function:

// fetchData.js
-import axios from "axios";
-
-const fetchData = async (url) => {
-  try {
-    const response = await axios.get(url);
-    return response.data;
-  } catch (error) {
-    throw new Error("Error fetching data");
-  }
-};
-
-export default fetchData;

We would mock the success and the error as follows:

import axios from "axios";
-import fetchData from "./fetchData";
-
-jest.mock("axios");
-
-describe("fetchData", () => {
-  it("fetches data successfully", async () => {
-    axios.get.mockResolvedValue({ data: "mockedData" });
-
-    const result = await fetchData("https://api.example.com/data");
-
-    expect(result).toBe("mockedData");
-  });
-
-  it("throws an error when fetching fails", async () => {
-    axios.get.mockImplementation(() => {
-      throw new Error("API error");
-    });
-
-    // We use an asynchronous assertion here because we're expecting a promise to reject
-    await expect(fetchData("https://api.example.com/data")).rejects.toThrow(
-      "Error fetching data"
-    );
-  });
-});

Parameterization

The following offers a good opportunity for parameterisation:

it("should return page for deletion from `ipages-live`", async () => {
-  // preview = false, isInternal = false
-  await deletePageFromS3("url", false, false);
-  const deleteObjectCommand = s3ClientMock.calls()[0].args[0];
-  expect(deleteObjectCommand.input).toEqual({
-    Bucket: "bbc-ise-ipages-live",
-    Key: "url/index.html",
-  });
-});
-
-it("should return page for deletion from `preview`", async () => {
-  // preview = true, isInternal = false
-  await deletePageFromS3("url", true, false);
-  const deleteObjectCommand = s3ClientMock.calls()[0].args[0];
-  expect(deleteObjectCommand.input).toEqual({
-    Bucket: "staff.bbc.com-preview",
-    Key: "preview/url/index.html",
-  });
-});
-
-...

Each time we are passing in three parameters to the deletePageFromS3 function which is the object under test. Each time there are different variations in the object that is output.

To parameterize the process rather than use repeated it blocks we can combine the input paramters and outputs into an array:

const testParams = [
-  {
-    preview: false,
-    isInternal: false,
-    bucket: "ipages-live",
-    key: "url/index.html",
-  },
-  {
-    preview: true,
-    isInternal: false,
-    bucket: "staff.com-preview",
-    key: "preview/url/index.html",
-  },
-];

Then use it.each to loop through all possible parameter combinations:

it.each(testParams)(
-  "should return page for deletion from %s",
-  async ({ preview, isInternal, bucket, key }) => {
-    await deletePageFromS3("url", preview, isInternal);
-    const deleteObjectCommand = s3ClientMock.calls()[0].args[0];
-    expect(deleteObjectCommand.input).toEqual({
-      Bucket: bucket,
-      Key: key,
-    });
-  }
-);

This uses the %s variable to print the parameters from each test, which outputs:

  ✓ should return page for deletion from {
-  preview: false,
-  isInternal: false,
-  bucket: 'ipages-live',
-  key: 'url/index.html'
-} (1 ms)
-    ✓ should return page for deletion from {
-  preview: true,
-  isInternal: false,
-  bucket: 'staff.com-preview',
-  key: 'preview/url/index.html'
-}
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Text_manipulation_in_Bash.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Text_manipulation_in_Bash.html deleted file mode 100644 index 05d7cb8..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Text_manipulation_in_Bash.html +++ /dev/null @@ -1,50 +0,0 @@ -Text manipulation - My Zettelkasten - - - - -

Text manipulation

Sorting strings: sort

If you have a .txt file containing text strings, each on a new line you can use the sort function to quickly put them in alphabetical order:

sort file.txt

Note that this will not save the sort, it only presents it as a standard output. To save the sort you need to direct the sort to a file in the standard way:

sort file.txt > output.txt

Options

  • -r
    • reverse sort
  • c
    • check if file is already sorted. If not, it will highlight the strings which are not sorted

Find and replace: sed

The sed programme can be used to implement find and replace procedures. In sed, find and replace are covered by the substitution option: /s :

sed ‘s/word/replacement word/’ file.txt

This however will only change the first instance of word to be replaced, in order to apply to every instance you need to add the global option: -g .

As sed is a stream editor, any changes you make using it, will only occur within the standard output , they will not be saved to file. In order to save to file you need to specify a new file output (using > output.txt) in addition to the original file. This hasthe benefit of leaving the original file untouched whilst ensuring the desired outcome is stored permanently.

Alternatively, you can use the -i option which will make the changes take place in the source file as well as in standard input.

Note that this will overwrite the original version of the file and it cannot be regained. If this is an issue then it is recommended to include a backup command in the overall argument like so:

sed -i.bak ‘s/word/replacement word/’ file.txt

This will create the file file.txt.bak in the directory you are working within which is the original file before the replacement was carried out.

Remove duplicates

We can use the sort -u command can be used to remove duplicates:

sort -u file.txt

It is important to sort before attempting to remove duplicates since the -u flag works on the basis of the strings being adjacent.

Split a large file into multiple smaller files: split

Suppose you have a file containing 1000 lines. You want to break the file up into five separate files, each containing two hundred lines. You can use split to accomplish this, like so:

split -l 200 big-file.txt new-files

split will categorise the resulting five files as follows:

  • new-file-aa,
  • new-file-ab
  • new-file-ac,
  • newfile-ad,
  • new-file-ae.

If you would rather have numeric suffixes, use the option -d . You can also split a file by its number of bytes, using the option -b and specifying a constituent file size.

Merge multiple files into one with cat

We can use cat read multiple files at once and then append a redirect to save them to a file:

cat file_a.txt file_b.txt file_c.txt > merged-file.txt

Count lines, words, etc: wc

To count words:

wc file.txt

When we use the command three numbers are outputted, in order: lines, words, bytes.

You can use modifiers to get just one of the numbers: -l, -w , -b .

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/The_History_of_Computing_Swade.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/The_History_of_Computing_Swade.html deleted file mode 100644 index 4d44cb4..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/The_History_of_Computing_Swade.html +++ /dev/null @@ -1,50 +0,0 @@ -History of Computing (Swade, 2022 ) - My Zettelkasten - - - - -

History of Computing (Swade, 2022 )

TitleAuthorPublication dateResource type
The History of Computing: A Very Short IntroductionDoron Swade2022Book

Timeline

A typical timeline approach rooted in major innovations.

  • Ancient aids to counting: knotted cords and notched sticks
  • Ancient aids to calculation: counting boards and abacii
  • Early mechanical calculator devices in the 17th century (number wheels, Pascal, Leibniz)
  • Modern aids to calculation: slide rules following the discovery of logarithms
  • Mechanised, automated calculating engines of Babbage in the 19th century
  • Punched-card machines leading to IBM in the early 20th century
  • Analogue and electro-mechanical computers of the early 20th century inclusive of wartime computers
  • Early valve-based (vacuum-tubed) digital computers (again wartime and early Cold War)
  • The invention of the transistor and first fully-digital computers
  • The invention of integrated_circuits
  • Supercomputers
  • Minicomputers
  • Consumer personal computers
  • Internet and later, Web
  • Smart phones

First three phases of digital electronic computers:

  • Wartime up to 1950s vacuum-tube era
  • Transistor era up to 1963
  • First microchip era ending in early 1970s

Terms

TermDefinition
automaticcan execute programs, process data and perform functions on its own once it has been started. Can monitor its own processes and make adjustments without human intervention
general-purposea computer designed to be able to solve a wide variety of problems and perform many different types of tasks as opposed to a computer built for a specific, limited purpose
programmablethe ability to change the operations a computer peforms without physically altering its hardware

Mechanical calculating devices in the 17th century

Focus was chiefly on creating a desktop calculator capable of four-function arithmetic.

Photograph of Pascaline

Photograph of replica of Leibniz stepped drum machine

The main contenders were the Pascaline of #Pascal (which only did cumulative addition) and the wheel or “stepped drum” calculator of #Leibniz that could do all operations (in theory).

Subsequent designs were based on these artefacts. In practice, neither worked consistently well with the carriage of tens remaining a sticking point.

Photograph of Arithmometer

Photograph of Comptometer

The arithmometer (crank driven) and comptometer (key-driven) were descendents of the Leibniz design that became commercially viable by the 19th century along with other mechanical calculators. In the US, Burroughs dominated the market.

Babbage: mechanized, automated calculation

I wish to God these calculations had been executed by Steam (#Babbage)

With Babbage’s machines we see an approach to computation that can only be understood against the backdrop of the Industrial Revolution in which they were conceived.

The idea is that the machine is a factory and number is the product. In the same way as the mechanised looms created textiles. It is the extension of a model of industrial production from goods/commodities to information.

Babbage conceived two machines: the Difference Engine (DE) and the Analytical Engine (AE). Neither were successfully built in his lifetime. The DE preceded the AE and was basically an advanced mechanical calculator whereas the AE approximated a general purpose computer.

Despite this, with the Difference Engine, in contrast to preceding aids to calculation, the steps of the computational algorithm were no longer directed by human intelligence but by internal rules embodied in the mechanism and automatically generated.

Difference Engine

The DE’s single purpose was to calculate and output mathematical tables such as the results of polynomial equations. The idea was that you would input the answer a bell would ring and the machine would halt. This influenced #Turing later. It was non-programmable and designed for a specific set of calculations.

Analytical Engine

Conceived as a general-purpose computing machine capable of perfoming a wide range of calculations, programmable using punched cards similar to those used with Jacquard looms.

It more resembled modern computers in that Babbage used concepts that would later translate into the #vonNeumann architecture. There was a “mill” (CPU), “store” (memory) and input/output mechanisms. It also had a concept of looping and conditional branching.

Lovelace’s insight

A central idea of Ada #Lovelace, expressed in her notes on the Analytical Engine is that number can represent entities other than quantity.

If we assign meaning to number, results arrived at by operating on number according to rules can say things about the world when mapped back onto the world using the meanings assigned to them.

Lovelace’s insight was that the potential of computing lay in the power of machines to manipulate representations of the world contained in symbols.

Analogue computers

Both digital and analogue computers are automatic. They differ in how they represent quantities and how their outputs are derived.

With digital machines, quantity is represented as a string of discrete digits.

With analogue machines, quantity is a physical property in itself rather than a representation. This could be, for example: the lowering of a weight, the flow of a liquid, or an electrical charge. This physical behaviour is analagous to the system that is being modelled. Quantities are continuously variable values rather than discrete (discontinuous values).

Digital machines produce results by calculation whereas analogue machines produce results by measurement, e.g. the height of liquid in a tank or the time it taks for a tank to be emptied.

Examples of analogue computers

The Phillips Hydraulic Computer

This used fluid to model the workings of the British economy. It consisted of a series of transparent plastic tanks and pipes which were fastened to a wooden board.

Philips Hydraulic Computer

Each tank represented some aspect of the UK national economy and the flow of money around the economy was illustrated by coloured water. At the top of the board was a large tank called the treasury. Water (representing money) flowed from the treasury to other tanks representing the various ways in which a country could spend its money. For example, there were tanks for health and education. To increase spending on health care a tap could be opened to drain water from the treasury to the tank which represented health spending.

Bush’s Differential Analyser

This was designed to solve differential equations by integration. In contrast to the Philips Computer it was general enough to be used to solve problems from different contexts. Examples of these contexts: heat flow, ballistics, mechanics, population growth, chemical interactions, astronomy.

Differential Analyser

It was about the size of a room and used shafts, motors, discs and wheels to work.

Historiography

There is a tendency in the history of computing to downplay or diminish the contribution of analogue computing devices and to present them as just an inferior precursor to the inevitable dominance of digital electronic computers.

This is ahistorical and inaccurate.

Analogue (and electromechanical devices) overlapped with and coexisted with digital devices for 40 years, spanning the first three generations of digital electronic devices. The term “analogue” itself only came about when the need arose to distinguish digital devices from other types of computer. They were not “rivals” before this.

Electro-mechanical computers

Electro-mechanical devices (also known as “electronic analogue computers”) are a sort of midway between full digital devices and analogue computers, forming a bridge between the two eras.

Their heyday was roughly 1935 - 1945.

Their key components were:

  • relays for logic operations
  • rotating shafts and gears for performing calculations
  • punched cards or paper tape for input instructions and outputs

They were slower than fully digital computers as they were limited by the speed of moving components rather than the flow of electric charge. In addition the various mechanical parts were prone to wear and needed frequent replacement.

Examples of electro-mechanical computers

Harvard Mark 1 (1937-1944) - Aikin, IBM

Designed by Howard Aiken and built by IBM (1937-1944). Also known as the Automatic Sequence Controlled Calculator (ASCC). A general-purpose electro-mechanical computer it was most famously used at Los Alamos by #vonNeumann to calculate the blast yield of the atomic bomb.

Harvard Mark One

It was more than 15m in length and weighed 5 tonnes comprising over 750,000 parts. It used paper tape and punched cards for input/output.

Complex Number Calculator (1940) - Bell Labs, Stibitz

Not general purpose nor was it programmable. It was hardwired to perform a specific set of operations on numbers and nothing else. It used relays like the others. Its distinguishing feature was that it used a teletype for input rather than cards or paper tape.

Calculating panel of the CMC

Teletype input of CMC

It comprised a panel (the calculating unit) and teletype (the input). One could remotely access the computer from the teletype in another location, providing it was connected to Bell Lab’s telephone network.

Z3 (1941) - Konrad Zuse

Z3

First designed in 1938 and completed in 1941. Considered the first fully automatic, programmable digital computer although relay-based. Programs were stored on external punched tape and binary was used as the number system. Destroyed by Allied bombing in the War but a replica (pictured) was built in 1998.

Vacuum-tube devices

Vacuum-tube devices were the first fully electronic digital devices as they used vacuum-tubes for implementing binary logic rather than relay switches.

Canonical examples from this era are the ABC computer, the Collossus and most famously, the ENIAC.

The Antanasoff-Berry Computer (1939 - 1942)

ABC Computer

Fully automatic, digital electronic computer but not programmable or really general-purpose, being created to do linear equations. It took decimal input and output but operated internally using binary arithmetic. The input was punched cards and the output was via a front-panel display.

Its importance stems from the fact that it was the first to use vacuum-tubes for the arithmetic calculations of the processor.

Colossus (1943-1945) - Tommy Flowers/Max Newman

Designed and built at the Post Office Research Station at Dollis Hill. Used for cracking the Lorenz messages of the German high command.

Mainly important (beyond its role in the War) for establishing the viability of vacuum-tubes over relays. It comprised 2.4 thousand tubes.

Debatable the extent to which the Collosus can be called the first digital computer since it was not general purpose and not fully programmable.

Furthermore it was not even a complete solution in its context of application. The codebreakers would be given a certain advantage using the Collosus (narrowing the field of possible deciphering keys) but still need to use manual methods to break the code. It made decipher time shorter rather than executing the full diciphering. In contrast to, say, the Bombe computer that would identify the key for the days transmissions.

It’s actual influence is also hard to gauge because of the secrecy that remained in place after the War. Apart from those who worked on it, its technical advancements were not public knowledge until the late 1970s.

ENIAC (1945) John Mauchly/J.P Eckert

The Electronic Numerical Calculator and Integrator

The main motivation for creating the ENIAC was military: the US Army needed speed and accuracy when calculating artiliary firing tables and munition trajectory so that shells could hit their intended targets. Accuracy depended on myriad factors: gun elevation, shell shape and weight, explosive charge, distance, wind, temperature etc. Previously this had been done by human computers under the aegis of the Ballistic Research Laboratory.

The main control panel of the ENIAC

It was not completed until after VE day but was used at Los Alamos after the War and retired in 1955.

The BRL commissioned the Moore School of Engineering at the University of Pennsylvania for the construction of an automatic electronic calculator.

It used vacuum-tubes, along with switches and realys. It used decimal rather than binary and had punch card input and output. It was crudely programmable and could be set up to work on different problems by rearranging the different components using switches and plugboards. But this took roughly two days.

It’s design was very influential because it was made public and not classified.

EDVAC (1944-49) John Mauchly/J.P Eckert/ John von Neumann

Built at the Moore School for the BRL as a successor to ENIAC by Mauchly and Eckert whilst ENIAC was still operational. It’s architecture arose out of discussions between #vonNeumann and Mauchly and Eckert and was necessitated by the need to calculate the behaviour of the fissile materials in the atomic bomb.

It resulted in the famous First Draft of a Report on the EDVAC by #vonNeumann which is seen as the definitive statement of the modern digital programmable general-purpose computer.

As a result of the paper, #vonNeumann effectively got the credit for the invention even though it synthesised ideas from the ENIAC and the contributions of others to the EDVAC.

There was lots of disputed provenance and claims of plagiarism generally. Antanasoff won a legal claim against Eckert and Mauchly for stealing ideas from the ABC to make ENIAC.

// Add more on the hardware.

Concept of the internal stored program

  • Key innovation of the EDVAC was the internal stored program (ISP).

  • Solution to the problem of preceding computers requiring down-time when switching between applications and problem sets.

  • Circuitry would need to be reconfigured before the computer could run on the next problem

  • ISP removed the friction:

    • the instructions comprising the program would be prepared on tape or punched cards and read into electronic memory
    • the hardware configuration of the machine would remain the same accross different programs and require no reconfiguration, only the input program data would change
  • This was basically the invention of software. Both instructions and data shared the same memory space once they were read-in. Before, the data would be stored in memory but the instructions would be read one-by-one from the external storage media.

  • Key consequences:

    • flexibility (no need for re-wiring)
    • speed: fetching instructions from memory is quicker than fetching from external storage devicde
    • self-modification: since they were in memory, programs could modify themselves during their execution (e.g. use branching conditions) and treating one program as data for another. This enabled more complex algorithms and also opened the possibility of higher-level languages and compilers
    • simplified architecture: both programs and data in memory
    • generalisation: computers could switch between different tasks simply by loading different programs

Post-EDVAC devices

There were several notable devices which attempted to implement the architecture described in the First Draft using vacuum tubes for logic operations and a variety of different electronic methods for memory:

  • the Manchester “Baby”
  • the Cambridge EDSAC
  • Turing’s ACE computer

Manchester Baby (1948)

The Manchester Baby Computer

  • An experimental computer intended to create the von Neumann architecture using Williams_Tube_RAM

  • Developed at the Univesity of Manchester and completed in 1948.

  • Considered the first electronic stored-program computer and first to contain all the elements of a modern electronic digital computer.

EDSAC (1949) J.Wilkes et al.

EDSAC

  • Electronic Delay Storge Automatic Computer

  • Constructed by Maurice Wilkes and others at the Mathematical Laboratory of the University of Cambridge.

  • The second digital stored-program computer after the Manchester Baby.

  • It used vacuum-tubes for the arithmetical operations in the ALU and mercury delay line memory for the RAM.

  • Designed to be used by relatively non-specialist practitioners from other university departments who were expected to program it themselves. To this end, a formal programming paradigm was forged for the EDSAC which established the following:

    • subroutines as a library of common procedures available to programmers (e.g. printing a result, reading input tape, program checking, mathematical operations)
    • diagnostics: techniques for verifying program code and its correctness

Programming Digital Electronic Computer book

  • The key players wrote the first textbook on programming in 1951: The Preparation of Programs for an Electronic Digital Computer (Wilkes, Wheeler, and Gill)

The Automatic Computing Engine (ACE) (1946) Alan Turing

  • Technical design provided by Alan #Turing working at the Mathematics Division of the National Physical Laboratory. The product of Turing’s theoretical work in “On Computable Numbers” where he proposes the concept of a Turing_machine and based on his experience with early single-purpose computing devices at Bletchley.

  • Due to secrecy over wartime work, it was hard for get Turing to build a fully electronic implementation since this would disclose advances made during the War. Tommy Flowers was intended to be brought in to build it but again this was scuppered over the classification of wartime technology. Had this not been the case, it is likely it would’ve been seen as on par with the EDVAC in its design, if not dwarfing it.

  • Turing proposed a stored program architecture with high-speed memory. It would be more perfomant than the EDVAC as a result.

The Pilot ACE computer

  • Turing’s actual design was not implemented as it was thought too ambitious given how powerful it would need to be. Instead a smaller prototype was made, the Pilot ACE. It used vacuum-tubes for logic, and mercury delay lines for memory. Data and memory was input via punched cards.

Further applications of the EDSAC architecture

LEO I

  • Built by Lyons Tea Company to manage business affairs (payroll, inventory, stock management)

  • Marked a shift from military and academic contexts for computers to business and data management.

IAS machines

The MANIAC computer

Several machines were built at the Institute for Advanced Study utilising the “von Neumann” architecture and associated advancements such as vacuum-tubes and Williams’ tubes. There was the original IAS machine (1952) as well as the JOHNNIAC (1954) and MANIAC (1956).

Although their purpose was military (Los Alamos), their designs were public and widely studied making them influential outside of academia.

UNIVAC (1951)

UNIVAC_computer

Mauchley and Eckert, who had designed the ENIAC left the Moore School and went into business: Eckert-Mauchley Computer Corporation. This was bought by Remington Rand and in subsequent years became the main competitor to IBM.

In this capacity they built the UNIVAC: Universal Automatic Computer. It’s name being an embodiment of its nature as a general-purpose, electronic digital computer.

It used vacuum-tubes for logic and mercury delay lines for memory. It had multiple means of input/output including: directly via an operator console (basically a typewriter keyboard), magnetic tape for input and output, along with punched cards.

UNIVAC operator console

It was the first computer specifically designed to include business and administrative use. This was underscored by its first client: the US Census Bureau.

A key event was its succesful prediction of the 1952 general election. It correctly predicted a landslide for Eisenhower (against expectations). (This was so unlikely, they actually fudged the data because they thought the machine was way off.) It was a novelty on the results night but it cemented a certain concept of the computer in the public imagination - large, room sized machines with blinking lights.

Swade notes that Eckert and Mauchley effectively launched the US commercial computer industry with the UNIVAC.

IBM

  • First created in 1911 as a merger of four companies all involved in some capacity in business data processing. The most significant of these was the Hollerith Tabulating Machine Company who’s punched card machines had been used in the 1890 census, greatly reducing its collation time

  • Named IBM in 1924

  • UNIVAC represented the encroachment of computing devices into IBM’s market of punched-card based data-processing and effectively put IBM on notice.

  • To attack the threat IBM brought out three crucial machines: the 701, 702 and 650.

  • IBM’s approach to marketing their computers was to emphasise the comfort of continuity over the shock of the new represented by the UNIVAC. IBM had already captured the business market. Their computers would be more of the same, just faster and more powerful than their punched card machines due to the electronics. To this end they initially did not call their devices ‘computers’.

  • IBM were ultimately totally successful in their pivot to the computing market. By 1960 it owned over 70% of the data processing and computer market.

IBM 701 (“Defense Calculator”) (1952)

Control unit of the IBM 701

IBM’s first electronic computer. It directly competed with the UNIVAC for government contracts. It followed the prevailing approach of vaccuum tubes for logic and had a variety of storage methods: Williams tubes, magnetic tape , and magentic drums.

701s were used at Los Alamos and avionics companies. Some were also used to manage payroll in business contexts.

IBM 702 (“Tape Processing Machine”) (1953)

Advertisement for the IBM 702

Focused primarily on business applications and targetted at businesses rather than government contracts. Less powerful than the 701.

IBM 650 (1953)

IBM 650

Low-cost general purpose machine using magnetic drum memory. Marketed as slower but more affordable than the 700 range. It was mass-produced unlike the others which were built for specific customers. It was in fact the first mass-produced computer in the world. It proved the breakout star in IBMs initial line up and sometimes called “IBM’s Model T”.

IBM_650 console panel

IBM offerred 650s to univesities at a 60% discount on the condition that the universities would establish courses in computing. This was shrewd as it meant that a whole generation of engineers and computer scientists learned on 650s and would prefer them in their research. It also created a pool of skilled users that would go on to work at IBM.

Donald Knuth dedicated The Art of Computer Programming to the 650.

It used magnetic drum memory along with vacuum-tubes.

IBM 1401 (1959)

IBM 1401

Another IBM mainframe. Transistors replaced vacuum-tubes. Magnetic core storage replaced magnetic drum storage. It was housed in rectangular light-blue cabinets and the ubiquity of the 1401 in industry earned IBM the moniker ‘Big Blue’.

IBM System/360 (1964)

IBM 360

Named to suggest all-round compatibility - a family of mainframes designed to cover commercial and scientific applications. Considered one of history’s most successful computers.

Up until this point all IBM computers had a programming language unique to the specific processor. At that point there were about seven IBM computer models in active use and they were all incompatible with each other.

IBM 360 promo poster

In contrast the 360 computers all used the same programming language. This meant they were interoperable with each others. Because the there were variants in the 360 ranges, customers could purchase a smaller system knowing they could expand it if their needs grew, without reprogramming their application software.

Magnetic core devices: Whirlwind and SAGE

Two devices that leveraged the new technology of magnetic_core_memory where the Whirlwind and SAGE computers. The ENIAC was also updated to use magnetic cores.

Whirlwind magnetic core memory

The Whirlwind computer (1953) was a flight simulator and the first to use magnetic cores. Crucially was able to operate in realtime for output.

The SAGE computer (Semi-Automatic Ground Environment) emerged as a response to the Soviet acquisition of the atomic bomb in 1949. The Americans realised they needed a much better early warning and air defence system that would allow them to identify bombers in their airspace and dispatch fighters.

To achieve this, it was necessary to detect enemy bombers with radar and compute an interception course. Alterations in the bomber flight path required continuous updates and real-time computation of directions for the responding fighter.

The resulting computer was SAGE (made by IBM) which was modelled on Whirlwind, using magnetic cores. SAGE computers were spread accross the continental US in sectors and managed by NORAD.

SAGE command post

The SAGE system was operation between 1958-1984, receiving continual improvements and updates. In addition to magnetic cores it introduced many technological innovations that influenced computers generally: interactive screens, printed circuit boards, mass-storage devices, digital communication over telephone lines, time-sharing, along with advances in software.

Because so many private companies worked as contractors on SAGE (IBM, Burroughs, Bell Labs, RAND Corp), the military technology (both hardware and software) made its way from the military context to business and consumer computing.

An example of a civilian application of SAGE technology was airline booking systems, where booking reservation data needed to be processed in realtime. IBM worked with American Airlines to introduce this.

Transistor and integrated circuit revolution

The arc of modern computing history (and its main eras) can be presented as

The transistor was invented at Bell Labs in 1947 by William Shockley and others. They were not created with computers in mind. Instead they were first used in hearing aids (1953) and transistor radios (1954).

From the mid-1950s onwards they started being used in military computers.

They had several advantages over vacuum-tubes: they were durable and reliable with no required startup time, they were power efficient and small.

The actual period where transistors alone were supreme in the form of a transistor board was relatively short-lived and rapidly gave way to ICs.

Computers of the transistor era had the following components separate from each other: the transistors, wired connections, resistors and capacitors. Integrated circuits put these all on the same piece of silicon.

They were first manufactured by Fairchild Semiconductor which was an offshoot of Shockley’s Shockley Semiconductor Laboratory.

The initial marked for ICs was military and scientific: the Minuteman ICBM and computers of the Apollo spacecraft. This laid the groundworkd for later commercial use and the personal computer revolution.

Mini-computers

Mini computers did not threaten mainframes but they opened up a new class of user. They were vastly cheaper than a mainframe and only the size of a small fridge.

The main player was DEC (Digital Equipment Corporation) starting in the mid-1960s. The introduced the PDP-8 in 1965 (Programmed Data Processor). The PDP-8 used transisotrs and magnetic core memory. It was affordable to smaller businesses if not yet, consumers.

The PDP-8

The internals were made public and DEC encouraged making the machine extensible by users being permitted to create their own programs and specialised applications. This was a very different culture to IBM where technicians were required and machines were typically leased.

By 1988, DEC was the second largest computer company after IBM. This led to additional companies entering the mini-computer market: Data General, Honeywell, Hewlett-Packard.

Mini-computers died as a category in the mid-1990s in the wake of the PC.

The Personal Computer

The PC emerged out of advances in IC chip design - this was the engine of the PC.

Intel (newly founded by Robert Noyce and Gordon Moore) were charged with making custom chips for a Japanese calculator company. Instead of creating the custom chips, they advised the company to use a general purpose chip that could handle general computing as well as the basic calculator functions. This generic chip - the Intel 4004 - was the microprocessor combined with three other ICs (comprising 2.3k transistors) that comprised the fundamental building blocks of the #vonNeumann architecture.

Intel 4004 chip

However it took until the Apple II in 1977 for the phrase “personal computer” to enter the lexicon and become an identifiable class.

The broader context for this was the computer hobbyists in Silicon Valley/Menlo Park (particularly the Homebrew Club of amateur computer engineers) along with idealistic figures from the 60s counterculture (such as Stuart Brand) who began associating computing technology as a tool of personal liberty and fulfillment.

Microsoft and Apple

The PC “boom” began with the Altair 8800. This was a mail-order kit that required manual assembly. It was released by Micro Instrumentation Telemetry Systems (MITS) in 1975. It couldn’t do much but had expansion capability (memory, teletype interface, casette player for data storage).

Altair 8800

Bill Gates and Paul Allen made a proposal to MITS: they would write software that would allow users to program the Altair in BASIC. They agreed and were prepared to distribute the software. As a result Gates and Allen founded Microsoft in 1975.

Around the same time, Steve Wozniak (member of the Homebrew club) built the Apple I as a single-board hobbyist project. He made this available to buy via mail order and formed Apple with Steve Jobs in 1976 to manage the enterprise.

Apple I

By 1977 they had investment capital and brought out the Apple II. This was sold preassembled with casing and required no soldering. It had expansion slots for third-party vendors to create compatible devices and had colour graphics.

The design of the Apple II was published in Byte in order to invite crowd-sourced plugins and extensions. One of these was the Z-80 softcard which allowed it to run the CP/M OS (created by the company Digital Research) giving ready-made access to software such as a word-processor, spreadsheets and databases.

Apple 2

Other competitors in the PC market at this time were Radioshack’s TRS-80 and the Commodore PET.

IBM

All the while it was hobbyist and tinkerers driving the PC market, IBM had no real interest. When PCSs started being used by businesses and their capacity grew to include typical business applications (databases, spreadsheets) it sensed an incursion into its market.

IBM PC

Thus, in 1981, IBM launched the “IBM Personal Computer” which rapidly became the industry standard. This had the effect of legitimising the concept of a PC. There was overwhelming demand. In their marketing IBM melded home and office use to capture both markets at once.

The internal specification of the IBM PC was freely available (dubbed ‘open architecture’), in contrast to IBM’s business computers, to encourage software expansion. Cards could be created to fit in its expansion slots adding graphics, sound, additional memory and networking capability.

IBM originally contracted Digital Research to create software based on CP/M but this fell through. Microsoft got the deal to supply the OS which became MS-DOS (Microsoft Disk Operating System). Henceforth every PC and PC-clone came with DOS bundled.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/The_Little_Man_computer.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/The_Little_Man_computer.html deleted file mode 100644 index 5d1d0e3..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/The_Little_Man_computer.html +++ /dev/null @@ -1,50 +0,0 @@ -The Little Man Computer - My Zettelkasten - - - - -

The Little Man Computer

The Little Man Computer is a simplified computer that works on Von Neuman principles. It has all the CPU components we have detailed above. It is programmed in machine code but for simplicity it uses the denary rather than the binary number system.

LMC_5.gif

On the left is the instruction set. Each number constitutes and execution routine and the xx stand for the address in RAM that the execution will work on.

Each row of the RAM has a denary address, 1 through to 99. Each address can hold three digits.

  • So the instruction 560 would mean load the number at address 60.
  • The instruction 340 would mean store a datum at address 40

Working through a basic computation

We are going to add two numbers together as a basic example.

  1. First we need to place the two numbers in RAM we are going to use 5 and 3
    • At address 60 we will put the number 5 and at address 61 we will put the number 3
    • We are going to start at address 0 in the top left of the RAM grid
  2. The first instruction will be load address 60 which in the assembly will be 560 . We put this in address 0, our starting point.
  3. This first instruction is now stored in the accumulator.
  4. Now we want to add this number (in the accumulator) to the number in address 61
  5. This second instruction is 161 . We write this in address 1
  6. Finally we want to store the output of the calculation in the RAM, let’s say at address 62
  7. So we store the command 362 at address 2
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/The_PATH.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/The_PATH.html deleted file mode 100644 index ffe8bcc..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/The_PATH.html +++ /dev/null @@ -1,55 +0,0 @@ -The $PATH - My Zettelkasten - - - - -

The $PATH

We know that $PATH is an environment variable. This variable keeps track of directories where executables are found.

Whenever any command is run, the shell looks up the directories contained in the PATH for the target executable file and runs it. We can see this is the case by using the which command which traces the executable of bash commands. Take the echo program:

which echo
-# echo: shell built-in command

Or npm :

which npm
-/home/thomas/.nvm/versions/node/v19.4.0/bin/npm

By default the path will always contain the following locations:

  • /usr/bin
  • /usr/sbin
  • /usr/local/bin
  • /usr/local/sbin
  • /bin
  • /sbin

All the inbuilt terminal programs reside at these locations and most of them are at /usr/bin. This is why they run automatically without error. If you attempt to run a program that doesn’t reside at these locations then you will get an error along the lines of program x is not found in PATH.

Structure of the PATH

/home/thomas/.nvm/versions/node/v19.4.0/bin:
-/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/lib/jvm/default/bin:
-/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl

Adding to the PATH

Only the default directories load to the PATH on every session. How then can we add custom directories to the path without them being lost every time we start a new session? Remember that the user config .bashrc loads on init for every bash session. Therefore, if we set the custom path in this file, it will be created every time we start a session. This is why when you add a new program it often ask you to append a script to the bottom of your .bashrc .

For example, at the bottom of my .zshrc on my work computer I have:

export CHROME_BIN=/mnt/c/Program\\ Files\\ \\(x86\\)/Google/Chrome/Application/chrome.exe

This enables me to access the Chromium binaries from my terminal session (needed for running Angular tests) but it doesn’t add it to the path, it creates an environment variable on every session.

For demonstration, let’s add a user’s desktop directory to the PATH.

First we go to the .bashrc and add the export command. Remember that this is the command for creating a new environment variable:

export PATH="$PATH=:~/Desktop"

We force a reload of the .bashrc with the command:

source ~/.bashrc

Then we can check this directory has been added to the path with an echo

echo $PATH
-...:~/Desktop
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/The_Pragmatic_Programmer_1999.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/The_Pragmatic_Programmer_1999.html deleted file mode 100644 index 42ddc32..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/The_Pragmatic_Programmer_1999.html +++ /dev/null @@ -1,57 +0,0 @@ -The Pragmatic Programmer (Hunt/Thomas, 1999) - My Zettelkasten - - - - -

The Pragmatic Programmer (Hunt/Thomas, 1999)

General

Meyer’s Uniform Access Principle

All services offered by a module should be available through a uniform notation, which does not betray whether they are implemented through storage or through computation

This is a clear recommendation for using getters and setters with classes. You should not see method calls outside of the class, they should appear as properties of the object.

Don’t Repeat Yourself

Every piece of knowledge must have a single, unambiguous, authoritative representation within a system

The Principle of Orthogonality

This notion comes from geometry. Two lines are orthogonal to each other if they form a right-angle when they meet.

Their meeting isn’t the important part. Think of a simple x, y graph:

If you move along one of the lines, your position projected onto the other doesn’t change

In computing this is expressed in terms of decoupling and is implemented through modular, component-based architectures. As much as possible code should be scoped narrowly so that a change in one area does not cause changes in others. By keeping components discrete it is easier to make changes, refactor, improve and extend the codebase.

We want to design components that are self-contained: independent and with a single, well-defined purpose. When components are isolated from one another, you know that you can change one without having to worry about the rest. As long as you don’t change that component’s external interfaces, you can be comfortable that you won’t cause problems that ripple through the entire system.

Benefits of orthogonality: productivity

  • Changes are localised so development time and testing time are reduced
  • Orthogonality promotes reuse: if components have specific, well-defined responsibilities, they can be combined with new components in ways that were not envisioned by their original implementors. The more loosely coupled your systems, the easier they are to reconfigure and reengineer.
  • Assume that one component does M distinct things and another does N things. If they are orthogonal and you combine them, the result does M x N things. However if the two components are not orthogonal, there will be overlap, and the result will do less. You get more functionality per unit effort by combining orthogonal components.

Benefits of orthogonality: reduced risk

  • Diseased sections of code are isolated. If a module is sick, it is less likely to spread the symptoms around the rest of the system.
  • Overall the system is less fragile: make small changes to a particular area and any problems you generate will be restricted to that area.
  • Orthogonal systems are better tested because it is easier to run and design discrete tests on modularised components.

Building a unit test us itself a an interesting test of orthogonality: what does it take to build and link a unit test? Do you have to drag in a large percentage of the rest of the system just to get a test to compile or link? If so, you’ve found a module that is not well decoupled from the rest of the system

Relationship between DRY and orthogonality

With DRY you’re looking to minimize duplication within a system, whereas with orthogonality, you reduce the interdependency among the system’s components. If you use the principle of orthogonality combined closely with the DRY principle, you’ll find that the systems you develop are more flexible, more understandable and easier to debug, test, and maintain.

Reversibility

The principles of orthogonality and DRY result in code that is reversible. This means it is able to change in an agile way when the circumstances of its use and deployment change. This is important because when developing software in a business setting, the best decisions are not always made the first time around. By following the principles it should be relatively easy to change your program’s interfaces, platform and scale. In other words, with the principle of orthogonality and DRY, refactoring becomes less of a chore.

Prototyping and Tracer Bullets

‘Tracer bullets’ are used by the military for night warfare. They are phosphorous bullets that are included in the magazines of guns alongside normal bullets. They are not intended to kill but instead light-up the surrounding area making it easier to see the terrain and target more efficiently.

The authors use the notion of tracer bullets as a metaphor for developing software at the early stages of a project. This is not the same thing as prototyping. A tracer bullet model is useful for building things that haven’t been built before. They exist to ‘shed light’ on the project’s needs and to help the client understand what they want.

They differ from prototypes in that they include integrated overall functionality but in a rough state. Whereas prototypes are more for singular, specific subcomponents of the project. Because tracer bullet models are joined-up in this way, even if they turn out to be inappropriate in some regard, they can be adapted and developed into a better form, without losing the core functionality.

Tracer bullets work because they operate in the same environment and under the same constraints as the real bullets. They get to the target fast, so the gunner gets immediate feedback. And from a practical standpoint they are a relatively cheap solution. To get the same effect in code, we’re looking for something that gets us from a requirement to some aspect of the final system quickly, visibly and repeatably.

Tracer code is not disposable: you write it for keeps. It contains all the error-checking, structuring, documentation and self-checking that a piece of production code has. It simply is not fully functional. However, once you have made an end-to-end connection among the components of your system, you can check how close to the target you are, adjusting as necessary.

Distinguishing from prototyping

Prototyping generates disposable code. Tracer code is lean but complete, and forms part of the skeleton of the final system. Think of prototyping as the reconnaissance and intelligence gathering that takes place before a single tracer bullet is fired.

Design by contract

To understand DBC we have to think of a computational process as involving two stages: the call and the execution of the routine that happens in response to the call (henceforth caller and routine).

  • the caller could be a function expression that invokes a function and passes arguments to it expecting a given output. The function that executes is the routine
  • the caller could be an object instantiation that calls a method belonging to its parent class
  • the caller could be a parent React component that passes props to a child component

Design by contract means specifying clear and inviolable rules detailing what must obtain at both the call stage and the routine stage if the process is to execute.

Every function and method in a software system does something. Before it starts that something, the routine may have some expectation of the state of the world and it may be able to make a statement about the state of the world when it concludes. These expectations are defined in terms of preconditions, postconditions, and invariants. They form that basis of a contract between the caller and the routine. Hence design by contract**.**

Preconditions

Preconditions specify what must be true in order for the routine to be called. In other words, the requirements of the routine. What it needs and what should be the case before it even considers executing the task. A routine should never get called when its preconditions would be violated.

Postconditions

Providing the preconditions are met, this is what the routine is guaranteed to do. In other words: the state of affairs that must obtain after the routine has ran.

Invariants

Once established, the preconditions and postconditions should not change. If they need to change, that is a separate process and contract. In the processing of a routine, the data may be variant relative to the contract, but by the end the overall conditions establish the equilibrium of the contract.

There is an analogue here with functional programming philosophy: the function should always return the same sort of output, without ancillary processes happening, i.e side-effects.

One way to achieve this is to be miserly when setting up the contract, which overlaps with orthogonality. Only specify the minimum return on a contract rather than multiple postconditions. This only increases the likelihood that the contract will be breached at some point. If you need multiple postconditions, spread them out an achieve them in a compositional way, with multiple separate and modular processes.

Be strict in what you will accept before you begin, and promise as little as possible in return. If your contract indicates that you’ll accept anything and promise the world in return, then you’ve got a lot of code to write!

Division of responsibilities

If all the routine’s preconditions are met by the caller, the routine shall guarantee that all postconditions and invariants will be true when it completes.

Note that the emphasis of responsibilities is on the caller.

Imagine that we have a function that returns the count of an array of integers. It is not the job of the count routine to verify that it has been passed integers and then to execute the count. Or, in the event that it is not passed integers, to mutate the data to integers and then execute.

This should be resolved by the caller: it is the responsibility of the caller to pass integers. If it doesn’t, the routine simply crashes or raises an exception. It doesn’t try to accommodate the input because that does not come down on its side of the contract. The caller has failed to meet the preconditions. If, due to some bug, the routine receives integers and fails to output the sum, then it has failed on its side

Example: type checking

An obvious example of this philosophy is when you perform checks or validation within your code (although validation is more of an issue when you are dealing with user data, not your own internal code). For instance using type checking with dynamically-typed languages.

When we use the prop-types library with React we are specifying preconditions: so long at the prop (effectively the caller) passed to the component (effectively the routine) is of type X, the component will render invariantly as R. If the prop is of type Y, an exception will be raised highlighting a breach in the contract.

Another example would be more advanced type checking with Javascript written using Typescript.

The Law of Demeter

Demeter’s Law has applicability chiefly when programming with classes.

It’s a fancy name for a simple principle summarised by ‘don’t talk to strangers’. Demeter’s law is violated when code has more than one step between classes. You should avoid invoking methods of an object returned by another method. You should only use your own methods when dealing with it.

Formal

A method m of object O may only invoke the methods of the following kinds of objects:

  • O itself
  • m’s parameters
  • any objects created or instantiated within m
  • O’s direct component objects (in other words nested objects)
  • a global variable (over and above O) accessible by O, within the scope of m

Model, View, Controller design pattern

The key concept behind the MVC idiom is separating the model from both the GUI that represents it and the controls that manage the view.

  • Model
    • The abstract data model representing the target object
    • The model has no direct knowledge of any views or controllers
  • View
    • A way to interpret the model. It subscribes to changes in the model and logical events from the controller
  • Controller
    • A way to control the view and provide the model with new data. It publishes events to both the model and the view

For comparison, distinguish React from MVC. In React data is unidirectional: the JSX component as controller cannot change the state. The state is passed down to the controller. Also MVC lends itself to separation of technologies: code used to create the View is different from Code that manages Controller and data Model. In React it’s all one integrated system.

Refactoring

Rewriting, reworking, and re-architecting code is collectively known as refactoring

When to refactor

  • Duplication: you’ve discovered a violation of the DRY principle
  • Non-orthogonal design: you’ve discovered some code or design that could be made more orthogonal
  • Outdated knowledge: your knowledge about the problem and you skills at implementing a solution have changed since the code was first written. Update and improve the code to reflect these changes
  • Performance: you need to move functionality from one area of the system to another to improve performance

Tips when refactoring

  • Don’t try to refactor and add new functionality at the same time!
  • Make sure you have good tests before you begin refactoring. Run the tests as you refactor. That way you will know quickly if your changes have broken anything
  • Take short, deliberative steps. Refactoring often involves making many localised changes that result in a larger-scale change.

Testing

Most developers hate testing. They tend to test-gently, subconsciously knowing where the code will break and avoiding the weak spots. Pragmatic Programmers are different. We are driven to find our bugs now, so we don’t have to endure the shame of others finding our bugs later.

Unit testing

A unit test is code that exercises a module. It consists in testing each module in isolation to verify its behaviour. Unit testing is the foundation of all other forms of testing. If the parts don’t work by themselves, they probably won’t work well together. All the modules you are using must pass their own unit tests before you can proceed.

We can think of unit testing as testing against contract (detailed above). We want to test that the module delivers the functionality it promises over a wide range of test cases and boundary conditions.

Scope for unit testing should cover:

  • Obviously, returning the expected value/outcome
  • Ensuring that faulty arguments/ types are rejected and initiate error handling (deliberately breaking your code to ensure it is handled appropriately)
  • Pass in the boundary and maximum value
  • Pass in values between the zero and the maximum expressible argument to cover a range of cases

Benefits of unit testing include:

  • It creates an example to other developers how to use all of the functionality of a given module
  • It is a means to build regression tests which can be used to validate any future changes to the code. In other words, the future changes should pass the older tests to prove they are consistent with the code base

Integration testing

Integration testing shows that the major subsystems that make up the project work and play well with each other.

Integration testing is really just an extension of the unit testing described, only know you’re testing how entire subsystems honour their contracts.

Commenting your code

In general, comments should detail why something is done, its purpose and its goal. The code already shows how it’s done, so commenting on this is redundant, and violates the DRY principle.

We like to see a simple module-level comment, comments for significant data and type declarations, and a brief class and per-method header describing how the function is used and anything it does that is not obvious

/*
-Find the highest value within a specified data range of samples
-
-Parameter: aRange = range of dates to search for data
-Parameter: aThreshold = minimum value to consider
-
-Return: the value, or null if no value found that is greater than or equal to the threshold
-*/
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/The_kernel.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/The_kernel.html deleted file mode 100644 index fef6cb8..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/The_kernel.html +++ /dev/null @@ -1,50 +0,0 @@ -The kernel - My Zettelkasten - - - - -

The kernel

Within the hierarchy of the OS, the kernel acts as the primary mediator between the hardware (CPU, memory) and user processes. Let’s look at each of its responsibilities in greater depth:

  • process management
  • memory management
  • device drivers
  • system calls

Process management

A process is just another name for a running program. Process management is the starting, pausing, resuming, scheduling and terminating of processes.

On modern computers it appears that multiple processes can run simultaneously at once. This is only because the processor is so fast that we do not detect changes. In fact access to the CPU is always sequential. The sequence in which multiple programs are allowed to access the CPU is managed by the kernel.

Consider a system with a one-core CPU. Many processes may be able to use the CPU, but only one process can actually use the CPU at any given time…Each process uses the CPU for a fraction of a second, then pauses, then another process uses it for a fraction of a second and so on… (How Linux Works: Third Edition, Brian Ward 2021)

This process of the CPU shuffling between multiple processes is called context switching.

The role of the kernel in facilitating this, is as follows:

  1. CPU runs process for a time slice based on its internal time. Then hands control back to the kernel (kernel mode)
  2. Kernel records current state of CPU and memory. This is necessary in order to resume the progress that was just interupted.
  3. The kernel executes any tasks that arose in the last timeslice executed by the CPU (e.g. collecting data from I/0)
  4. Kernel then analyses the list of processes that are ready to run next and chooses one.
  5. Kernel prepares memory for this new process and prepares the CPU.
  6. Kernel tells CPU how long the time slice for the new process will last.
  7. Kernel switches the CPU into user mode and hands control of CPU to the process.

Memory management

During the context switch from CPU to user space, the kernel allocates memory. It has the following jobs to manage:

  • Keeping its own private area in memory for itself that user processes cannot access
  • Assigning each user process its own section of memory
  • Managing shared memory between processes and ensuring the private memory of processes is not accessed by others
  • Managing read-only memory
  • Allowing for the use of disk space as auxiliary memory

Modern CPUs include a memory management unit which provides the kernel with virtual memory. In this scenario, memory isn’t directly accessed by the process instead it works on the assumption that is has access to the entire memory of the machine and this is then translated into a map that is applied to the real memory and managed by the kernel.

Device drivers

Devices are managed by the kernal and are not accessible directly via user space, since improper usage could crash the whole machine. There is little uniformity between devices and as a result drivers are needed. Thes are kernl code that enable different OS kernels to access and control the devices.

System calls

Syscalls are what enable programs to start and are required for the acts of opening, reading and writing files. System calls in Linux are typically managed via C.

In Linux there are two particularly important system calls:

  • fork()
    • When a process calls fork, the kernel creates a nearly identical copy of this running process
  • exec()
    • When a process calls exec it passes a program name as a parameter. Then the kernel loads and starts this program, replacing the current process.

Example with a terminal program like ls:

When you enter ls into the terminal window, the shell that’s running inside the terminal window calls fork() to create a copy of the shell, and then the new copy of the shell calls exec(ls) to run ls. (Ibid.)

Controlling processes

In Linux we can view, kill, pause and resume processes using ps.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/The_memory_hierarchy.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/The_memory_hierarchy.html deleted file mode 100644 index e915b39..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/The_memory_hierarchy.html +++ /dev/null @@ -1,50 +0,0 @@ -The memory hierarchy - My Zettelkasten - - - - -

The memory hierarchy

The diagram below compares the different forms of memory within a computing device in terms of speed, monetary cost and capacity:

Memory hierarchy diagram

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Theorems_and_empty_sets.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Theorems_and_empty_sets.html deleted file mode 100644 index 67c9f4f..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Theorems_and_empty_sets.html +++ /dev/null @@ -1,52 +0,0 @@ -Theorems and empty sets - My Zettelkasten - - - - -

Theorems and empty sets

We know that when we construct a derivation we start from a set of assumptions and then attempt to reach a proposition that is a consequence of the starting assumptions. However it does not always have to be the case that the starting set contains members. The set can in fact be empty.

Demonstration

We see in this example that there is no starting set and thus no primary assumptions. Instead we start with nothing other than the proposition we wish to derive. The proposition is effectively derived from itself. In these scenarios we say that we are constructing a derivation from an empty set.

Propositions which possess this property are called theorems:

A proposition \(P\) or a system of propositions in propositional logic is a theorem in a system of derivation for that logic if \(P\) is derivable from the empty set.

We represent a theorem as:

$$ -\vdash P -$$

(There is no preceding \(\Gamma\) as the set is empty. )

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Threads.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Threads.html deleted file mode 100644 index af0120f..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Threads.html +++ /dev/null @@ -1,50 +0,0 @@ -Threads - My Zettelkasten - - - - -

Threads

A process is a running instance of a given program. A program runs sequentially handling one task at a time, however we may need to run certain tasks in parallel.

Think of a program that is downloading a resource from the internet and wants to update the UI at the same time to show the download process.

If the program is strictly sequential, once the program starts the download, the UI is neglected since the CPU time dedicated to the process must be focused elsewhere.

We need the UI update and the download to execute in parallel. This is achieved via operating system threads of execution.

A thread is a schedulable unit of execution within a process. It runs within a process, shares its memory address and can execute any program code loaded within it.

Each thread has an identifier called a thread ID (TID).

Both procesess in user space and the kernel utilise threads.

Hardware considerations

Each processor core can only run one thread at a time so the number of cores that a device’s CPU has deterimines how many threads can run at once. In practice, then, the CPU shuffles between multiple threads in clock segments. This is known as scheduling and is managed by the process that the thread belongs to.

Processes

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Three_bit_counter.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Three_bit_counter.html deleted file mode 100644 index da18b6f..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Three_bit_counter.html +++ /dev/null @@ -1,52 +0,0 @@ -3-bit Counter - My Zettelkasten - - - - -

3-bit Counter

To demonstrate the use of Flip-Flops we will create the circuit for a 3-bit counter. This simply counts up from 0 to 7 because 7 is the maximum decimal number we can create with three bits (\(2^3\)):

BinaryDecimal
0000
0011
0102
0113
1004
1015
1106
1117

The circuit will have three memory components, each representing one bit of the 3-bit number. When the clock pulses, the 3-bit number increments by one. We need to synchronise the operation with a clock because each bit by itself is meaningless, it only gains meaning by the relation it sustains to the other two bits hence it must be kept in sync with them.

We can derive the circuit arrangement by analysing the outputs of a flipflop at each pulse:

Combined bitsQ2Q1Q0Decimal
0000000
0010011
0100102
0110113
1001004
1011015
1101106
1111117

If we look at the pattern of each flip-flops’ output we notice the following:

  • Q0 toggles on every pulse
  • Q1 toggles every time Q0 was previously 1
  • Q2 toggles when both Q1 and Q0 were previously 1

This means that to construct a circuit that displays this behaviour we just have to use a T flip-flop since the only state change we need is a single bit toggle three times that retains its value.

Using these pulse patterns we can construct a circuit as follows:

-
-

Remember from the table: Q2 is the most significant bit and Q0 is the least significant bit so we should read the output in the interactive circuit backwards, reversing the order. Then we will see that the cicuit is cyling through 0-7

This is how the circuit works:

  • All three flip-flops are connected to the same clock signal so that they are synchnonised
  • Because T0 is connected to the voltage source Q0 toggles every time the clock pulses
  • T1 is connected to Q0 so a clock pulse causes Q1 to toggle only when Q0 is high in line with the table
  • T2 is connected to Q0 AND Q1 so Q2 only toggles on a clock pulse when Q0 and Q1 are both high
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Time_and_computers.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Time_and_computers.html deleted file mode 100644 index 061bffd..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Time_and_computers.html +++ /dev/null @@ -1,54 +0,0 @@ -Time and computers - My Zettelkasten - - - - -

Time and computers

Epochs and Unix Time

An epoch is a period of time identified by a starting point.

The standard epoch for measuring against is known colloqially as “Unix Time”: midnight on 1st January 1970. Unix time is the number of seconds that have elapsed since this point. This is the standard for Windows and most unix systems.

For example midnight on 2nd January 1970 would be 86400 seconds since the epoch. The deduction is as follows:

60 * 60 * 24 = 86400

We are multiplpying the number of seconds in a minute by the number of minutes in an hour by the number of hours in a day.

To represent times and dates before 1970, we use negative integers.

UTC and time zones

“Coordinated Universal Time” (UTC) is the time standard against which the world’s timekeeping is synchronized. It is not itself a timezone, it is a transcendent standard that defines what time zones are.

Time zones are defined relative to UTC, by their offset to this value.

For example North America is behind UTC by five or six hours hence uses the notation UTC-5:00 or UTC-6:00.

UTC is the successor to GMT of which there were variances necessitating a universal value. Despite this GMT is equal to UTC+00:00 so apart from when daylight saving is in effect in the UK, GMT = UTC.

Depending on your locale, relative to UTC, you will get different outputs when you attempt to log Unix Time.

Also daylight savings can impact on the outputs. For instance for half of the year, when DST applies, the UK is UTC+01:00.

Examples in Python

The following gives us the unix seconds in my current time zone (GMT DST):

import time
-print(time.time())
-# 1714322393.2929392

If I want UTC, I can do:

import datetime
-print(datetime.datetime.utcnow().strftime('%s'))
-# '1714318952'

We see clearly that they are not identical.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Torrenting.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Torrenting.html deleted file mode 100644 index c2b234d..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Torrenting.html +++ /dev/null @@ -1,50 +0,0 @@ -Torrenting - My Zettelkasten - - - - -

Torrenting

What is torrenting? Is this the same thing as a peer-to-peer network? How do these technologies fit within the client-server paradigm?

Torrenting is a specific application of peer_to_peer_networking applied to file-sharing.

Each peer on the network both consumes resources and makes resources available to others.

Procedure

Large files are divided into small equal sized pieces and each piece is assigned a unique hash identifier. The .torrent file details the number of pieces, their sizes and hash values.

Clients request different pieces from different peers simultaneously. As pieces are received, they are verified against their hash. Corrupted or incorrect pieces are discarded and re-downloaded.

The client software reassembles the pieces in the correct order and the final file will be identical to the original which can be verified by comparing hashes.

Key terms

  • tracker
    • a server that coordinates communication between peers (so there is a server but its role is more lightweight than client-server, coordinating the peers rather than hosting or distributing file content)
  • swarm
    • a group of peers sharing the same file
  • seeding
    • uploading file pieces to other peers
  • leeching
    • downloading file pieces from other peers

An alternative to a tracker server is to use trackerless methods such as distributed hash tables

Terminological clarification

  • BitTorrent is the communications protocols for P2P file sharing. It was also a client software developed by the company BitTorrent Inc.

  • torrenting is the general terms for that act of sharing files using the BitTorrent protocol

Napster

Napster pre-dated the emergence of the BitTorrent protocol. It did not segment files and files were downloaded directly from peers. It was a centralised P2P network because there was a central server that indexed all available files which kept a database of all connected users and their files.

When you searched Napster you would be querying this DB on the server. The server would facilitate a direct connection between the consumer and provider peer for the data exchange.

When users share with BitTorrent the .torrent file is the source of truth and a swarm is created around the users who have possess the file.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Transistors.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Transistors.html deleted file mode 100644 index 71f2870..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Transistors.html +++ /dev/null @@ -1,50 +0,0 @@ -Transistors - My Zettelkasten - - - - -

Transistors

A digital circuit requires that electrical phenomena be treated as discrete rather than continuous values.

Although a given voltage at a point in the circuit can vary widely, in order to represent the binary states of ‘on’ and ‘off’ we need it to remain fixed within certain narrow parameters. This is achieved with transistors.

Transistors are an electrical component that is capable of controlling the flow of current in the manner of a switch where the ‘off’ and ‘on’ states are represented by voltage values within set parameters.

There are different types of transistors but the simplest for the purposes of explanation are bipolar junction transistors.

BJT transistor terminals

The pins:

  • C: collector
  • B: base
  • E: emitter

Applying a small amount of current at the base allows a larger current to flow from the collector to the emitter. Applying current to the base is like turning the switch on. Removing this current is like turning the switch off.

This happens because of how current and voltage interact in a transistor. The small base current controls the larger collector-emitter current through a process called current amplification.

When a small voltage is applied to the base, it allows a small current to flow from the base to the emitter. This base current triggers a much larger current to flow from the collector to the emitter. Think of it like a water valve: a small turn of the handle (base current) can control a large flow of water (collector-emitter current). The transistor amplifies this effect, allowing a tiny input signal to control a much larger output.

Transistors and logic gates

We can combine transistors to create logic gates. A logic gate is a combination of transistors arranged such that the logical function is embodied by the characteristic input and output voltages to the transistor.

For example to create an AND gate we would have two voltage inputs going into two transistors that are connected in sequence. The two transistors create a continuous line going from the collector of one to the emitter of the other. If either voltage input is low then the voltage of the combined line is low (equivalent to the circuit being broken) and there is no current flowing.

// Add example of OR gate created with transistors

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Transport_Layer_of_Internet_Protocol.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Transport_Layer_of_Internet_Protocol.html deleted file mode 100644 index fa0e2a4..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Transport_Layer_of_Internet_Protocol.html +++ /dev/null @@ -1,50 +0,0 @@ -Transport Layer of the Internet Protocol - My Zettelkasten - - - - -

Transport Layer of the Internet Protocol

Transport Layer protocols provide a communications channel for data to be sent between hosts. The Transport Layer is dependent upon the Internet Layer for addressing and routing the data and the Link_Layer_of_Internet_Protocol for transferring the data to a specific host once it has reached the local network.

The protocol governing the Transport Layer is the Transmission Control Protocol (TCP).

A TCP fragment fits within an IP packet’s data section, giving us the following iteration of the network stack:

Transport layer fragment

The segment header contains a destination network port number. The port number identifies the specific service or process on the host device which will receive the data.

A useful analogy:

The IP address is like the street address of an office building. The port number is like the office number of a specific worker within the building. Once a letter arrives at the building, the mail processing office (like the OS) is not the intended recipient. Instead the mail worker passes on the letter to the intended recipient. Likewise, the OS examines the port number and delivers the inbound data to the process listening on the specified port.

Ports

A host with a single IP address can have multiple active ports, each used for performing a different type of activity on the network.

Both servers and clients possess ports. A server will have a dedicated port which it listens for requests on (typically port 80 or port 443). A client will have an “ephemeral” port where it listens for responses from a server. They are ephemeral because they are open only temporarily to receive a response to a certain request and are assigned dynamically by the networking components of the OS.

An IP address plus a port (e.g: 192.168.2.1:3000) constitutes an endpoint. An instance of an endpoint is a socket.

If multiple clients connect to the same endpoint each has its own socket (for instance on a host that is a server). A socket can listen for new connections or it can represent an established, ongoing connection.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Troubleshooting_MongoDB.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Troubleshooting_MongoDB.html deleted file mode 100644 index 180637e..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Troubleshooting_MongoDB.html +++ /dev/null @@ -1,62 +0,0 @@ -Troubleshooting MongoDB connection issues - My Zettelkasten - - - - -

Troubleshooting MongoDB connection issues

Arch Linux troubleshooting

Most times any problems will be a result of a Mongo process that is already running. Resolve with:

# Kill running Mongo process...
-# Identify PID
-sudo lsof -iTCP -sTCP:LISTEN -n -P
-sudo kill [pid]

Otherwise try the below.

# Check that the systemd service is runnign for Mongo
-sudo systemctl status mongodb
-
-# If not, enable and start service (only need to do this once for machine)
-sudo systemctl enable --now mongodb
-sudo systemctl start --now mongodb
-
-# If issues with Mongo daemon...
-# Remove the current socket
-rm /tmp/mongodb-27017.sock

For additional command line utilities you will also need to install mongodb-tools from the AUR.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Truth_functional_connectives.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Truth_functional_connectives.html deleted file mode 100644 index 4b534bc..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Truth_functional_connectives.html +++ /dev/null @@ -1,98 +0,0 @@ -Truth-functional connectives - My Zettelkasten - - - - -

Truth-functional connectives

Propositions generated from other (simple) propositions by means of propositional connectives are compound propositions.

We know that logically determinant propositions express a truth value. When simple propositions are joined with a connective to make a compound proposition they also have a truth value. This is determined by the nature of the connective and the truth value of the constituent propositions. We therefore call connectives of this nature truth functional connectives since the truth value of the compound is a function of the truth values of its components.

A propositional connective is used truth-functionally if and only if it is used to generate a compound proposition from one or more propositions in such a way that the truth value of the generated compound is wholly determined by the truth-values of those one or more propositions from which the compound is generated, no matter what the truth values may be.

Each truth-functional connective has a characteristic truth table. This discloses the conditions under which the constituent propositions have a given truth value when combined with one or more connectives.

We shall now review each of the truth-functional connectives in detail.

Conjunction

Conjunction is equivalent to the word AND in natural language. We use \(\land\) as the symbol for this connective.

A molecular proposition joining two conjuncts P and Q is true iff both conjuncts are true and false otherwise:

P	Q				P	&	Q
-T	T					T
-T	F					F
-F	T					F
-F	F					F

Disjunction

Conjunction is equivalent to the word OR in natural language. We use v as the symbol of this connective.

A molecular proposition joining two disjuncts P and Q is true if either disjunct is true or if both disjuncts are true and false otherwise. This corresponds to the inclusive sense of OR in natural language.

P	Q				P	∨	Q
-T	T					T
-T	F					T
-F	T					T
-F	F					F

Negation

In contrast to the two previous connectives, negation is a unary connective not a binary connective. We use ~ to symbolise negation. It does not join two or more propositions, it applies to one proposition as a whole. This can be a simple proposition or a complex proposition. It simply negates the truth-value of whichever proposition it is applied to. Hence applied to P, it is true if P is false. And if P is false, it is true when P is true. !

P			~	P
-T			F
-F			T

Material conditional (a.k.a implication)

The material conditional approximates the meaning expressed in natural language when we say if such-and-such is the case then such-and-such will the case. Another way of expressing the sense of the material conditional is to say that P implies Q.

If it rains today the pavement will be wet.

We call the proposition that expresses the ‘if’ proposition the antecedent and the proposition that expresses the ‘then’ statement the consequent. The symbol we use to represent the material conditional is although you may see used as well.

The truth table is as follows:

P	Q				P	⊃	Q
-T	T					T
-T	F					F
-F	T					T
-F	F					T

The material conditional is perhaps the least intuitive of the logical connectives. The first case (TT) closely matches what we expect the connective to mean: it has rained so the pavement is wet. The antecedent is true and therefore the consequent is true. This chimes with what we tend to mean by ‘if’ in natural language. In the second case (TF) it also makes sense: the complex proposition is false because it rained and the pavement wasn’t wet: this negates the truth of the expression. The final case (FF) is also straight forward. It didn’t rain therefore the pavement wasn’t wet, thus the overall assertion that rain implies wet pavements is retained.

FT is less intuitive:

It did not rain today. The pavement was wet.

To some degree one just has to take these statements as axioms, whether or not they have intuitive sense is a secondary, more philosophical question. The semantic issues arise because we tacitly assume the material conditional to be a causal connective: there is something about the nature of P that engenders or brings about Q but causality is not a logical concern.

If we instead just focus on the simple propositions that comprise the truth value it is more plausible. In the case of FT we can say it didn’t rain yet the pavement was wet does not stop the pavement being wet when it rains. The fact that I can pour a beer on the pavement thereby making it wet doesn’t stop or render false the idea that the rain can also make the pavement wet. The same explanation covers the FF case: it hasn’t rained and so the pavement is not wet does not contradict the assertion that when it rains the pavement will be wet.

Things are elucidated when we look at an equivalent expression of P ⊃ Q, ~P v Q:

P	Q				~	P	∨	Q
-T	T						T
-T	F						F
-F	T						T
-F	F						T

A disjunction is true whenever either disjunct is true so when both are false the overall expression is false, the same as with FT and FF with the material conditional.

Material biconditional (a.k.a equivalence)

The material biconditional equates to the English expression ‘if and only if’, as a conditional connective it therefore avoids some of the perplexity aroused by its material cousin. In this scenario both antecedent and consequent have to be true for the overall expression to be true. If either is false the complex proposition is false. Other ways of expressing the semantics of this connective is to say that one proposition implies the other or that P and Q are equivalent.

If and only if James studies every day he will pass the exam.

There is no possibility in which James passes the exam and has not studied every day. If he studies for three out of the seven days leading up to the exam he will not pass. Alternatively, there is no possibility that James studied every day yet failed the exam. The antecedent and consequent are locked, as indicated by the truth-table:

P	Q				P	≡	Q
-T	T					T
-T	F					F
-F	T					F
-F	F					T

The last condition (FF) maybe requires some explanation: if he has not studied every day then he cannot have passed the exam. Therefore, to say that he will pass iff he studies every day is rendered true.

Combinations of truth-functional connectives


So far we have applied connectives to simple propositions. In so doing we generate complex propositions. However propositions and connectives are inherently generative: we can build more complex expressions from less complex parts, using more than one type of connective or several different connectives to make larger complex propositions and express more detailed logical conditions ans statements about the world.

For example the proposition:

Socrates was either a philosopher or a drinker but he wasn't a politician.

Can be expressed with greater logical clarity as:

Socrates was a philosopher or Socrates was a drinker and Socrates was not a politician.

Using P for ‘Socrates was a philosopher’, Q for ‘Socrates was a drinker’ and R for ‘Socrates was a politician’ we can express this symbolically as:

(P v Q) & ~R

Which has the truth table:

P	Q	R				(	P	∨	Q	)	&	~	R
-T	T	T									F
-T	T	F									T
-T	F	T									F
-T	F	F									T
-F	T	T									F
-F	T	F									T
-F	F	T									F
-F	F	F									F

Let’s walk through each case where S stands for the overall proposition.

  1. S is false if Socrates was a philosopher, a drinker and a politician.
  2. S is true if Socrates was a philosopher, a drinker but not a politician.
  3. S is false if Socrates was a philosopher, a politician but not a drinker.
  4. S is true if Socrates was a philosopher but not a drinker or politician.
  5. S is false if Socrates was not a philosopher but was a drinker and politician
  6. S is true if Socrates was not a philosopher or politician but was a drinker.
  7. S is false if Socrates was neither a philosopher or drinker but was a politician.
  8. S is false if Socrates was neither a philosopher, drinker, or politician.

If we look just at the true cases for simplicity, it becomes obvious that the truth value of the whole is a function of the truth-values of the parts.

At the highest level of generality the proposition is a conjunction with two disjuncts: P v Q and ~R . Therefore, for the proposition to be true both conjuncts must be true. The first conjunct is true just if one of the subordinate disjuncts is true (Socrates is either a philosopher, a drinker, or both). The second conjunct is true just if Socrates is not a politician. Thus there is only one variation for the second conjunct (not being a politician) and two variations for the first conjunct (being a drinker/being a philosopher) hence there are three cases where the overall proposition is true.

Logical equivalence

Once we start working with complex propositions with more than one truth-functional connective it becomes clear that the same proposition expressed in natural language can be expressed formally more than one way and thus that in logical terms, both formal expressions are equivalent. We can prove this equivalence by comparing truth tables.

For example the proposition:

I am going to the shops and the gym.

Can obviously be expressed formally as:

P & Q

But also as:

~ (~P v ~Q)

And we know this because the truth-tables are identical:consistency

P	Q				P	&	Q
-T	T					T
-T	F					F
-F	T					F
-F	F					F
P	Q			~	(	~	P	∨	~	Q	)
-T	T			T
-T	F			F
-F	T			F
-F	F			F

Another example of equivalent expressions:

Neither Watson or Sherlock Holmes is fond of criminals

The first formalisation:

~P & ~Q

Equivalent to:

~(P v Q)

Again the truth-tables for verification:

P	Q				~	P	&	~	Q
-T	T						F
-T	F						F
-F	T						F
-F	F						T

~P & ~Q

P	Q			~	(	P	∨	Q	)
-T	T			F
-T	F			F
-F	T			F
-F	F			T

Important equivalences

The example above is a key equivalence that you will encounter a lot especially when deriving formal proofs. It goes together with another one. We have noted them both below for future reference:

~P & ~Q = ~P v ~Q
~P v ~Q = ~(P & Q)

Enforcing binary connectives through bracketing

If we had a proposition of the form

Socrates is man, is mortal and a philosopher.

We could not write this as:

P & Q & R

This would not be a well-formed proposition because at most truth functional connectives can only connect two simple propositions. It would not be possible to generate truth conditions for this proposition in its current form. Instead we introduce brackets to enforce a binary grouping of simple propositions. In this instance, the placement of the brackets does not affect the accurate interpretation of the truth conditions of the compound, so the following two formalisations are equivalent:

(P & Q) & R
-
-P & (Q & R)
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Truth_tables.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Truth_tables.html deleted file mode 100644 index f6fce99..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Truth_tables.html +++ /dev/null @@ -1,76 +0,0 @@ -Truth-tables - My Zettelkasten - - - - -

Truth-tables

We are already familiar with truth-tables from the previous entry on the truth-functional connectives and the relationship between sentences, connectives and the overall truth-value of a sentence. Here we will look in further depth at how to build truth-tables and on their mathematical relation to binary truth-values. We will also look at examples of complex truth-tables for large compound expressions and the systematic steps we follow to derive the truth conditions of compound sentences from their simple constituents.

Formulae for constructing truth-tables

For any truth-table, the number of rows it will contain is equal to \(2n\) where:

  • \(n\) stands for the number of sentences
  • \(2\) is the total number of possible truth values that the sentence may have: true or false.

When we count the number of sentences, we mean atomic sentences. And we only count each sentence once. Hence for a compound sentence of the form \((\sim B \supset C) & (A \equiv B)\), \(B\) occurs twice but there are only three sentences: \(A\), \(B\), and \(C\).

Thus for the sentence \(P & Q\) ,we have two sentences so \(n\) is 2 which equals 4 rows (2 x 2):

P	Q				P	&	Q
-T	T					T
-T	F					F
-F	T					F
-F	F					F

For the sentence \((P \lor Q) & R\) we have three sentences so \(n\) is 3 which equals 8 rows (2 x 2 x 2):

P	Q	R				(	P	∨	Q	)	&	R
-T	T	T									T
-T	T	F									F
-T	F	T									T
-T	F	F									F
-F	T	T									T
-F	T	F									F
-F	F	T									F
-F	F	F									F

For the single sentence \(P\) we have one sentence so \(n\) is 1 which equals 2 rows (2 x 1):

P			P
-T			T
-F			F

This tells us how many rows the truth-table should have but it doesn’t tell us what each row should consist in. In other words: how many Ts and Fs it should contain. This is fine with simple truth-tables since we can just alternate each value but for truth-tables with three sentences and more it is easy to make mistakes.

To simplify this and ensure that we are including the right number of possible truth-values we can extend the formula to \(2n^-i\). This formula tells us how many groups of T and F we should have in each column.

We can already see that there is a pattern at work by looking at the columns of the truth tables above. If we take the sentence \((P \lor Q) & R\) we can see that for each sentence:

  • \(P\) consists in two sets of \({\textsf{T,T,T,T}}\) and \({\textsf{F,F,F,F}}\) with four elements per set
  • \(Q\) consists in four sets of \({\textsf{T,T}}\) , \({\textsf{F,F}}\), \({\textsf{T,T}}\) , \({\textsf{F,F}}\) with two elements per set
  • \(R\) consists in eight sets of \({\textsf{T}}\), \({\textsf{F}}\), \({\textsf{T}}\), \({\textsf{F}}\), \({\textsf{T}}\), \({\textsf{F}}\), \({\textsf{T}}\), \({\textsf{F}}\) with one element per set.

If we work through the formula we see that it returns 4, 2, 1:

$$\begin{equation} \begin{split} 2n^-1 = 3 -1 \\ = 2 \\ = 2 \cdot 2 \\ = 4 \end{split} \end{equation}$$

$$ -\\begin{equation} \begin{split} 2n^-2 = 3 - 2 \\ = 1 \\ = 2 \cdot 1 \\ = 2 \end{split} \end{equation} -$$

$$ -\\begin{equation} \begin{split} 2n^-3 = 3 - 3 \\ = 0 \\ = 2 \cdot 0 \\ = 1 \end{split} \end{equation} -$$

Truth-table concepts

Recursion

When we move to complex truth-tables with more than one connective we realise that truth-tables are recursive. The truth-tables for the truth-functional connectives provide all that we need to determine the truth-values of complex sentences:

The core truth-tables tell us how to determine the truth-value of a molecular sentence given the truth-values of its immediate sentential components. And if the immediate sentential components of a molecular sentence are also molecular, we can use the information in the characteristic truth-tables to determine how the truth-value of each immediate component depends n the truth-values of its components and so on.

Truth-value assignment

A truth-value assignment is an assignment of truth-values (either T or F) to the atomic sentences of SL.

When working on complex truth tables, we use the truth-assignment of atomic sentences to count as the values that we feed into the larger expressions at a higher level of the sentential abstraction.

Partial assignment

We talk about partial assignments of truth-values when we look at one specific row of the truth-table, independently of the others. The total set of partial assignments comprise all possible truth assignments for the given sentence.

Working through complex truth-tables

The truth-table below shows all truth-value assignments for the sentence \((\sim B \supset C) & (A \equiv B)\) :

A	B	C				(	~	B	⊃	C	)	&	(	A	≡	B	)
-T	T	T					F	T	T	T		T		T	T	T
-T	T	F					F	T	T	F		T		T	T	T
-T	F	T					T	F	T	T		F		T	F	F
-T	F	F					T	F	F	F		F		T	F	F
-F	T	T					F	T	T	T		F		F	F	T
-F	T	F					F	T	T	F		F		F	F	T
-F	F	T					T	F	T	T		T		F	T	F
-F	F	F					T	F	F	F		F		F	T	F

As with algebra we work outwards from each set of brackets. The sequence for manually arriving at the above table would be roughly as follows:

  1. For each sentence letter, copy the truth value for it in each row.
  2. Identify the connectives in the atomic sentences and the main overall sentence.
  3. Work out the truth-values for the smallest connectives and sub-compound sentences. The first should always be negation and then the other atomic connectives.
  4. Feed-in the truth-values of the atomic sentences as values into the main connective, through a process of elimination you then reach the core truth-assignments:
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Truth_trees.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Truth_trees.html deleted file mode 100644 index af23f6f..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Truth_trees.html +++ /dev/null @@ -1,62 +0,0 @@ -Truth trees - My Zettelkasten - - - - -

Truth trees

Rationale

Like Truth-tables, truth-trees are a means of graphically representing the logical relationships that may obtain between propositions. Truth-trees and truth-tables complement each other and which method you choose depends on which logical property you are seeking to derive.

Whilst truth-tables have the benefit of being exhaustive - every possible truth assignment is factored into the representation - their complexity grows exponentially with each additional proposition they contain. This can make manually constructing truth tables long-winded and prone to mistakes.

Truth-trees are less onerous but they lack the exhaustive scope of a truth-table. They are more targeted and are best used for demonstrating that something is the case rather than all the possible states that could be the case. For example, a truth tree will tell us that a set S is logically consistent whereas a truth-table will tell us that S is consistent on the following three assignments.

Logical consistency

Recall that a set of propositions is logically or truth-functionally Consistency just if there is at least one assignment of truth conditions which results in all members of the set being true. To identify consistency for a set of three propositions via the truth table approach we would need to construct a truth table with \(2^3\) (8) rows. Assume that this set is consistent on one partial assignment only. This means that 87.5% of our rows are redundant, they are not required to prove the consistency of the set. However we can only know this and we can only be sure of consistency once we have gone through the process of generating an assignment for each row.

Truth trees allow us to reduce the amount of work required and go straight to the assignment that proves consistency, disregarding the rest which are irrelevant.

Truth tree structure and key terms

When using a truth tree to derive logical consistency, the goal is to determine whether there is a truth-value assignment on which all of the sentences of a set are true. If the set is consistent we should be able to derive a partial assignment from the tree that demonstrates consistency.

Each truth tree begins with a series of sentences one on top of the other in a column. We call the sentences that comprise the initial column set members. In constructing the tree, we work downwards from the initial column decomposing set members into their atomic constituents. We a call an atomic sentence that has been decomposed a literal. A literal will either be an atomic sentence or the negation of an atomic sentence. If one of the set members is already a literal, there is no need to decompose it; it can remain as it is.

Once every set member has been decomposed the truth tree is complete. It can then be interpreted in order to derive logical consistency or inconsistency. If the set is consistent, we are able to derive the partial assignment(s) that demonstrate consistency.

The rules for decomposing compound sentences match the truth conditions of the logical connectives. There are rules for every possible connective and the negation of every possible connective however in terms of their tree shape they all correspond to either a conjunction or a disjunction. Disjunctive decomposition results in new branches being formed off the main column (or trunk). Conjunctive decomposition is non-branching which means the decomposed constituents are placed within the trunk of whichever tree or branch they are decomposed within.

As we construct the tree we list each line in the left-hand margin and the decomposition rule in the right-hand margin. When we apply a decomposition rule we must cite the lines to which it applies.

Closed and open branches

Any branch on which an atomic sentence (\(P\)) and the negation of that sentence (\(\sim P\)) both occur is a closed branch. A branch that is not closed is an open branch. No partial assignment is recoverable from a closed branch. An open branch allows truth to ‘flow up’ to the original set members whereas a closed branch blocks this passage.

Completed open branch

A completed open branch occurs when we have an open branch that has been fully decomposed: the branch is open and all molecular sentences have been ticked off such that it contains only literals.

Completed tree

A tree where all its branches are either completed open branches or closed branches.

Closed tree

A tree where all the branches are closed

Open tree

A tree with at least one completed open branch

Deriving consistency

Using the definitions above, we can now define truth-functional consistency and inconsistency in terms of truth trees:

A finite set (\(\Gamma\) ) of sentences is truth-functionally inconsistent if \(\Gamma\) is a closed tree

A finite set (\(\Gamma\) ) of sentences is truth-functionally consistent if \(\Gamma\) is an open tree

Examples

First example

The following is a truth tree for the set \({P \lor Q, \sim P }\):

basic-open-tree 1.svg

Interpretation

  • We decompose the disjunction at line 1 on line 3. We tick off the compound sentence to indicate that it is now decomposed and no longer under consideration.
  • Both P and its negation exist on a single branch (at line 2 and line 3). This makes it a closed branch. We indicate this by the X beneath the branch that is closed, citing the source of the closure by line number.
  • The rightward branch is a completed open branch given the decomposition at 3 and the lack of negation of Q. Overall this makes the tree an open tree.

As the set gives us an open tree, it must be truth-functionally consistent. If this is the case we should be able to determine the partial assignment in which each set member is true. Given that Q is not negated the assignment of consistency will contain Q but we have both P and ~P. This means there are two possible assignments where the set is consistent: \(P, Q\) and \(\sim P, Q\). This is confirmed by the truth-table:

P	Q				P	∨	~	P				Q
-T	T					T						T     *
-T	F					T						F
-F	T					T						T     *
-F	F					T						F

Any time there is an open tree with a closed branch it will be the case that the negated sentences of the closed branch will appear both as \(S\) and \(\sim S\) in the resultant assignment.

Invoking the truth-table highlights the differences between the two techniques. The values that are derived when we interpret a truth tree are not the truth-functions of the set members but the truth-values for when they are simultaneously true. With truth-tables in contrast, we are deriving the truth functions for every possible truth-value assignment. In other words the values derived from a truth tree correspond to the left hand side of the truth table not the right hand side.

Second example

The following is a truth tree for the set \({A & \sim B, C, \sim A \lor \sim B }\).

basic-closed-tree 1.svg

Interpretation

  • The two molecular set members are decomposed. The disjunction (line 3) results in a branching tree. The conjunction (line 1) results in the continuation of the trunk.
  • Both branches are completed making it a completed tree. As each branch is closed this is a closed tree.

As this is a closed tree, the set is not truth-functionally consistent. This is confirmed by the truth table where there is no partial assignment where all set members are true.

A	B	C				A	&	~	B				C				~	A	∨	~	C
-T	T	T					F						T						F
-T	T	F					F						F						T
-T	F	T					T						T						F
-T	F	F					T						F						T
-F	T	T					F						T						T
-F	T	F					F						F						T
-F	F	T					F						T						T
-F	F	F					F						F						T

Truth tree decomposition rules


So far we have encountered the decomposition rules for conjunction (&D) and disjunction (vD). We will now list all the rules. We will see that for each rule, the decomposition either branches or does not branch which is to say that each rule either has the shape of a conjunction or a disjunction (however the permitted values of the specific disjuncts/conjuncts obviously differ in each case). Moreover there is a parallel rule for the decomposition of the negation of each of the main connectives and these rules rely on logical equivalences

Negated negation decomposition: ~~D

negated-negation-decomposition-rule 2.svg

Truth passes only if \(P\) is true

Conjunction decomposition: &D

conjunction-decomposition-rule.svg

Truth passes only \(P\) and \(Q\) are both true.

Negated Conjunction decomposition: ~&D

negated-conjunction-decomposition-rule.svg

Truth passes if either \(\sim P\) or \(\sim Q\) is true. This rule is a consequence of the equivalence between \(\sim (P & Q)\) and \(\sim P \lor \sim Q\) , the first of DeMorgan’s Laws.

Disjunction decomposition: vD

disjunction-decomposition-rule.svg

Truth passes if either \(P\)or \(Q\) are true.

Negated Disjunction decomposition: ~vD

negated-disjunction-decomposition-rule.svg

Truth passes if both \(P\) and \(Q\) are false. This rule is a consequence of the equivalence between \(\sim (P \lor Q)\) and \(\sim P & \sim Q\), the second of DeMorgan’s Laws.

Conditional decomposition: ⊃D

conditional-decomposition-rule.svg

Truth passes if either \(\sim P\) or \(Q\) are true. This rule is a consequence of the equivalence between \(P \supset Q\) and \(\sim P \lor Q\) therefore this branch has the shape of a disjunction with \(\sim P\) , \(Q\) as its disjuncts.

Negated Conditional decomposition: ~⊃D

Truth passes if both \(P\) and \(\sim Q\) are true. This is a consequence of the equivalence between \(\sim (P \supset Q)\) and \(P & \sim Q\).

negated-conditional-decomposition-rule.svg

Biconditional decomposition: ≡D

biconditional-decomposition-rule.drawio(1).svg

Truth passes if either \(P\) and \(Q\) are true or \(\sim P & \sim Q\) are true. This is an interesting rule because it combines the disjunction and conjunction tree shapes.

Negated biconditional decomposition: ~≡D

negated-biconditional-decomposition-rule.drawio.svg

Truth passes if either \(P\) and \(\sim Q\) is true or if \(\sim P\) and \(Q\) is true.

Further examples and heuristics for complex truth trees

With truth-trees regardless of which order you decompose the set members, the conclusion should always be the same. This said, there more are more efficient ways than others to construct the trees. You want to find the route that will demonstrate consistency or non-consistency with the shortest amount of work. The following heuristic techniques followed in order, facilitate this:

  1. Decompose those molecular sentences the decomposition of which does not produce new branches. In other words that are decompositions of double negations or pure conjunctions.
  2. Perform those decompositions that will rapidly generate closed branches.
  3. If neither (1) or (2) is applicable, decompose the most complex sentence first.

Here are some examples of these rules applied:

complex-tree.svg

Observe that here we don’t bother to decompose the sentence on line 1. This is because, having decomposed the sentences on lines 2 and 3 we have arrived at a closed tree. It is therefore unnecessary to go any further for if two sentences in the set are inconsistent with each other, adding another sentence is not going to change the overall assignment of inconsistency.

Deriving properties other than logical consistency from truth trees

So far truth trees have been discussed purely in terms of logical consistency however they can be used to derive all the other key truth-functional properties of propositional logic. Given the foundational role of consistency to logic, these properties are expressible in terms of consistency which is what makes them amenable to formulation in terms of truth trees.

Logical falsity

For a given finite set \(\Gamma\), \(\Gamma\) is logically consistent just if all of its members can be true at once. Expressed in terms of truth trees, this is equivalent to an open tree. Contrariwise, \(\Gamma\) is inconsistent if it is not possible for every member of the set to be true at once. This is the same as a tree where all of the branches are closed (i.e. a closed tree).

When we wish to assess logical falsity we are not focused on sets however, we are interested in a property of a sentence. However we can easily construe single sentences as unit sets: sets with a single member. With this in mind and the above accounts of consistency and logical falsity we are equipped to express logical falsity in terms of truth-trees with the following rule:

A sentence \(P\) is logically false if and only if the unit set \({ P }\) has a closed tree

A logically false sentence cannot be true on any assignment. This is the same thing as an inconsistent set. Thus it will be represented in a truth tree as inconsistency which is disclosed via a closed tree.

logical-falsity-tree.svg

Logical truth

For a sentence \(P\) to be logically true, there must be no possible assignment in which \(P\) is false. We express this informally by saying it is not possible to consistently deny \(P\). We know that in terms of truth trees an inconsistent set is a closed tree therefore a unit set of \({ P }\) is logically true if \({ \sim P }\) is a closed tree. This is to say: if the negation of \(P\) is inconsistent.

A sentence \(P\) is logically true if and only if the set \({ \sim P }\) has a closed tree

Logical indeterminacy

Indeterminacy follows from the two definitions above; we do not require any additional apparatus. We recall that a sentence \(P\) is logically indeterminate just if it is neither logically true or logically false. Thus the truth tree for an indeterminate sentence is straightforward:

A sentence \(P\) is logically indeterminate if and only if neither the set  \({ P }\) nor the set \({ \sim P }\) has a closed tree

This follows because a closed tree for  \({ P }\) means it is not logically false and an open tree for \({ \sim P }\) means it is not logically true. So if it is neither of these things, \(P\) must be indeterminate.

Logical equivalence

Recall that \(P\) and \(Q\) are logically equivalent just if there is no truth assignment on which one is true and the other is false. We know from the material biconditional shorthand that this state of affairs can be expressed as $P \equiv Q$ and that if this compound sentence is true on every assignment then both simple sentences are equivalent. But ‘true on every assignment’ is another way of saying logically true since there is no possibility of a false assignment. We already know what logical truth looks like as a truth tree: it is a closed tree for the negation of the sentence being tested. Therefore, to test the logical equivalence of two sentences it is necessary to construct a truth tree for the negation of the sentences conjoined by the biconditional (i.e. \(\sim (P \equiv Q)\) )and see if this results in a closed tree. If it does, the two sentences are logically equivalent.

Sentences \(P\) and \(Q\) are truth-functionally equivalent if and only if the set \(\sim (P \equiv Q)\) has a closed tree

logical-equivalence-tree.svg

Logical entailment and validity

Let’s remind ourselves of the meaning of truth-functional entailment and validity and the relation between the two. \(\Gamma\) \(\vdash\) \(P\) is true if and only if there is no truth-assignment in which every member of \(\Gamma\) is true and \(P\) is false. Entailment is closely related to validity; it is really just a matter of emphasis: we say that \(\Gamma\) are the premises and \(P\) is the conclusion and that this is a valid argument if there is no assignment in which every member of \(\Gamma\) is true and \(P\) is false.

As with the previous properties, to express validity and entailment in terms of truth trees we need to express these concepts in the language of logical consistency. \(\Gamma\) entails \(P\) just if one cannot consistently assert \(\Gamma\) whilst denying \(P\). This is to say that the set \(\Gamma \cup {\sim P}\) is inconsistent. So we just need a closed truth tree for \(\Gamma \cup {\sim P}\) to demonstrate the validity of this set.

A finite set of sentences \(\Gamma\) truth-functionally entails a sentence \(P\) if and only if the set \(\Gamma \cup {\sim P}\) has a closed truth tree.

An argument is truth functionally valid if and only if the set consisting of the premises and the negation of the conclusion has a closed truth tree.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Tuples_in_Python.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Tuples_in_Python.html deleted file mode 100644 index 97818a8..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Tuples_in_Python.html +++ /dev/null @@ -1,96 +0,0 @@ -Tuples in Python - My Zettelkasten - - - - -

Tuples in Python

TODO: Exapand tuple notes - give more use cases

Tuples are one of the main data-structures or containers in Python. Tuples are useful in cases where you want to group related data and ensure that it will not change.

Tuples have the following properties:

  • They are ordered
  • They have a fixed size
  • They are immutable and cannot be modified
  • Allow duplicate members
  • They are indexed

In essence a tuple is a list that is immutable.

As with all containers in Python they permit any data type.

Tuples are denoted with (...)

Basic usage

tup1 = (1, 3, 5, 7)
-print(tup1[2])
-
-# 5
-"""

Slicing

tup1 = (1, 3, 5, 7)
-
-print(tup1[1:3])
-print(tup1[:3])
-print(tup1[1:])
-print(tup1[::-1])
-
-"""
-(3, 5)
-(1, 3, 5)
-(3, 5, 7)
-(7, 5, 3, 1)
-"""

Looping

tup3 = ('apple', 'pear', 'orange', 'plum', 'apple')
-for x in tup3:
-    print(x)
-
-"""
-apple
-pear
-orange
-plum
-apple
-"""

Useful methods and predicates

tup3 = ('apple', 'pear', 'orange', 'plum', 'apple')
-
-# Count instances of a member
-print(tup3.count('apple'))
-# 2
-
-# Get index of a member
-print(tup3.index('pear'))
-# 1
-
-# Check for membership
-if 'orange' in tup3:
-    print('orange is in the Tuple')
-
-# orange is in the Tuple

Nest tuples


-tuple2 = ('John', 'Denise', 'Phoebe', 'Adam')
-tuple3 = (42, tuple1, tuple2, 5.5)
-print(tuple3)
-
-# (42, (1, 3, 5, 7), ('John', 'Denise', 'Phoebe', 'Adam'), 5.5)
-

// TODO: How to flatten a tuple?

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Turing_completeness.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Turing_completeness.html deleted file mode 100644 index 0fecba2..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Turing_completeness.html +++ /dev/null @@ -1,50 +0,0 @@ -Turing Completeness - My Zettelkasten - - - - -

Turing Completeness

We know that a Turing machine is a theoretical construct of a computer that:

contains mutable state, executes sequences of simple instructions that read and write that state, and can pick different execution paths depending on the state (via conditional branch instructions.)

A Turing Complete (TC) system is a system that abides by, or can be reduced to, the above description.

TC also serves as a definition of computability and provides a formal basis for conceiving of computation at a theoretical level.

All Turing Complete systems are functionally equivalent. This means they can simulate each other given enough time and memory. Similarly a TC system can in principle perform any computation that any other programmable computer can perform. This is true for other TC systems and also those that are not TC however the inverse doesn’t hold: a non-TC system cannot emulate a TS system. For instance a calculator cannot do what a TC smart phone can do. But a smart phone can act as a calculator.

This concept of completeness is also expressed in terms of a Universal Turing Machine - a TM capable of simulating any other Turing machine. Given that the ability of a TM to simulate another TM is the condition for completeness, a TC system is also a UTM.

Completeness applies to the hardware of computers as well as their software.

Turing Completeness is the theoretical basis of the practical concept of a “general-purpose computer”: a general-purpose computer is such because it is TC - it can in theory compute anything that is computable.

Most modern programming languages are Turing Complete in that they can, in theory, be used to compute anything that is computable.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Turing_machines.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Turing_machines.html deleted file mode 100644 index 0186a55..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Turing_machines.html +++ /dev/null @@ -1,50 +0,0 @@ -Turing Machines - My Zettelkasten - - - - -

Turing Machines

What is a Turing Machine?

Turing Machine is a machine that contains mutable state, executes sequences of simple instructions that read and write that state, and can pick different execution paths depending on the state (via conditional branch instructions.)

This is a general expression, it is typically expanded as follows.

The machine consists of an infinitely long tape, that has been divided up into cells. Each cell can contain either a 1, a 0 or an empty space. Above one cell of the tape is a head, which can either move left or right, and can read the symbols written in the cells. The head is also capable of erasing symbols and writing new symbols into the cells.

Turing_machines_01.gif

The direction that the head moves, which values it erases, and which values it writes in, are dependent on a set of instructions provided to the machine.

Different sets of instructions can be divided into states. States are like sub-routines and can themselves feature as part of instructions.

For example:

State 2

  • If 0 then erase
  • Write 1 then move right
  • Go to state 5

State 5

  • If 1, then erase
  • Write 0 then move left
  • Go to state n

Alan Turing proved that any problem that is computable can be computed by a Turing Machine using this simple system.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Twos_complement.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Twos_complement.html deleted file mode 100644 index c8e6d5f..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Twos_complement.html +++ /dev/null @@ -1,54 +0,0 @@ -Two’s complement - My Zettelkasten - - - - -

Two’s complement

Summary

  • Two’s complement is a method for representing signed numbers (negative integers) in binary.

  • It is derived by inverting the values of an unsigned binary integer to create its signed equivalent.

  • A benefit is that hardware implementation of the binary arithmetic of signed and unsigned numbers can be handled in the same manner as unsigned numbers, requiring no additional handling. A drawback is that it halves the informational capacity of the given word length for the binary system.

Detail

Procedural steps

Two’s complement divides the available word length (see binary encoding) into two subsets: one for negative integrs and one for positive integers.

Take the binary encoding of decimal five (0101). Its complement is 1011.

The procedure for deriving the complement is as follows.

To derive the complement of an unsigned number:

  1. Take the unsigned number and invert its digits: 0 becomes 1, 1 becomes 0
  2. Add one

To derive the unsigned equivalent of a signed number you invert the process but still make the smallest digit 1:

Formal expression

$$ -2^n - x -$$

  • where \(x\) is the negative integer in binary that we wish to derive
  • where \(n\) is the word length of the binary system in bits.

Applied to the earlier example we have \(2^4 -5\) which is:

$$ -16 - 5 = 11 -$$

When we convert the decimal 11 to binary we get 1011 which is identical to the signed version of the unsigned integer.

We can confirm the correctness of the derviation by summing the signed and unsigned binary values. If this results in zeros (ignoring the overflow bit), the derivation is correct as the two values effectively cancel each other out:

$$

1011 + 0101 = 0000 $$

Advantages

  • The circuit implementation of arithmetic involving positive and negative integers is the same as the implementation of positive integers. There is no need for additional harware or special handling of the values.
  • This can be contrasted with the alternative approaches to signing numbers such as signed magnitude representation which uses certain bits as designators of negative/positive status.

Limitations

  • Two’s complement reduces the overall informational capacity of the given binary word length, effectively halving the total number of unique values.

  • In a 4-bit system instead of 16 total unique encodings of integers you have 8 encodings for positive integers and 8 encodings for the their signed equivalent. For integers larger than denary 8 you would need to increase the bit length of the system

  • Consequently two’s complement can necessitate larger overall word lengths.

signed_and_unsigned_numbers, binary addition, Signed magnitude representation

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Type_guarding_and_narrowing_in_TS.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Type_guarding_and_narrowing_in_TS.html deleted file mode 100644 index b88d8f1..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Type_guarding_and_narrowing_in_TS.html +++ /dev/null @@ -1,50 +0,0 @@ -Type narrowing and guarding - My Zettelkasten - - - - -

Type narrowing and guarding

Type narrowing is the process of working out from a supertype like any or unknown whic type the value should be in the x course of your code. This is necessary since a process will not necessarily always return or involve homogenous types.

Related to this is type guarding: ensuring that a value is of the suitable type as a factor of control flow. For instance using typeof to ensure that an input is numerical before proceeding with a function’s logic.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Type_hinting.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Type_hinting.html deleted file mode 100644 index c812874..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Type_hinting.html +++ /dev/null @@ -1,77 +0,0 @@ -Type hinting in Python - My Zettelkasten - - - - -

Type hinting in Python

With type hinting we can add type information to variables, functions, and classes. This is not enforced by the Python interpreter but can be used by external tools like mypy to check the code.

Prior to 3.10, to use types you would have to import the types you wanted from the typing module. With later versions you can use them directly without importing from typing.

Basic syntax

Variables

name: str = "John"
-age: int = 30

Functions

def greet(name: str) -> str:
-    return "Hello, " + name

Classes

// TODO: Add examples

Complex data types

We can type complex data types such as dictionaries, lists, tuples etc.

The following function takes a tuple comprising two integers as a parameter and returns a list of ints:

def populate_pair_values(pair: tuple[int, int]) -> list[int]:
-    return [i for i in range(pair[0], pair[1] + 1)]

Custom dictionary types

We can create custom dictionary types in the manner of TypeScript types and interfaces as follows:

class ArticleInfo(TypedDict):
-    timestamp: str
-    article_    link: str

We could then use it thus:

def parse_articles() -> list[ArticleInfo]:

Optional types

Optional can be used to indicate that a variable can be None or the specified type.

from typing import Optional
-
-def find_index(numbers: list[int], target: int) -> Optional[int]:
-    try:
-        return numbers.index(target)
-    except ValueError:
-        return None

The function above returns an int or None.

Post 3.10, we don’t need to use Optional, we can use a union to cover the None case. Refactoring the previous example:

def find_index(numbers: list[int], target: int) -> int | None:
-    try:
-        return numbers.index(target)
-    except ValueError:
-        return None

Union types

Union can be used to indicate that a variable can be one of several types.

from typing import Union
-
-def add(a: Union[int, float], b: Union[int, float]) -> Union[int, float]:
-    return a + b

The function above returns an int or float.

Note that in the case of Optional and Union the type is specified using square brackets. This is a syntactic covnention and does not denote that the return type is a list. Below is an example of how we would use type hinting to indicate that the return type actually is a list:

from typing import List, Union
-def my_function() -> List[int]:
-    return [1, 2, 3]
-
-# And to show a return type of a list of integers or floats:
-
-def my_function() -> List[Union[int, float]]:
-    return [1, 2, 3]

Post 3.10 we can use | syntax instead of importing Union. E.g:


-def add(a: int | float, b: int | float) -> int | float:
-    return a + b
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Union_types_in_TS.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Union_types_in_TS.html deleted file mode 100644 index e6ab9f3..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Union_types_in_TS.html +++ /dev/null @@ -1,77 +0,0 @@ -Union types - My Zettelkasten - - - - -

Union types

Like intersection types, union types allow us to combine the properties of existing primitive and custom types to make composites.

Intersection types work well when you have complete knowledge of what form your data will take. This approach only works if you know in advance that your data will be and that it will share properties from more than one type. But what if you don’t have this knowledge? You only know that it will be one of the three possible types? This is where union types become helpful. Instead of saying that event X will be of type A we say that event X may be one of types A or B or C.

A union type is a type formed from two or more other types, representing values that may be any one of those types. We refer to each of these types as the union’s members.

Demonstration

type Petrol = {
-  maxSpeed: number;
-  tankVolume: number; // unique property
-};
-
-type Electric = {
-  maxSpeed: number;
-  maxCharge: number; // unique property
-};
-
-type Car = Petrol | Electric;
-
-const tesla: Car = {
-  maxSpeed: 120,
-  maxCharge: 22,
-};
  • We have defined two custom types: Petrol and Electric
  • We have unified them to make a new custom type of Car
  • tesla is an instance of the union type

Usage with functions

Union type syntax is not limited to the declaration phase. You can also use them as parameters to functions or function return types:

function generateCar(car: Petrol | Electric): void {
-  console.log(`The car has a max speed of ${car.maxSpeed}`);
-}

Unifying primitive and custom types

We can also use unions with primitive types as well as custom types:

function printId(id: number | string): void {
-  console.log(`Your id is ${id}`);
-}

We can also combine primitive and custom types in the same union:

function printStringOrNumber(): string | Petrol {}

Set theory: understanding errors

In JavaScript we have the primitive types of string , number , boolean etc. In TS, these types are distinct and exclusive: if you declare that x : string you cannot redefine it as boolean or expect Boolean properties and methods to belong to a string type. For instance a string type is incapable of having as its value false.

This is not true in the case of unions.

With a union of string | boolean a value x could be 'banana' or true. We are allowing for all values that are either from the set string or the set boolean. Logically this is equivalent to the OR operator: a value of type string | boolean could be one of infinite possible strings or true/false. With union types then, we radically widen the scope of possible values for the type. a

These constraints don’t just apply to the values themselves but the methods and properties you can use with the values. For instance a boolean doesn’t have the property of length. Therefore if you have a union type of string|boolean you are going to get an error if you apply length to it since the property must exist on both types that comprise the union. The way round this is to use type narrowing and execute control flow based on the parameter that is passed to a function that is declared to be of this mixed type.

Here is an example of this:

function printId(id: number | string) {
-  if (typeof id === "string") {
-    // In this branch, id is of type 'string'
-    console.log(id.toUpperCase());
-  } else {
-    // Here, id is of type 'number'
-    console.log(id);
-  }
-}
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Unknown_type_in_TS.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Unknown_type_in_TS.html deleted file mode 100644 index 1597ac1..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Unknown_type_in_TS.html +++ /dev/null @@ -1,50 +0,0 @@ -Unknown - My Zettelkasten - - - - -

Unknown

You might think that a good use case for any is a scenario where you don’t know in advance what the data type is going to be.

In order to mark that this is the case, you type the value as any. In fact, TypeScript provides a type for this specific scenario: unknown.

Like any, unknown is equivalent to every type in TS (it is also a supertype) but it is deliberately inhibiting, in contrast to any. When you use unknown you have to use type narrowing to avoid it being returned. So if your code starts with unknown, you should filter out scenarios where it evaluates to each of the possible types otherwise if unknown is returned it will cause an error.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Untitled.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Untitled.html deleted file mode 100644 index 160e089..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Untitled.html +++ /dev/null @@ -1,50 +0,0 @@ -Untitled - My Zettelkasten - - - - -

Untitled

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Update_a_Mongo_document.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Update_a_Mongo_document.html deleted file mode 100644 index 8dc19cd..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Update_a_Mongo_document.html +++ /dev/null @@ -1,79 +0,0 @@ -Update a MongoDB document - My Zettelkasten - - - - -

Update a MongoDB document

There are two methods for updating a document

  • query first
  • update first

Query first document update

With this approach we first execute a query to retrieve the document we want to edit and then make the change. We use the findById method to identify the document by its UUID and then set to update specified properties on the document. The set method is one of many operators that can be used to update values. For example there is also built-in operators for increment, renaming, multiplying values.

Query first is best used when you want to secure the update with some prior logic or to validate. For example you may not want to update a course if it is listed as published. You could use a query to determine the publish status and then only update the entry if it returns isPublished: false.

async function updateCourseFromQuery(id) {
-  const course = await Course.findById(id);
-  if (!course) return;
-  course.set({
-    isPublished: true,
-    author: "A new author",
-  });
-
-  // Instead of an object, we could also set the updated properties individually
-  course.isPublished = true;
-  course.author = "Biggs Volunksire";
-
-  const result = course.save();
-  console.log(result);
-}

Update first document update

With this approach we don’t bother with a prior query. We are confident that the update is legitimate and do not need to first determine that certain conditions are met.

To do this we directly use the update method, not find:

async function updateCourseFromQuery(id) {
-  const result = await Course.update({ _id: id });
-  $set: {
-    // Invoke the set operator
-    author: "Terry Nutile";
-    isPublished: true;
-  }
-  console.log(result);
-}

This function will just return some metadata about the update. It won’t by default return the updated value. To do this use the findByIdAndUpdate() method instead of update:

async function updateCourseFromQuery(id) {
-    const course = await Course.findByIdAndUpdate(id, {
-    $set: { // Invoke the set operator
-        author: 'Terry Nutile'
-        isPublished: true
-    }, {new: true}});
-    console.log(result)
-}

If we don’t add {new: true}, it will return the document before the update.

Updating multiple documents at once

// Add: notes on this

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Update_an_SQL_table.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Update_an_SQL_table.html deleted file mode 100644 index 2e89b49..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Update_an_SQL_table.html +++ /dev/null @@ -1,50 +0,0 @@ -Updating an SQL table - My Zettelkasten - - - - -

Updating an SQL table

We use the ALTER query to add, remove and otherwise change the structural properties of a table in the database.

Add an additional field to existing table

This adds a price field to the sales table. The price field accepts data of the type real.

ALTER TABLE sales ADD price real;
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Update_existing_data_in_SQL_table.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Update_existing_data_in_SQL_table.html deleted file mode 100644 index 4548c63..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Update_existing_data_in_SQL_table.html +++ /dev/null @@ -1,57 +0,0 @@ -Update existing data with the SQL UPDATE command - My Zettelkasten - - - - -

Update existing data with the SQL UPDATE command

We use UPDATE to modify existing records in our table.

Schematic syntax

UPDATE [table_name]
-SET [field]
-WHERE [conditional expression/filter]

Example

UPDATE manufacturer
-SET url = '<http://www.hp.co.uk>'
-WHERE manufacturer_id = 4; --typically this will be the primary key as you are updating and existing record and need to identify it uniquely

Update multiple fields

UPDATE manufacturer
-SET url = '<http://www.apple.co.uk>',
-    year_founded = 1977
-WHERE manufacturer_id = 2;
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Useful_operators_in_SQL.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Useful_operators_in_SQL.html deleted file mode 100644 index a1c8d1b..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Useful_operators_in_SQL.html +++ /dev/null @@ -1,58 +0,0 @@ -Useful operators in SQL - My Zettelkasten - - - - -

Useful operators in SQL

True and false

In SQL false results are represented by 0 and true results are represented by 1. Any zero value is false and any non-zero value is true.

When comparing operators we can use SELECT as a general “execute” function for SQL to interpret

SELECT 0 = 0 -- 1
-SELECT 0.0 = 0 -- 1
-SELECT 9 >= 12 -- 0

Boolean operators

SQL supports all Boolean operators:

SELECT (9 > 7) AND (3 < 5) -- 1
-SELECT (3 > 1) OR (2 > 5) -- 1
-SELECT (3 > 1) XOR (5 > 1) -- 0

We also have IS and IS NOT for testing Boolean values:

SELECT (9 > 7) IS TRUE -- 1
-SELECT (9 > 7) IS NOT TRUE -- 0

NULL

  • NULL is neither true (1) or false (0). It has no value.
  • An empty string ("") is not NULL
SELECT 1 IS NULL -- 0
-SELECT 1 IS NOT NULL -- 1
-SELECT NULL IS NULL -- 1
-SELECT "" IS NULL -- 0
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/User_Space.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/User_Space.html deleted file mode 100644 index f5b3583..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/User_Space.html +++ /dev/null @@ -1,58 +0,0 @@ -User space - My Zettelkasten - - - - -

User space

User space is the portion of the main memory that the kernel allocates for user processes.

There is a hierarchy within the user space with several different groups of user processes:

-
Basic services
-
Run at the bottom level and therefore are closest to ther kernel. Comprises small components that perform single, uncomplicated tasks. Examples include network configuration, the communication bus, and diagnostic logging
-
Utiility services
-
The middle level: larger components such as mail, print, and database services
-
Services controllable by the user
-
The top level: complicated tasks that the user controls directly such as using a web-browser, editing a text file
-
-

What is a user?

A user is an entity that can run processes and own files.

At the level of users, a user is associated with a user name however the kernel does not manage usernames, it identifies users via numeric identifiers called user IDs.

Users exist in order to support permissions and access boundaries. A user may terminate or modify the behaviour of its own processes (within limits) but cannot interfere with another user’s proceses. In addition, users may own files and choose whether to share them with other users.

Root user (superuser)

A Linux system normally has a number of users in addition to the ones that correspond to the real human users. The most important is root. The root user can terminate and alter another user’s processes and access any file on the local system.

A person who can operate as root is an administrator on a typical user system.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/User_management_in_Linux.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/User_management_in_Linux.html deleted file mode 100644 index 2853ba2..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/User_management_in_Linux.html +++ /dev/null @@ -1,50 +0,0 @@ -User management - My Zettelkasten - - - - -

User management

Switch user

If already logged in as a user you can switch users with the command su - [username].

Login as root

If you are logged in as a standard user, if you use su - without specifying a username, then it will assume you wish to log in as root.

If you wish to login as root in the tty at startup, then use root as the username.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/User_management_on_AWS.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/User_management_on_AWS.html deleted file mode 100644 index 666388b..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/User_management_on_AWS.html +++ /dev/null @@ -1,50 +0,0 @@ -User management and roles - My Zettelkasten - - - - -

User management and roles

IAM

Identity and Access Management

An IAM user is an identity with long-term credentials that is used to interact with AWS in an account. An IAM login is different from a root login. The root user is the one who creates the AWS account and who has the power to delete it. The root user can create IAM logins so that other users can log in through dedicated IAM portals. The root user should also create an IAM login for himself and use that, set to administrator policies, for most activities, reserving root for the most consequential stuff like adding users etc.

Users and user groups

  • Use to create users and access rights accross the AWS services
  • Users get permissions through policies (use template or create your own)
  • You can also create user groups and add users to them to simplify role attribution

Roles

Roles are adopted by services rather than users. They run either periodically (from a cronjob say) or when they are hit from an API.

This allows you to assign policies to a role that a service can adopt when running. A good example is a lambda. Lambdas often need access to other services such as an S3 bucket or a DynamoDB table. Say you have a service that combines a lambda with a DynamoDB database. You could assign a role to the lambda and it would have access to the database.

Distinction between principal and identity

Both “principal” and “identity” refer to entities that can perform actions and interact with AWS resources. However, there is a subtle difference in their usage:

a principal is a specific type of entity that can take actions in AWS, while an identity is the unique identifier associated with that principal.

  1. Principal: In the context of IAM policies, a principal represents the entity that is allowed or denied access to AWS rThe principal is specified in the policy statement as the entity to which the permissions are granted or deniedesources. It can be an IAM user, an IAM role, an AWS service. The principal is specified in the policy statement as the entity to which the permissions are granted or denied.
  2. Identity: An identity, on the other hand, is a broader term that encompasses both the principal and the authentication credentials associated with that principal. It refers to the entity’s unique identifier, such as an IAM user’s username or an IAM role’s ARN (Amazon Resource Name). An identity is used for authentication purposes to verify the entity’s identity and determine its permissions.

Cognito

Amazon Cognito provides authentication, authorization, and user management for your web and mobile apps.

There are user pools and identity pools.

User pools provide sign-up and sign-in options for your app users. Identity pools provide AWS credentials to grant your users access to other AWS services.

You would use identity pools to manage access to API endpoints or S3 buckets. They can be authenticated or unauthenticated. For example if you want to use an image from S3 in a website you would authenticate for that, but you would explicitly have to specify that it is general access by applying the policy AmazonS3ReadOnlyAccess.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Using_GraphQL_with_Node.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Using_GraphQL_with_Node.html deleted file mode 100644 index 07d485d..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Using_GraphQL_with_Node.html +++ /dev/null @@ -1,67 +0,0 @@ -Using GraphQL with Node.js - My Zettelkasten - - - - -

Using GraphQL with Node.js

Create a basic Express server

First we create a basic server in Node using Express:

import express from "express";
-
-app.get("/", (req, res) => {
-  res.send("Graph QL test project");
-});
-
-app.listen(8080, () =>
-  console.log("Running server on port localhost:8080/graphql")
-);

Add GraphQL as middlewear

Next we introduce GraphQL as a piece of Node.js middlewear, with the app.use() method.

import { graphqlHTTP } from "express-graphql";
-
-app.use(
-  "/graphql",
-  graphqlHTTP({
-    schema: schema,
-    rootValue: resolvers,
-    graphiql: true,
-  })
-);
  • schema is a reference to our GraphQL schema - the structure of the fields that define our server.
  • rootValue is a reference to our resolvers.
  • graphiql is the GUI tool that will be served from the GraphQL endpoint at localhost:8080/graphql. This tool enables us to interrogate our data using the defined schema and see what data we would get back from frontend queries.
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Using_arguments_with_Apollo_Client.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Using_arguments_with_Apollo_Client.html deleted file mode 100644 index e1a88a6..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Using_arguments_with_Apollo_Client.html +++ /dev/null @@ -1,178 +0,0 @@ -Using arguments with Apollo Client - My Zettelkasten - - - - -

Using arguments with Apollo Client

What are arguments?

  • An argument is a value you provide for a particular field in a query.
  • The schema must define the arguments that a field accepts (if any)
  • The resolver invokes a field’s provided arguments to determine how to return specific data
  • Some example use cases of arguments:
    • retrieve specific objects
    • filter through a set of objects
    • transform a field’s returned value

Updated schema

In order to demonstrate arguments we need to expand the original schema.

Remember a Track is a group of modules that teaches about a specific topic. We are going to add:

  • description and numberOfViews fields to the original Track type
  • A new Module type
  • A field modules to the Track type that will be an array of type Module
type Query {
-  tracksForHome: [Track!]!
-}
-
-type Track {
-    id: ID!
-        authorId: String! // They added this on the sly
-    thumbnail: String
-    length: Int
-    modulesCount: Int
-    description: String
-    numberOfViews: Int
-    modules: [Module!]!
-}
-
-type Module {
-    id: ID!
-        length: Int
-}
-
-type Author {
-    id: ID!
-    name: String!
-    photo: String
-}

Adding additional query

Currently we only have one query in the schema (tracksForHome) and this returns an array of all the tracks. To demonstrate arguments we want to return a specific track by its id. We are going to add a query that enables this.

type Query {
-    track(id: ID!):  Track
-}

This query will take an id as an argument and the resolver will match the id to a given track and return that Track.

To define an argument for a field in the schema we add parentheses after the field name. In the parentheses we write the name of the argument and its type. If we have more than one argument we can separate them with commas.

Create resolver for new query

Now we have to create a resolver for our new track query. We will quickly run through the server-side process.

Update our RESTDataSource

class TrackAPI extends RESTDataSource {
-  constructor() {...}
-  getTracksForHome() {...}
-  getAuthor(authorId) {...}
-
-  getTrack(trackId){
-    return this.get(`track/${trackId}`);
-  }
-}
-

Add resolver to resolvers.js

const resolvers = {
-  Query: {
-    tracksForHome: (_, __, { dataSources }) => {
-      return dataSources.trackApi.getTracksForHome();
-    },
-    track: (_, { id }, { dataSources }) => {
-      return dataSources.trackAPI.getTrack(id);
-    },
-  },
-  Track: {
-    author: ({ authorId }, _, { dataSources }) => {
-      return dataSources.trackApi.getAuthor(authorId);
-    },
-  },
-};

Making a query

With the server changes complete, we can now issue a query with an argument from the client:

query track(id: 'xyz'){
-  title
-}

This will return the title field from the track with the specific id. This query complies with the schema since the Track type has the field title

Resolver chains

What about the following query:

query track(id: 'xyz'){
-  title
-  author {
-    name
-  }
-}

It’s not obvious how the resolver should respond to the nested query here since author name is not a field on Track, it is a field on Author:

type Track {
-  id: ID!
-    authorId: String!
-  thumbnail: String
-  length: Int
-  modulesCount: Int
-  description: String
-  numberOfViews: Int
-  modules: [Module!]!
-}
-
-type Author {
-  id: ID!
-  name: String!
-  photo: String
-}

This is where we use a resolver chain. Because authorId exists on Track we can use this to get the name part of the query. We already have a resolver for author under the Track resolver:

Track: {
-    author: ({ authorId }, _, { dataSources }) => {
-      return dataSources.trackApi.getAuthor(authorId);
-    },
-  },

Notice that authorId is used in the place of the parent parameter. It already exists on the Track type that wraps the resolver. So this can be invoked to fulfill author and thereby access the author name from the graph.

This process is also required for our extended schema. The Track type now has a modules field that comprises an array of the Module type.

Here’s a reminder of the Module type:

type Module {
-    id: ID!
-        length: Int
-}

The modules for a Track can be sourced from the track id. So we can again add a resolver chain function to the resolvers file:

const resolvers = {
-  Query: {
-    tracksForHome: (_, __, { dataSources }) => {
-      return dataSources.trackApi.getTracksForHome();
-    },
-    track: (_, { id }, { dataSources }) => {
-      return dataSources.trackAPI.getTrack(id);
-    },
-  },
-  Track: {
-    author: ({ authorId }, _, { dataSources }) => {
-      return dataSources.trackApi.getAuthor(authorId);
-    },
-    modules: ({ id }, _, { dataSources }) => {
-      return dataSources.trackAPI.getTrackModules(id);
-    },
-  },
-};

Once again we are using a property on the parent Track type to use as a parameter in the resolver function.

This setup would enables like the following to be run:

query track(id: 'xyz'){
-  title
-  modules
-}

The id parameter would be used by the modules resolver to return the array of the Modules type.

Variables in arguments

Instead of writing the following within our query constants on the client-side:

query GetTrack {
-  track(id: 'xyz'){
-    title
-  }
-}

We can make the code more reusable by using variables instead of the hardcoded id argument:

query GetTrack($trackId: ID!) {
-  track(id: $trackId){
-    title
-  }
-}

This way we do not need to write a new query constant every time we want to return a specific track.

Send query with arguments using Apollo useQuery

We can now write a proper query using the useQuery hook from Apollo Client, with variables.

First define our query constant:

export const GET_TRACK = gql`
-  query GetTrack($trackId: ID!) {
-    track(id: $trackId) {
-      id
-      title
-      author {
-        name
-      }
-      description
-      modules {
-        id
-        title
-        length
-      }
-    }
-  }
-`;

Then to employ in React:

const trackId = "xyz";
-
-const { loading, error, data } = useQuery(GET_TRACK, {
-  variables: {
-    id: trackId,
-  },
-});

Note that in contrast to the simple example because we are using variables, we have to pass-in an additional options object with the query constant that specifies our variables.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Utilities_operators_flags.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Utilities_operators_flags.html deleted file mode 100644 index ba80179..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Utilities_operators_flags.html +++ /dev/null @@ -1,57 +0,0 @@ -Utilities, operators, flags in Bash - My Zettelkasten - - - - -

Utilities, operators, flags in Bash

The following are useful built-in utility methods that you can use for checking and validation in the course of your bash scripts.

Flags

Prevent newline

Prevent bash from adding a new line after an echo:

echo 'Your name is Thomas'
-echo 'and you are 33 years old'
-
-# Your name is Thomas
-# and you are 33 years old
echo -n 'Your name is Thomas '
-echo 'and you are 33 years old'
-
-# Your name is Thomas and you are 33 years old

Operators

Mathematical

-lt , -gt,
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Validating_Mongoose_schemas.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Validating_Mongoose_schemas.html deleted file mode 100644 index 93de2c3..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Validating_Mongoose_schemas.html +++ /dev/null @@ -1,68 +0,0 @@ -Validating Mongoose schemas - My Zettelkasten - - - - -

Validating Mongoose schemas

Let’s say we have the following schema:

const courseSchema = new mongoose.Schema({
-  name: { type: String, required: true, minlength: 5, maxlength: 255 },
-  author: String,
-  tags: [String],
-  data: { type: Date, default: Date.now }, // if unspecified, entry will default to current date
-  isPublished: Boolean,
-});

We set our validation criteria as the second property for each schema value. If it does not obtain, an exception will be thrown when we attempt to modify the database. This will most likely take the form of a Promise rejection.

Note that this validation only occurs at the level of Mongoose. There is no mechanism for running the validation within the database itself. This is one of the ways that Mongo differs from an SQL database where you would be able to set the property of required for a cell in the table. If we didn’t set any validation via Mongoose, Mongo would accept whatever we sent to it.

What is the relationship between this Mongoose validation and the Joi validation that we use when validating API requests in Node/Express? They complement each other. We use Joi to validate the client request to the API. If this is valid, the process would then move onto the next stage which would be transforming the data from a REST request to a database request implemented through Mongoose, where a second layer of validation would appy. We would also have validation on the client-side.

Validator functions

Instead of simply applying a built-in validator like required, we can instead pass a function that validates agains the validation status of another property in the schema. For instance: make the price property required only if the entry has true for isPublished:

const courseSchema = new mongoose.Schema({
-  ...
-  isPublished: Boolean,
-  price: {
-    type: Number,
-    required: function() {return this.isPublished}
-  }
-});

Enum validators

An enum validator enables us to ensure that whatever value is passed when instantiating a document that is of a given schema type, it must be one of a finite set of values:

const anotherSchema = new mongoose.Schema({
-  sex: {
-    type: String,
-    enum: ["male", "female"],
-  },
-});
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Validation_in_NodeJS.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Validation_in_NodeJS.html deleted file mode 100644 index b033d82..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Validation_in_NodeJS.html +++ /dev/null @@ -1,57 +0,0 @@ -Creating a RESTful API: Validation - My Zettelkasten - - - - -

Creating a RESTful API: Validation

We can provide server-side validation for our projects by using a schema validator. This is a program that declaratively parses the JSON values received as requests from the client. This makes it easy to systematically validate the data that we receive from any HTTP requests where the client sends a body to the endpoint.

One of the most popular schema validators for NodeJS is joi.

Demonstration

Let’s say we have a POST request that expects a single field as the body that must be a string and greater than two characters long. First we define our schema:

const schema = Joi.object({
-  name: Joi.string().min(3).required(),
-});
-
-const { error } = schema.validate(req.body);

The schema variable is an object whose keys should match those of the intended request body. Instead of actual values we provide Joi’s in-built validators, concatenated as necessary. We then store the results of the validation in a variable.

Next we add handling in the case of errors:

if (error) {
-  error.details.map((joiErr) => res.status(400).send(joiErr.message));
-  return;
-}

We loop through the error array and return 400s as the response if they are found. If there are no errors, the Joi object will return undefined.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Validity_and_entailment.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Validity_and_entailment.html deleted file mode 100644 index b4f1986..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Validity_and_entailment.html +++ /dev/null @@ -1,57 +0,0 @@ -Validity and entailment - My Zettelkasten - - - - -

Validity and entailment

Informal definition

In order to say whether an argument is ‘good’ or ‘bad’ we must have criteria of evaluation. in logic there are different criteria of evaluation:

  • Deductive validity

    An argument is deductively valid if and only if it is not possible for the premises to be true and the conclusion false. Linking to consistency: it is not possible to consistently assert all of the premises but deny the conclusion.

  • Inductive strength

    We do not say that inductive arguments have ‘validity’ because despite inductive premises being true, the conclusion may be falsifiable. Therefore we say inductive ‘strength’ rather than ‘validity’. An argument is inductively strong if and only if the conclusion is probably true given the premises.

Demonstration

The Socrates demonstration above is an example of deductive validity.

The following is an example of an argument that is inductively strong:

99% of deaf persons have no musical talent.
-Beethoven was deaf.
-___________________________________________
-Beethoven had no musical talent.

The test for a strong inductive argument is not whether the conclusion is true, rather it concerns the evidence the premises provide in support of the conclusion.

In propositional logic we are concerned solely with deductive validity or invalidity.

Formal definition

An argument is truth-functionally valid if and only if there is no truth-assignment on which all the premises are true and the conclusion is false.

Linking this to derivation, we say:

In a system of derivation in propositional logic, an argument is valid if the conclusion of the argument is derivable within the system of derivation from the set consisting of the premises, and invalid otherwise.

Demonstration

The inference from the set \({P, P \rightarrow Q}\) to \(Q\) is valid

Truth-table

\(P\)\(Q\)\(P \rightarrow Q\)\(P\)\(Q\)Assessment
TTTTTValid
TFFTF
FTTFT

Entailment

Informal definition

Entailment as a concept is almost identical to validity. We say that a proposition is entailed by a set of propositions if it is not possible for every member of this set to be true and the proposition to be false.

The difference with validity resides in the fact that the propositions are distinguished in terms of whether they are premises or a conclusion. So, technically, validity is a subclass of entailment. A case of entailment where we distinguish propositions in terms of whether they are premises or conclusions. A proposition may be entailed by a given set without that proposition being the conclusion of the set and where the set is a syllogism.

Formal definition

A finite set of sentences \(\Gamma\) \(\vdash\) \(P\) if and only if there is no truth-assignment in which every member of \(\Gamma\) is true and \(P\) is false.

Informal demonstration

It is raining.
-If it is raining then the pavement will be wet.
-The pavement is wet.

Formal demonstration

$$ -\{ P, P\rightarrow Q \} \vdash Q -$$

Truth-table

\(P\)\(Q\)\(P \rightarrow Q\)\(P\)\(Q\)Assessment
TTTTTValid
TFFTF
FTTFT
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Variable_indirection_in_Bash.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Variable_indirection_in_Bash.html deleted file mode 100644 index 4c2b127..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Variable_indirection_in_Bash.html +++ /dev/null @@ -1,77 +0,0 @@ -Variable indirection - My Zettelkasten - - - - -

Variable indirection

Write proper notes on this

function array_empty() {
-    declare -n arr=$1
-    # Proceed if array not empty:
-    if [ ${#arr[@]} -gt 0 ]; then
-        return 1 # array is not empty
-    else
-        return 0 # array is empty
-    fi
-}
-
-my_array=(1 2 3)
-
-function push() {
-    # $1 = stack name
-    local stack_name="$1"
-    if [ "${stack_name}" ]; then # stack exists
-        if array_empty "${!stack_name}"; then
-            echo "stack is empty"
-        else
-            echo "stack is not empty"
-        fi
-    else
-        echo "Error: ${stack_name} does not exist."
-    fi
-}
-
-push "my_array"
-

In Bash scripting, ${!stack_name} is an example of indirect variable referencing or variable indirection. It’s a way to use a variable whose name is stored in another variable.

Let’s break it down:

${stack_name}: This syntax is used to reference the value of a variable. So if stack_name=“my_array”, then ${stack_name} would return “my_array”.

${!stack_name}: Adding the ! introduces indirection. Now, instead of getting the value of stack_name, you get the value of the variable whose name is stored in stack_name. So if stack_name=“my_array” and my_array=(1 2 3), then ${!stack_name} would return (1 2 3).

So, in the context of your script, `${!stack_name} allows you to pass the name of an array (as a string) to your push function, and then use that string to indirectly reference the actual array within the function.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Variables_and_data_types_in_Bash.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Variables_and_data_types_in_Bash.html deleted file mode 100644 index fed7920..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Variables_and_data_types_in_Bash.html +++ /dev/null @@ -1,62 +0,0 @@ -Variables and datatypes in Bash - My Zettelkasten - - - - -

Variables and datatypes in Bash

Types

Variables

We use the equality symbol to create a variable:

stringVar="My first variable"
-floatVar="50.3"
-boolVar="true"

As there is no typing in bash, the names of these variables are purely notional.

To invoke a variable we use special brackets:

echo ${stringVar} # My first variable
-echo ${floatVar} # 50.3
-echo ${boolVar} # true
  • Quotation marks at declaration are also not strictly necessary however they can help avoid bugs. Also serves as a reminder that every type is basically a string at the end of the day

Common operations

Check if a variable exists

if [ -v variable_name ]; then
-    echo "The variable exists."
-else
-    echo "The variable does not exist."
-fi

Check if a variable is set (defined)

if [ -z "${variable_name+x}" ]; then
-    echo "The variable does not exist."
-else
-    echo "The variable exists."
-fi

Parameter expansion

Still not very clear on this.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Variables_in_C.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Variables_in_C.html deleted file mode 100644 index f9d3762..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Variables_in_C.html +++ /dev/null @@ -1,50 +0,0 @@ -Variables in C - My Zettelkasten - - - - -

Variables in C

int age = 25
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Viewing_remote_changes_without_merging.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Viewing_remote_changes_without_merging.html deleted file mode 100644 index cf83d24..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Viewing_remote_changes_without_merging.html +++ /dev/null @@ -1,52 +0,0 @@ -Viewing remote changes without merging - My Zettelkasten - - - - -

Viewing remote changes without merging

git fetch origin/master
-git log origin/main
-git show origin/master
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Views_in_relational_databases.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Views_in_relational_databases.html deleted file mode 100644 index a794e7c..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Views_in_relational_databases.html +++ /dev/null @@ -1,50 +0,0 @@ -Views in relational databases - My Zettelkasten - - - - -

Views in relational databases

A view is a virtual table that is based on the result-set of a query. Although it doesn’t actually exist in the same manner as an actual table it has exactly the same properties and functionality. Rather than adding the raw data manually, you derive it from logic applied to existing actual tables.

This is a good way of dynamically generating data and is often employed as a way of creating mutations without changing the underlying data structure. In SQL, views can be created by combining PRIMARY and FOREIGN keys.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/VirtualMemory.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/VirtualMemory.html deleted file mode 100644 index 9c41ec0..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/VirtualMemory.html +++ /dev/null @@ -1,50 +0,0 @@ -Virtual memory - My Zettelkasten - - - - -

Virtual memory

Virtual memory is an abstracted and idealised representation of the physical memory capacity of a machine that is presented to user space for its memory operations.

When an OS implements virtual memory, processes in user space cannot directly read or write to the physical memory. Instead they execute memory operations against virtual memory and the kernel translates these into the actual operations against the memory hardware.

The main benefits:

  • User mode processes do not have to be concerned with the physical memory management
  • There is a buffer between user mode processes and physical memory, meaning that memory cannot be accidentally corrupted by other processes in user space.

Because the physical memory is abstracted, it can be the case that the physical memory addresses are non-contiguous or even distributed accross different hardware components (such as the cache and swap). Despite this, the memory addresses will appear contiguous in virtual memory. Each user space process is presented with the same range of available memory addresses and the same total capacity.

It is also possible for the kernel to present user space with an available virtual memory capcacity that exceeds the current physical capacity of the machine:

It’s possible for the kernel and all running processes to request more bytes of virtual memory than the total size of RAM. In that situation, the OS can move move bytes of memory to secondary storage to make room in RAM for newly requested memory.

How Computers Really Work (2021) p.206

Virtual memory and the kernel

The kernel itself utilises virtual memory.

During the boot_process, it runs in physical memory mode however it rapidly creates a 1:1 mapping of physical to virtual memory for itself. This direct mapping allows the kernel to easily access any physical memory location as needed, whilst retaining the benefits of virtual memory.

With its own virtual memory established, it can then build additional virtual memory structures for itself and user processes.

While the kernel uses virtual memory it can also access physical memory at any time wherease user space processes can only ever access virtual memory.

The kernel virtual memory has a different range of virtual addresses to work with than user space virtual memory.

Unlike user space virtual memory, the kernel has access to everything running in kernel address space whereas processes in user address space are partitioned from each other with separate address spaces that cannot interact.

In addition to being able to access its own virtual memory (and physical memory, as required) the kernel can also access any user processes’ virtual address.

This said, the virtual memory space of the kernel and the virtual memory space of the user processes are distinct. It is not the case that the kernel is superset of all available virtual memory. It can access user space virtual memory because it sets up the tables and locations, not because it is a subset of its own virtual memory.

Virtual memory diagram

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Virtual_private_cloud.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Virtual_private_cloud.html deleted file mode 100644 index 511484e..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Virtual_private_cloud.html +++ /dev/null @@ -1,50 +0,0 @@ -Virtual Private Cloud - My Zettelkasten - - - - -

Virtual Private Cloud

AWS VPC is used to create a virtual network. This is typically used in concert with zk/Elastic_Compute_Cloud to manage connections to a virtual server both privately and accross the internet.

You define a network address range and then create subnets for managing different connections and functionality. You use a public subnet for resources that must be connected to the internet and a private subnet for resources that are to remain isolated from the internet.

The diagram below details a basic VPC configuration:

  • Within a given AWS region we have created a VPC network.
  • This comprises public and private subnets
  • Both subnets host an EC2 instance
  • The public subnet has a bridge to the internet through the Internet Gateway
  • Both subnets have a routing table to manage requests and access
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Voltage.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Voltage.html deleted file mode 100644 index 9865e12..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Voltage.html +++ /dev/null @@ -1,54 +0,0 @@ -Voltage - My Zettelkasten - - - - -

Voltage

Difference of potential and the transfer of energy

We noted in the discussion of current that current flows when there is a difference of potential between two points with negatively charged atoms at one point and positively charged atoms at the other.

Difference of potential is the same thing as voltage. Voltage is essential to current because it is the force that enables the current to flow.

Without voltage there can be no current because in their natural state, the electrons in an atom are in random motion with no direction. To produce a current, energy must be imparted to the electrons so that they all flow in the same direction.

Voltage is the application of this energy. Any form of energy that dislodges electrons from atoms can be used to produce current. Thus:

Voltage is the work required per coulomb to move a charge from one point to another.

Voltage exists even without current

Given that voltage is the force that generates current, it would be natural to think that voltage only exists when a voltage source (such as a battery) is connected to a circuit. This however is not the case. Even if a 9V battery isn’t connected to anything it still has a difference of potential of 9-volts accross its terminals. Remember voltage is potential energy not just the actualisation of that energy.

Voltage rise and voltage drops

In circuits there are actually two types of voltage:

  1. Voltage rise
  2. Voltage drop

Voltage rise

When we introduce potential energy into a ciruit in the form of voltage, this is a voltage rise. The current flows from the negative terminal of the voltage source and returns to the positive terminal of the voltage source.

A 12V battery connected to a circuit gives it a voltage rise of 12 volts.

Voltage drop

Voltage drop is the corrolary to voltage rise. It is the loss of energy that the electrons of the circuit current experience as a result of encountering resistance.

As they move through the circuit the electrons encounter a load which is what we call resistance to the flow of current. As they run into this, they give up their energy. The relinquishing of energy happens in the form of a conversion of electrical energy to heat (hence why computers heat up). The amount lost is equal to the amount of energy imparted by the voltage rise.

The voltage drop in a circuit equals the the voltage rise of the circuit because energy cannot be created or destroyed, only changed to another form. When a voltage rise is converted to a voltage drop we say that the energy has been consumed by the circuit.

Examples

  • If a 12V source is connected to a 12V lamp, the source supplies a 12V voltage rise and the lamp produces a 12V voltage drop.
  • If two identical 6V lamps are connected in series to the same 12V source, each lamp produces a 6V drop for a total of 12 volts
  • If two different lamps are connected in series to to a 12V source: a 3V and a 9V lamp, the 9V lamp produces a drop of 9V and the 3V lamp produces a drop of 3V. The sum of the voltage drops equals the voltage rise of 12 volts.

These examples demonstrate that the voltage rise: voltage drop ratio always evens out.

Kirchoff’s Voltage Law

The relationship between voltage rise and voltage drop is expressed in Kirchoff’s Voltage Law:

The sum of the voltages around any closed loop in a circuit must be zero.

The application of the Law is illustrated in the following diagram:

The explanation for the voltage drop at the positions \(V^{A}\) and \(V^{D}\) are obvious enough: they are at the beginning and end of the loop so are equal to the maximal voltage rise and minimal voltage drop, respectively.

We can work out the voltage of the remaining voltage points by inverting Ohm’s Law: \(V = I \times R\):

For the voltage at \(V^{B}\):

$$ -0.5\textsf{mA} \times \textsf{4}k\Omega = 2 \textsf{V} -$$

For the voltage at \(V^{C}\):

$$ -0.5\textsf{mA} \times \textsf{6}k\Omega = 3 \textsf{V} -$$

The total drops (2V, 3V, 5V) are equal to the initial volatage rise (10V)

Distinguishing voltage from electric field

It can be confusing that two different symbols often seemed to be used interchangeably when talking about voltage: \(V\) and \(E\). However, while they broadly point to the same phenomenon there is a difference in emphasis.

  • \(V\) stands for volts or voltage conceived purely in terms of the difference in potential between two points: the positive and negative terminals
  • \(E\) stands for electric field. This is the field that surround each electric charge and exerts force on all other charges in the field, attracting or repelling them. So it is more the physical process that the volatage represents rather than the numerical representation of the potential between the terminals.
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Voltage_sources.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Voltage_sources.html deleted file mode 100644 index 6db849f..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Voltage_sources.html +++ /dev/null @@ -1,50 +0,0 @@ -Voltage sources - My Zettelkasten - - - - -

Voltage sources

The following phenomena are the main sources that we use to generate voltage:

  • friction
  • magnetism
  • chemicals
  • light
  • heat
  • pressure

In each case, energy in one state is transferred into energy as current. No energy is lost or gained, it simply changes its form.

Magentism (electrical generators)

Magnetism is used as the voltage source in electrical generators and is by far the most common method of producing powerful and large currents at scale.

If a conductive wire is passed through a magnetic field voltage will be produced so long as there is motion between the magnetic field and the conductor. A generator is a device that generates current in this manner. Generators themselves need to be powered. They can be powered by steam from a nuclear power plant, water, wind, coal or other fossil fuels.

AC/DC

Depending on how it is wired, a generator can produce directed current (DC) or alternating current (AC):

  • Directed current

    • The electrons flow in only one direction
  • Alternating current

    • The electrons flow in one direction and then the other

Chemicals (cells and batteries)

The chemical creation of current is the physics behind batteries. Chemical current production produces currents on a smaller and less industrial scale than generators.

A chemical cell consists in two dissimilar metals such as copper and zinc. We call these the electrodes. They are immersed in a salt, acid or alkaline solution. We call these the electrolytes. The electrolyte pulls the free electrons from the copper electrode which leaves it imbalanced with a positive charge. The zinc electrode attracts the free electrons from the electrolyte giving it a negative charge, thus a difference of potential is achieved.

Light (photovoltaic cells)

Solar energy can be converted to electrical energy through solar panels which are large collections of photovoltaic cells.

When the surfaces of these cells are exposed to light, it dislodges electrons from their orbits around the surface atoms of the cell material. For each cell this only produces a very small amount of energy, therefore large quantities must be used.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/What_are_disks.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/What_are_disks.html deleted file mode 100644 index 822d619..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/What_are_disks.html +++ /dev/null @@ -1,50 +0,0 @@ -What are disks? - My Zettelkasten - - - - -

What are disks?

A disk is a mass storage block_device which we can write to and read from.

SCSI

  • Small Computer System Interface, responsible for handling disk access on most Linux systems.
  • It is a protocol that allows communicaton between printers, scanners and other peripherals in addition to harddisks.

Disk schematic

The following diagram represents the basic anatomy of a disk device.

  • A disk is divided up into Partitions which are subsections of the overall disk. The kernel presents each partition as a block device as it would with an entire disk.
  • The disk dedicates a small part of its contents to a partition table: this defines the different partitions that comprise the total disk space.
  • The filesystem is a database of files and directories: this comprises the bulk of the partition and is what you interact with in user space when reading and writing data.
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/What_is_memory.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/What_is_memory.html deleted file mode 100644 index bfcaf8d..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/What_is_memory.html +++ /dev/null @@ -1,50 +0,0 @@ -What is memory ? - My Zettelkasten - - - - -

What is memory ?

A CPU is just an operator on memory. It reads its instructions and data from the memory and writes back out to the memory. (Ward 2021)

When a CPU executes a program, it needs a place to store the program’s instructions and related data. This is the role of memory.

The data that comprises a program is a series of bits. The basic unit of memory storage is a memory cell: a circuit that can store a single bit.

RAM memory is volatile : the memory is only retained whilst the computer has a power supply and is wiped when the computer is rebooted. This contrasts with the memory of the harddisk which is non-volatile and is retained after a reboot.

Programs that are executing are loaded into memory because the chips that comprise memory can read and store data much faster than the harddisk. It would be possible to run a program from the harddisk but it would be 500 - 1000 times slower than memory.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Whole_numbers.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Whole_numbers.html deleted file mode 100644 index 1cb2368..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Whole_numbers.html +++ /dev/null @@ -1,50 +0,0 @@ -The set of whole numbers - My Zettelkasten - - - - -

The set of whole numbers

We recall the set of whole numbers:

$$ \mathbb{W} = {0, 1, 2, 3, ...} $$

The properties of \(\mathbb{W}\)

In mathematics, a property is any characteristic that applies to a given set.

The commutative property

Addition

When adding whole numbers, the placement of the addends does not affect the sum.

Let a, b represent whole numbers, then:

$$ a + b = b + a $$

Multiplication

When multiplying whole numbers the placement of the Symbols-and-formal-conventions-80aeaf1872f94a0d97a2e8d07e3855bd does not affect the Symbols-and-formal-conventions-80aeaf1872f94a0d97a2e8d07e3855bd.

Let a, b represent whole numbers, then:

$$ a \cdot b = b \cdot a $$

Subtraction

Subtraction is not commutative, viz:

$$ a - b \neq b - a $$

Division

Division is not commutative, viz:

$$ a \div b \neq b \div a $$

The associative property

Addition

When grouping symbols (parentheses, brackets, braces) are used with addition, the particular placement of the grouping symbols relative to each of the addends does not change the sum.

Let a, b, c represent whole numbers, then:

$$ (a + b) + c = a + (b + c) $$

Multiplication

Let a, b, c represent whole numbers, then:

$$ a \cdot (b \cdot c) = (a \cdot b) \cdot c $$

Subtraction

Subtraction is not associative, viz:

$$ (a - b) - c \neq a - (b - c) $$

Division

Division is not associative

$$ (a \div b) \div c \neq a \div (b \div c) $$

The property of additive identity

If a is any whole number, then:

$$ a + 0 = a $$

We therefore call zero the additive identity: whenever we add zero to a whole number, the sum is equal to the whole number itself.

The property of multiplicative identity

If a is any whole number, then:

$$ (a \cdot 1 = a) = (1 \cdot a = a) $$

Multiplication by zero

If a is any whole number, then:

$$ (a \cdot 0 = 0) = (0 \cdot a = 0) $$

Division by zero

Division by zero is undefined but zero divided is zero.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Why_computers_use_binary.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Why_computers_use_binary.html deleted file mode 100644 index 9105c27..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Why_computers_use_binary.html +++ /dev/null @@ -1,50 +0,0 @@ -Why computers use binary - My Zettelkasten - - - - -

Why computers use binary

Now we know how binary works, how does it relate to computing?

The reason is straight forward: it is the simplest way on the level of pure engineering of representing numerical and logical values; both of which are the basic foundations of programming. An electronic circuit or transistor only needs to represent two states: on (1) and off (0) which corresponds to the switch on an electrical circuit. A single circuit representing the binary values of 1 and 0:

multi_on_off 1.gif

It would be much more complicated to have to represent ten different states under the decimal number system, although denary computers do exist.

If we want more digits, we just need to add in more circuits, and we can represent as large a binary number as we need. We just need one switch for every digit we want to represent. The switches used in modern computers are so cheap and so small that billions can be fitted on a single circuit board.

multiple_circuits.gif

When we use the term ‘switch’ we actually mean the transistor components of a circuit. We don’t need to know the physical details at this level but we can say that a transistor turns a current on and off. They can also be used to amplify the current.

On the level of electrical engineering and in the subsequent examples using a light bulb and a simple circuit, the switch being OFF corresponds to the light being ON, this is because the switch breaks the current. So when it is unbroken, the current passes to the bulb. This also means that 1 corresponds to the switch being OFF and 0 corresponds to the switch being ON which can be confusing at first.

From circuits to programs

The following breaks down how we get from the binary number system to electrical circuits to computer programs:

  1. ”Data”= a piece or pieces of information

  2. In computing all data is represented in binary form:

    2.1. ”Binary” means that the value of a piece of data is exclusively one thing or another

    2.2. The values in binary code are exclusively 1 and 0 (either a piece of data is a 1 or it is a 0, it can never be both). Binary can also be expressed in logical terms where 1 is equal to true and 0 is equal to false

  3. The smallest piece of data is a bit

  4. We apply the binary number system to bits

  5. Thus by 1-4, a bit is either 1 or 0

  6. Binary form bears an isomorphic relation to switches on electrical circuits (the hardware of computers). Thus binary code can be mapped onto circuits.

    • Circuits are controlled by switches
    • A switch is a binary function: it is either on or off ”On/off” corresponding to 1/0.
    • In this way, switches control the flow of electric current
  7. Thus by the above, hardware (which is a physical structure made up of electric circuits) is readily programmable in binary terms

  8. Restatement of 6: in order for hardware to be programmed the program must provide the hardware with something that it can actually perform. The program must be formulated in binary code.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Wildcards_in_SQL.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Wildcards_in_SQL.html deleted file mode 100644 index 1b647a4..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Wildcards_in_SQL.html +++ /dev/null @@ -1,54 +0,0 @@ -Wildcards in SQL - My Zettelkasten - - - - -

Wildcards in SQL

SQL does not use Regex. Instead it has a simpler glob-like syntax for carrying out string matching.

In order to signal that you wish to compare by a wildcard and not a value, you have to use the LIKE keyword. The actual wildcard operator is % .

In an SQL statement, the % wild card will match any number of occurrences of any character. Any characters can appear before or after ‘MacBook’ and the record will still be returned:

SELECT name, cores, release_date
-FROM model
-WHERE name LIKE '%MacBook%';

This wildcard only filters characters that come after Raspberry :

SELECT name, cores, release_date
-FROM model
-WHERE name LIKE 'Raspberry%';
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Williams_Tube_memory.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Williams_Tube_memory.html deleted file mode 100644 index f8595a2..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Williams_Tube_memory.html +++ /dev/null @@ -1,50 +0,0 @@ -Williams Tube memory - My Zettelkasten - - - - -

Williams Tube memory

  • One of the early attempts to create RAM in computers based on the EDVAC stored-program architecture.

  • Worked by displaying a grid of dots on a cathode-ray tube (“screen”)

  • Due to the way CRTs work, this creates a small charge of static electricity over each dot. The charge at the location of each of the dots is read by a thin metal sheet just in front of the display.

  • Each dot position could be written to and read from and the pattern was constantly refreshed as the dots would fade over time.

A Williams CRT tube

Memory dot pattern from a Williams Tube

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Working_with_CSVs_in_Python.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Working_with_CSVs_in_Python.html deleted file mode 100644 index c8f90a0..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Working_with_CSVs_in_Python.html +++ /dev/null @@ -1,58 +0,0 @@ -Working with CSVs in Python - My Zettelkasten - - - - -

Working with CSVs in Python

Core package

import csv

Read and write to CSV

Read

Use standard Pythonic “read” syntax:

with open('./path.csv', mode="r") as csv_file:
-    reader = csv.reader(csv_file)

Parse values

Having created the reader object, you can then loop through this as an iterable:

for row in reader:
-    print(row)

Will return something like:

column something, column something else, ...

Which we can individuate with:

print(row[0])
-# column something

We can also parse the rows as a dictionary for easier individuation. We do this by creating a DictReader rather than the default reader:

...
-dict_reader = csv.DictReader(csv_file)

Now we can use the header row values to individuate particular columns.

Say we have a CSV with the following headers:

name, profession

We can individuate thus:

for row in dict_reader
-    name = row["name"]

Write

Use standard Pythonic “read” syntax:

with open('./new_csv_file.csv', mode="w") as csv_file:
-    writer = csv.writer(csv_file)

The above will create the file as well, it doesn’t need to be pre-existing.

This creates the writer object. To actually write a row:

some_list = ['thomas', 'engineer']
-for element in some_list:
-    writer.writerow(element)
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Working_with_JSON_in_Python.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Working_with_JSON_in_Python.html deleted file mode 100644 index db7f72c..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Working_with_JSON_in_Python.html +++ /dev/null @@ -1,50 +0,0 @@ -Working with JSON in Python - My Zettelkasten - - - - -

Working with JSON in Python

json.loads()

Convert a string containing JSON data into the native Python dictionary object. Equivalent to JSON.parse() in JavaScript.

Will error if the input string is not properly formatted JSON. This will be json.JSONDecodeError, a subclass of the ValueError exception

json.dumps()

Take a JSON-formatted dictionary and convert it into a string. The reverse of json.loads() and equivalent to JSON.stringify() in JavaScript.

JSON errors

The .loads() and .parse() methods will throw an error if the input string is

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Working_with_numbers_in_Bash.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Working_with_numbers_in_Bash.html deleted file mode 100644 index 11958dd..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Working_with_numbers_in_Bash.html +++ /dev/null @@ -1,62 +0,0 @@ -Working with numbers in Bash - My Zettelkasten - - - - -

Working with numbers in Bash

We distinguish:

  • arithmetic expansion $(( ))
    • returns the result of literal numbers that can then be stored in a variable
  • artihmetic evaluation (( ))
    • perform calculations on existing variables

An example of expansion:

a=3
-((a += 3))
-echo $a
-# 6
-((a++))
-# 7

Note: we do not use a dollar-sign when referring to variables within arithmetic evaluation, there is no need. If we do, we get an error. This is because we are using an expansion, therefore the variables are already being interpreted as variables.

Declaring variables as integers

It is good practice to safeguard against Bash treating numbers as strings to declare them as integers in addition to using arithmetic evaluation, e.g:

declare -i b=3

Whilst this isn’t a strict type, it means we can do this:

b=$b+4
-echo b
-# 7

Without getting 3+4 in return

No decimals in bash

Bash does not support decimal calculations natively. This is what you’d get for example:

echo $(( 1/3 ))
-# 0 (not 0.33)

So work with decimals you should use awk or bc (“basic calculations”).

Example of using bc:

declare -i c=1
-declare -i d=3
-e=$(echo "scale=3; $c/$d" | bc)
-# 0.333

Random numbers

Generate a pseudo-random number between 1 and 20:

echo $(( 1 + RANDOM % 10))
-# 18
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Zero_property_of_multiplication.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Zero_property_of_multiplication.html deleted file mode 100644 index 500a642..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Zero_property_of_multiplication.html +++ /dev/null @@ -1,50 +0,0 @@ -Zero property of multiplication - My Zettelkasten - - - - -

Zero property of multiplication

Let \(a\) represent any member of \(\mathbb{W}\) or \(\mathbb{Z}\) then:

$$ a \cdot 0 = 0 $$

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Zip_function_in_Python.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Zip_function_in_Python.html deleted file mode 100644 index 8c23e75..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/Zip_function_in_Python.html +++ /dev/null @@ -1,75 +0,0 @@ -zip - My Zettelkasten - - - - -

zip

The zip function returns a zip object when you pass in two iterator data types (typically two lists). This is an iterator of tuples where the first item in each passed iterator is paired together, and then the second item in each passed iterator are paired together, and so on.

Example

a = ("John", "Charles", "Mike")
-b = ("Jenny", "Christy", "Monica", "Vicky")
-
-x = zip(a,b)
-
-print(x)
-# <zip object at 0x1514af34c340>
-
-# To display the resulting tuple in a readable format:
-
-print(tuple(x))
-
-(('John', 'Jenny'), ('Charles', 'Christy'), ('Mike', 'Monica'))

As indicated above, if the input iterators are of equal lengths, Python will ignore the value in iterator B that doesn’t have an equivalent index in iterator A.

Real-life example

prompts = [
-    "Enter title",
-    "Enter author",
-    "Enter publication date",
-    "Enter year you read the book"
-]
-
-keys = ["Title", "Author", "Publication_date", "Date_read"]
-
-book = {}
-
-for key, prompt in zip(keys,prompts):
-    book[key] = input(prompt + ": ")
-

Here I take the prompts and keys lists, collate them via zip and then loop through them to populate the book dictionary, which contains properties sourced from the keys list and values from the user’s answers to the prompts.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/cache.json b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/cache.json deleted file mode 100644 index b0fb265..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/cache.json +++ /dev/null @@ -1 +0,0 @@ -{"Graph":{"adjacencyMap":{"Using_arguments_with_Apollo_Client":{"Apollo_Server":["cf",[]]},"Conjunction_Elimination":{},"Equivalent_equations":{},"Monitoring_processes_and_resources":{"Swap_space":["cf",[]],"Processes":["cf",[]],"The_kernel":["cf",[]]},"Effective_logging_in_Git":{},"Binary_colour_encoding":{},"Quote_marks_in_Bash":{},"Magnetic_core_memory":{"Magnetic_drum_memory":["cf",[]],"Delay_line_memory":["cf",[]]},"Disk_info":{},"Formal_proofs_in_propositional_logic":{"Disjunction_Elimination":["cf",[]],"Negation_Elimination":["cf",[]],"Disjunction_Introduction":["cf",[]],"Biconditional_Introduction":["cf",[]],"Biconditional_Elimination":["cf",[]],"Conjunction_Introduction":["cf",[]],"Conditional_Elimination":["cf",[]],"Negation_Introduction":["cf",[]],"Conditional_Introduction":["cf",[]]},"Type_hinting":{},"Push_buttons":{},"Memory_Management_Unit":{},"CPU_architecture":{"Chipset_and_controllers":["cf",[]],"Bus":["cf",[]],"Fetch_decode_execute":["cf",[]],"Logic_gates":["cf",[]],"Electromagnetism":["cf",[]],"Clock_signals":["cf",[]],"The_kernel":["cf",[]],"Arithmetic_Logic_Unit":["cf",[]]},"Working_with_numbers_in_Bash":{"Expansions_and_substitutions":["cf",[]]},"Full_Node_API_example":{},"AWS_CLI":{},"Ohms_Law":{"Current":["cf",[]],"Voltage":["cf",[]],"Resistance":["cf",[]]},"Negative_exponents":{},"Chipset_and_controllers":{"Bus":["cf",[]],"What_are_disks":["cf",[]],"Motherboard":["cf",[]]},"Create_timed_systemd_job":{},"Matter_and_atoms":{},"Create_an_SQL_table":{"Data_types_in_MySQL":["cf",[]]},"Binary_addition":{},"Bus":{"Motherboard":["cf",[]]},"Instruction_set_architectures":{"Bus":["cf",[]],"Signed_and_unsigned_numbers":["cf",[]],"Arithmetic_Logic_Unit":["cf",[]]},"Add_Subtract_Fractions":{"Factors_and_divisors":["cf",[]]},"Logarithms":{},"Delete_a_branch":{},"Variable_indirection_in_Bash":{},"Listing_and_navigating_directories_in_the_Shell":{},"Deleting_Mongo_documents":{},"Validating_Mongoose_schemas":{"Validation_in_NodeJS":["cf",[]]},"Map_and_filter_in_Python":{},"Conditional_statements_in_Python":{},"Update_a_Mongo_document":{"Querying_a_Mongo_collection":["cf",[]]},"Law_of_Non_Contradiction":{},"Latches":{},"Testing_with_Jest":{},"Internet_Layer_of_Internet_Protocol":{"Link_Layer_of_Internet_Protocol":["cf",[]]},"Torrenting":{"Network_protocols":["cf",[]],"Peer_to_peer_network":["cf",[]]},"Importing_MongoDB_data":{},"Inversion_of_operators":{},"Mutations_with_Apollo_Client":{},"Lambdas_in_Python":{"Map_and_filter_in_Python":["cf",[]]},"AWS_architecture_hierarchy":{},"Docker_images":{},"Reset_to_remote_version":{},"Signed_magnitude_representation":{"Signed_and_unsigned_numbers":["cf",[]]},"Additive_identity":{},"http_in_Node":{},"Lists_and_arrays_in_Bash":{"Test_values_in_Bash":["cf",[]],"Functions_in_Bash":["cf",[]]},"Controlled_components_in_React":{},"SAM":{},"Modules_in_NodeJS":{},"Fetch_decode_execute":{"CPU_architecture":["cf",[]],"Logic_gates":["cf",[]]},"Global_object_in_NodeJS":{},"Proper_shebang_syntax":{},"Prop_types_in_React":{},"Observer_pattern":{},"Network_debugging":{},"Theorems_and_empty_sets":{},"Binary_encoding_of_text":{"Binary_encoding":["cf",[]]},"The_memory_hierarchy":{},"Git_bisect":{},"Custom_types_in_TypeScript":{"Classes":["cf",[]]},"Environmental_and_shell_variables":{},"Format_specifiers_in_C":{},"Truth_functional_connectives":{"Atomic_and_molecular_propositions":["cf",[]],"Logical_indeterminacy":["cf",[]]},"Event_loop":{"Call_stack":["cf",[]],"The_kernel":["cf",[]]},"HTTP_request_types":{},"Basic_model_of_the_operating_system":{},"Concise_subfield_mapping_JS":{},"Map_and_filter_to_reduce_in_JS":{},"Read_command__in_Bash":{"Find_Bash_command":["cf",[]],"Split_into_array_in_Bash":["cf",[]]},"Logical_equivalence":{"Biconditional_Introduction":["cf",[]]},"Compile_Python_app_to_single_executable":{},"Heap_memory":{"Stack_memory":["cf",[]],"Memory_leaks":["cf",[]]},"Passing_arguments_to_Python_scripts":{},"Identify_merged_branches":{},"Conditionals_in_Bash":{},"React_Components":{"Functions":["cf",[]]},"User_Space":{},"systemd_status":{},"Printing_values_in_C":{},"Application_state_management_with_React_hooks":{"React_useReducer":["cf",[]],"React_useContext":["cf",[]]},"Utilities_operators_flags":{},"Setting_up_and_configuring_TypeScript":{},"Middleware_in_NodeJS":{"Ports_in_NodeJS":["cf",[]],"Morgan":["cf",[]]},"Time_and_computers":{},"Boolean_functions":{},"Text_manipulation_in_Bash":{},"React_useEffect":{"Lifecycle_methods":["cf",[]],"Memory_leaks":["cf",[]]},"Update_existing_data_in_SQL_table":{},"Sets_in_Python":{},"Memoization_in_React":{"React_useEffect":["cf",[]]},"Routing_on_link_click_in_React":{},"Lists_in_Python":{"Sorting_lists_in_Python":["cf",[]]},"Redirect_to_dev_null":{},"What_are_disks":{"User_Space":["cf",[]],"Devices":["cf",[]]},"Components_props_classes":{},"Linux_disk_partitions":{"The_kernel":["cf",[]]},"Compile_from_source":{},"Functions_in_Python":{},"Flip_flops":{"Latches":["cf",[]],"Clock_signals":["cf",[]]},"Arrays":{},"Relation_between_kernel_and_CPU":{"Fetch_decode_execute":["cf",[]]},"Logical_consistency":{"Negation_Elimination":["cf",[]]},"Boolean_function_synthesis":{"Boolean_functions":["cf",[]],"Logic_gates":["cf",[]]},"Law_of_the_Excluded_Middle":{},"Working_with_CSVs_in_Python":{},"Redirection_in_Bash":{"Redirect_to_dev_null":["cf",[]],"File_descriptors":["cf",[]]},"Expansions_and_substitutions":{"Working_with_numbers_in_Bash":["cf",[]],"Shell_sessions":["cf",[]],"Variables_and_data_types_in_Bash":["cf",[]]},"Truth_tables":{},"Complete_Mongo_example":{},"3_PUT":{},"journald":{"systemd":["cf",[]],"The_kernel":["cf",[]]},"Logic_gates":{"Latches":["cf",[]],"Integrated_circuits":["cf",[]],"Hardware_abstraction_and_modularity":["cf",[]],"Transistors":["cf",[]],"Half_adder_and_full_adder":["cf",[]]},"Viewing_remote_changes_without_merging":{},"Handling_negative_fractions":{},"Syllogism":{"Logical_consistency":["cf",[]]},"IO_in_Python":{"Error_handling_in_Python":["cf",[]]},"Create_Mongo_database":{},"Mainframe_computers":{},"2_POST":{"Validation_in_NodeJS":["cf",[]]},"Further_examples_of_TS_generics":{},"Network_card":{},"Electromagnetism":{"Current":["cf",[]]},"Lifecycle_methods":{},"MongoDB_Introduction":{"Relational_database_architecture":["cf",[]]},"Naming_conventions":{},"Primes_and_composites":{},"Cells_and_batteries":{"Voltage":["cf",[]]},"Integrated_circuits":{},"Filesystems":{"Swap_space":["cf",[]]},"MAC_addresses":{"Hexadecimal_number_system":["cf",[]]},"Stale_branches_and_pruning":{"Remote_tracking_branches":["cf",[]]},"Coulombs_Laws":{},"Pacman":{},"VirtualMemory":{"Boot_process":["cf",[]]},"Working_with_JSON_in_Python":{},"Exponents":{},"Expressing_whole_numbers_as_fractions":{},"Retrieve_data_from_SQL_table":{},"Package_management_in_NodeJS":{"Semantic_versioning":["cf",[]]},"Reiteration":{},"Command_pattern":{},"Register_and_cache_memory":{},"Network_scanning":{},"Network_requests_in_Python":{"Dictionaries_in_Python":["cf",[]],"RESTful_APIs":["cf",[]]},"Guide_to_YAML":{},"Validity_and_entailment":{},"GPU_versus_CPU":{},"Creating_memory_with_NAND":{},"Joins_in_SQL":{"Create_an_SQL_table":["cf",[]]},"Disjunction_Elimination":{},"Application_structure":{},"Basic_prop_passing_in_React":{},"Node_and_MySQL_db":{"Managing_environments_in_NodeJS":["cf",[]],"Docker_Compose":["cf",[]]},"Tuples_in_Python":{},"Grep":{},"Cron":{},"Schema_Definition_Language_in_GraphQL":{},"Syntax_of_propositional_logic":{"Atomic_and_molecular_propositions":["cf",[]]},"Numbers_in_Python":{},"Binary_encoding":{},"Bitwise_operators":{},"Factory_pattern":{},"Call_stack":{"Stacks":["cf",[]]},"Connecting_a_frontend_to_a_Docker_backend":{"Node_and_MySQL_db":["cf",[]],"Docker_Compose":["cf",[]]},"Views_in_relational_databases":{},"jq":{},"Classes_in_Python":{"Functions_in_Python":["cf",[]]},"DynamoDB_data_structure":{"Foreign_keys_in_SQL":["cf",[]]},"Voltage_sources":{"Cells_and_batteries":["cf",[]]},"Object_language_and_meta_language":{},"Fetch_from_Secrets_Manager":{},"Forms_in_React":{"Forms_in_React":["cf",[]]},"Rules_for_operations_on_like_and_unlike_terms":{},"Managing_environments_in_NodeJS":{"Environmental_and_shell_variables":["cf",[]]},"Insert_data_into_SQL_table":{},"Strategies_for_constructing_proofs":{"Conjunction_Elimination":["cf",[]],"Disjunction_Elimination":["cf",[]],"Negation_Elimination":["cf",[]],"Disjunction_Introduction":["cf",[]],"Biconditional_Elimination":["cf",[]],"Recursion":["cf",[]],"Conjunction_Introduction":["cf",[]],"Conditional_Elimination":["cf",[]],"Conditional_Introduction":["cf",[]]},"Lambda_directory_structure":{},"Python_application_structure":{},"Single_file_Python_scripts":{},"Docker_Compose":{"Node_and_MySQL_db":["cf",[]]},"Turing_completeness":{"Turing_machines":["cf",[]]},"DynamoDB_SDK_commands":{},"Creating_a_Mongo_schema_and_model":{"Validating_Mongoose_schemas":["cf",[]],"MongoDB_Introduction":["cf",[]]},"Swap_space":{"The_kernel":["cf",[]]},"Role_of_memory_in_computation":{"Chipset_and_controllers":["cf",[]],"Bus":["cf",[]],"Boot_process":["cf",[]]},"Test_values_in_Bash":{"Lists_and_arrays_in_Bash":["cf",[]]},"Querying_a_Mongo_collection":{},"Function_overloads":{},"Non_null_assertion_in_TypeScript":{},"Algorithmic_complexity":{},"Local_AWS_development_with_SAM":{},"Class_inheritance_in_Python":{},"Docker_architecture":{"RESTful_APIs":["cf",[]]},"LEDs":{},"v8":{},"Solving_equations":{},"Secrets_or_env_vars_in_AWS":{},"Defining_a_computer":{},"Headless_Raspi_network_setup":{},"Mixed_and_improper_fractions":{},"The_History_of_Computing_Swade":{"Magnetic_core_memory":["cf",[]],"CPU_architecture":["cf",[]],"Logarithms":["cf",[]],"Integrated_circuits":["cf",[]],"Magnetic_tape":["cf",[]],"Transistors":["cf",[]],"Delay_line_memory":["cf",[]],"Turing_machines":["cf",[]],"Relays":["cf",[]]},"Binary_units_of_measurement":{"Binary_number_system":["cf",[]],"Prefixes_for_units_of_electrical_measurement":["cf",[]]},"Database_options_on_AWS":{},"Child_to_parent_data_flow_in_React":{},"Match_statements_in_Python":{},"Containerization":{"User_Space":["cf",[]],"The_kernel":["cf",[]]},"Multiplicative_identity":{},"Docker_general_overview":{"Docker_architecture":["cf",[]]},"Magnetic_drum_memory":{"The_History_of_Computing_Swade":["cf",[]],"Williams_Tube_memory":["cf",[]],"Delay_line_memory":["cf",[]]},"Current":{"Coulombs_Laws":["cf",[]],"Voltage":["cf",[]]},"systemd":{"Daemons":["cf",[]],"Boot_process":["cf",[]]},"Queue":{},"Difference_between_remote_origin_and_head":{},"Data_types_in_MySQL":{},"Cherry_picking":{"Remote_tracking_branches":["cf",[]]},"Iterating_in_React":{},"Elastic_Compute_Cloud":{},"Negation_Elimination":{"Negation_Introduction":["cf",[]]},"Variables_in_C":{},"Binary_number_system":{"Hexadecimal_number_system":["cf",[]]},"Useful_operators_in_SQL":{},"Magnetic_tape":{},"Sliding_window":{"Multiple_pointers":["cf",[]]},"Distributivity":{},"What_is_memory":{"CPU_architecture":["cf",[]]},"Order_of_operations":{},"Lambda_programming_model":{"Lambda_handler_function":["cf",[]],"Lambda_triggers":["cf",[]]},"Invoking_the_shell_in_Python":{},"Nodemon":{},"Atomic_and_molecular_propositions":{},"Tags_in_Git":{},"Transport_Layer_of_Internet_Protocol":{"Internet_Layer_of_Internet_Protocol":["cf",[]],"Link_Layer_of_Internet_Protocol":["cf",[]]},"Formal_conventions":{},"User_management_in_Linux":{},"Creating_a_Docker_image":{},"DynamoDB_CLI_commands":{},"Frequency_counters":{},"Network_protocols":{"Network_fundamentals":["cf",[]],"Internet_fundamentals":["cf",[]]},"5__Integrating_the_Mongo_database":{"Create_Mongo_database":["cf",[]],"Querying_a_Mongo_collection":["cf",[]],"Adding_documents_to_a_Mongo_collection":["cf",[]],"Connect_to_Mongo_database":["cf",[]]},"Foreign_keys_in_SQL":{},"Ports_in_NodeJS":{},"Basic_properties_of_sets":{},"Algebra_key_terms":{},"Loops_in_Python":{},"Packet_switching_British_precursors":{},"Dates_in_Python":{},"Save_readonly_Vim_file":{},"Logical_truth_and_falsity":{"Logical_consistency":["cf",[]],"Validity_and_entailment":["cf",[]]},"Shell_sessions":{},"Symlinks":{},"Components_props_hooks_in_React":{},"Disjunction_Introduction":{},"python_advent_learnings":{},"Accessing_metadata_about_SQL_database":{},"Semantic_versioning":{},"Union_types_in_TS":{},"Increasing_fractions_to_their_highest_terms":{},"Unknown_type_in_TS":{},"Built_in_React_hooks":{},"Sorting_lists_in_Python":{},"Handle_multiple_endpoints_single_lambda":{},"Williams_Tube_memory":{},"Signed_and_unsigned_numbers":{"Signed_magnitude_representation":["cf",[]],"Binary_encoding":["cf",[]],"Twos_complement":["cf",[]]},"Apollo_Client":{"Apollo_Server":["cf",[]]},"Python_modules_and_imports":{},"Machine_code":{"CPU_architecture":["cf",[]],"Instruction_set_architectures":["cf",[]],"Assembly":["cf",[]],"Hexadecimal_number_system":["cf",[]]},"API_Gateway":{"HTTP_request_types":["cf",[]],"Lambda_handler_function":["cf",[]],"Practical_walkthrough_Lambda_creation_within_AWS":["cf",[]]},"File_permissions_and_execution_in_Bash":{},"Python_data_types":{"Strings_in_Python":["cf",[]]},"Untitled":{},"Daemons":{},"The_Little_Man_computer":{},"Four_bit_adder":{},"Docker_containers":{},"Messaging_services":{"Queue":["cf",[]]},"Prime_factorization":{},"Link_Layer_of_Internet_Protocol":{"MAC_addresses":["cf",[]]},"Dependency_injection":{},"Testing_Python_code":{"Python_package_management":["cf",[]]},"React_useReducer":{"React_useState":["cf",[]]},"Multiple_pointers":{},"0_Introduction":{"HTTP_request_types":["cf",[]],"Middleware_in_NodeJS":["cf",[]],"3_PUT":["cf",[]],"2_POST":["cf",[]],"1_GET":["cf",[]],"RESTful_APIs":["cf",[]]},"Prototypical_inheritance":{},"Formatting_output_text_in_Bash":{},"Associativity":{},"React_useContext":{"Application_state_management_with_React_hooks":["cf",[]]},"Generics_in_TypeScript":{},"Voltage":{"Ohms_Law":["cf",[]],"Cells_and_batteries":["cf",[]],"Voltage_sources":["cf",[]],"Current":["cf",[]]},"Creating_a_Linux_partition_table":{},"Equivalent_fractions":{},"Biconditional_Introduction":{},"Twos_complement":{"Binary_addition":["cf",[]],"Signed_magnitude_representation":["cf",[]],"Binary_encoding":["cf",[]],"Signed_and_unsigned_numbers":["cf",[]]},"Multiplexers_and_demultiplexers":{},"Factors_and_divisors":{},"Using_GraphQL_with_Node":{"Middleware_in_NodeJS":["cf",[]]},"Peer_to_peer_network":{"Torrenting":["cf",[]]},"AWS_SAM_and_Docker":{},"1726814727_LUWV":{},"Docker_storage":{},"Network_hosts":{},"Hardware_abstraction_and_modularity":{},"Git_rebasing":{},"Boot_process":{"User_Space":["cf",[]],"The_kernel":["cf",[]]},"Adding_documents_to_a_Mongo_collection":{},"DRAM_and_SRAM_memory":{"Flip_flops":["cf",[]],"Current":["cf",[]],"Transistors":["cf",[]]},"Transistors":{"Voltage":["cf",[]]},"Delay_line_memory":{},"Find_Bash_command":{},"Docker_compose_and_Dockerfile_difference":{},"NodeJS_scripts":{},"Multiplying_fractions":{"Reducing_fractions":["cf",[]]},"OpenSearch":{},"Hardware_simulation":{"Hardware_Description_Language":["cf",[]]},"React_useState":{},"Hardware_Description_Language":{"Boolean_functions":["cf",[]],"Integrated_circuits":["cf",[]],"Hardware_simulation":["cf",[]]},"Case_statements_in_Bash":{},"Prefixes_for_units_of_electrical_measurement":{"Exponents":["cf",[]]},"Clock_signals":{"Latches":["cf",[]],"Electromagnetism":["cf",[]],"Half_adder_and_full_adder":["cf",[]]},"Turing_machines":{},"Reciprocals":{},"Custom_React_hook_examples":{},"Passing_arguments_and_options_to_Bash_scripts":{"The_PATH":["cf",[]]},"Primitive_types":{"Custom_types_in_TypeScript":["cf",[]],"Any":["cf",[]]},"Integers":{},"Network_fundamentals":{"Network_hosts":["cf",[]]},"Truth_trees":{},"Dictionaries_in_Python":{},"Virtual_private_cloud":{},"Journey_of_GraphQL_query":{},"Database_indices":{},"Threads":{"User_Space":["cf",[]],"The_kernel":["cf",[]]},"Three_bit_counter":{"Flip_flops":["cf",[]],"Clock_signals":["cf",[]]},"Variables_and_data_types_in_Bash":{},"Module_pattern":{},"Strings_in_Python":{"Lists_in_Python":["cf",[]]},"Corresponding_material_and_biconditional":{},"Troubleshooting_MongoDB":{},"Ground":{},"Fundamental_Theorem_of_Arithmetic":{},"Lambda_handler_function":{},"fs":{"Event_loop":["cf",[]],"Streams_in_NodeJS":["cf",[]]},"Biconditional_Elimination":{},"Application_Layer_of_Internet_Protocol":{},"Validation_in_NodeJS":{},"Boolean_algebra":{"Logic_gates":["cf",[]],"Distributivity":["cf",[]],"DeMorgan's_Laws":["cf",[]]},"Substrings_in_Bash":{},"React_errors":{},"Zip_function_in_Python":{},"Docker_CLI":{},"Regular_expressions_in_SQL":{},"Rename_a_branch":{},"Processes":{},"The_kernel":{"Processes":["cf",[]]},"Python_package_management":{},"Restructure_URLs_lambda":{"Lambda_handler_function":["cf",[]]},"Awk":{},"Stacks":{},"Process_module_in_NodeJS":{"Managing_environments_in_NodeJS":["cf",[]]},"Practical_walkthrough_Lambda_creation_within_AWS":{"Lambda_triggers":["cf",[]]},"Classes":{"Functions":["cf",[]]},"Split_into_array_in_Bash":{},"Intro_to_the_Unix_shell":{},"Wildcards_in_SQL":{},"Killing_processes":{},"Singleton_pattern":{},"Comparing_React_classes_to_hooks":{},"Operating_system_API":{"Instruction_set_architectures":["cf",[]],"Intro_to_the_Unix_shell":["cf",[]]},"Internet_fundamentals":{"Internet_Layer_of_Internet_Protocol":["cf",[]],"Transport_Layer_of_Internet_Protocol":["cf",[]],"Network_protocols":["cf",[]],"Link_Layer_of_Internet_Protocol":["cf",[]],"Network_fundamentals":["cf",[]],"Application_Layer_of_Internet_Protocol":["cf",[]],"Example_scenario_internet_data_transfer":["cf",[]]},"Logical_indeterminacy":{},"Props_in_React":{},"Arithmetic_Logic_Unit":{"CPU_architecture":["cf",[]],"Fetch_decode_execute":["cf",[]],"Logic_gates":["cf",[]],"Half_adder_and_full_adder":["cf",[]]},"1_GET":{},"Soundness":{},"Dividing_fractions":{"Reciprocals":["cf",[]]},"Relays":{"The_History_of_Computing_Swade":["cf",[]]},"Binary_arithmetic":{},"Stack_memory":{"Heap_memory":["cf",[]],"Stacks":["cf",[]],"Memory_leaks":["cf",[]]},"Axioms_of_set_theory":{},"Delete_records_in_an_SQL_table":{},"Module_wrapping_at_runtime":{},"S3":{},"Enums":{},"CloudWatch":{},"List_comprehension_in_Python":{"Map_and_filter_in_Python":["cf",[]],"Lambdas_in_Python":["cf",[]]},"Morgan":{},"Loops_in_bash":{},"Recursion":{},"ROM_versus_disk_loading":{},"Connect_to_Mongo_database":{},"Motherboard":{"CPU_architecture":["cf",[]],"What_are_disks":["cf",[]]},"Memory_versus_processor":{},"RESTful_APIs":{"HTTP_request_types":["cf",[]]},"Relational_database_architecture":{},"Electrons":{},"Half_adder_and_full_adder":{"Logic_gates":["cf",[]]},"Analogue_and_digital":{},"Logical_possibility_and_necessity":{"Logical_consistency":["cf",[]],"Validity_and_entailment":["cf",[]]},"Commutativity":{},"Apollo_Server":{"Using_arguments_with_Apollo_Client":["cf",[]]},"Error_handling_in_Python":{},"Data_types_in_Bash":{},"Basics_of_web_components":{},"Role_of_unique_key_in_relational_databases":{},"The_PATH":{"Environmental_and_shell_variables":["cf",[]]},"Conjunction_Introduction":{},"Lambda_triggers":{},"Devices":{"Redirect_to_dev_null":["cf",[]]},"Structuring_Express_applications":{},"Maps_and_sets_in_JS":{},"ps":{"The_kernel":["cf",[]]},"Reducing_fractions":{},"DeMorgan's_Laws":{},"Resistance":{"Ohms_Law":["cf",[]]},"Python_interpreter":{"Binary_units_of_measurement":["cf",[]]},"IP_addresses":{"Internet_Layer_of_Internet_Protocol":["cf",[]]},"Key_characteristics_of_GraphQL":{},"Memory_addresses":{"Logarithms":["cf",[]],"Binary_encoding":["cf",[]],"Hexadecimal_number_system":["cf",[]]},"Example_scenario_internet_data_transfer":{"Internet_Layer_of_Internet_Protocol":["cf",[]],"Basic_model_of_the_operating_system":["cf",[]],"MAC_addresses":["cf",[]],"Transport_Layer_of_Internet_Protocol":["cf",[]],"Link_Layer_of_Internet_Protocol":["cf",[]],"Application_Layer_of_Internet_Protocol":["cf",[]]},"The_Pragmatic_Programmer_1999":{},"Conditional_Elimination":{},"Natural_numbers":{},"Any":{},"Whole_numbers":{},"Set_DNS_settings":{},"Modelling_relationships_in_MongoDB":{},"Negation_Introduction":{},"Memory_leaks":{},"Aggregate_functions_in_SQL":{},"Interactive_staging":{},"Type_guarding_and_narrowing_in_TS":{"Unknown_type_in_TS":["cf",[]],"Any":["cf",[]]},"Bluetooth":{},"Functions_in_Bash":{},"Assembly":{"CPU_architecture":["cf",[]],"Instruction_set_architectures":["cf",[]],"Hexadecimal_number_system":["cf",[]]},"Python_execution":{},"Capturing_user_input_in_Bash":{"Passing_arguments_and_options_to_Bash_scripts":["cf",[]]},"None_in_Python":{},"Iterating_through_complex_data_structures_in_Python":{"Map_and_filter_in_Python":["cf",[]],"Lambdas_in_Python":["cf",[]],"Sorting_lists_in_Python":["cf",[]],"List_comprehension_in_Python":["cf",[]]},"User_management_on_AWS":{},"Why_computers_use_binary":{},"Intersection_types_in_TypeScript":{},"Streams_in_NodeJS":{"fs":["cf",[]]},"Mapped_types_in_TS":{},"Strings_in_Bash":{},"Functions":{},"Update_an_SQL_table":{},"Conditional_Introduction":{},"Hexadecimal_number_system":{"Binary_number_system":["cf",[]]},"Additive_inverse_property":{},"Step_functions_and_state_machines":{"Lambda_programming_model":["cf",[]]},"Breadboards":{},"Remote_tracking_branches":{},"Multiplicative_property_of_negative_one":{},"Zero_property_of_multiplication":{},"File_descriptors":{"Redirection_in_Bash":["cf",[]]},"Accessing_secrets_from_a_Lambda":{"Fetch_from_Secrets_Manager":["cf",[]]},"Switch_between_Python_vers":{}},"vertices":{"Using_arguments_with_Apollo_Client":{"Path":"./Using_arguments_with_Apollo_Client.md","Slug":"Using_arguments_with_Apollo_Client","ID":"Using_arguments_with_Apollo_Client","Meta":{"tags":["graphql"]},"Title":"Using arguments with Apollo Client"},"Conjunction_Elimination":{"Path":"./Conjunction_Elimination.md","Slug":"Conjunction_Elimination","ID":"Conjunction_Elimination","Meta":{"tags":["logic","propositional-logic"]},"Title":"Conditional Elimination"},"Equivalent_equations":{"Path":"./Equivalent_equations.md","Slug":"Equivalent_equations","ID":"Equivalent_equations","Meta":{"tags":["algebra"]},"Title":"Equivalent equations"},"Monitoring_processes_and_resources":{"Path":"./Monitoring_processes_and_resources.md","Slug":"Monitoring_processes_and_resources","ID":"Monitoring_processes_and_resources","Meta":{"tags":["Linux","procedural","systems-programming"]},"Title":"Monitoring processes and resources"},"Effective_logging_in_Git":{"Path":"./Effective_logging_in_Git.md","Slug":"Effective_logging_in_Git","ID":"Effective_logging_in_Git","Meta":{"tags":["git","procedural"]},"Title":"Effective logging in Git"},"Binary_colour_encoding":{"Path":"./Binary_colour_encoding.md","Slug":"Binary_colour_encoding","ID":"Binary_colour_encoding","Meta":{"tags":["binary"]},"Title":"Binary encoding of colours"},"Quote_marks_in_Bash":{"Path":"./Quote_marks_in_Bash.md","Slug":"Quote_marks_in_Bash","ID":"Quote_marks_in_Bash","Meta":{"tags":["shell"]},"Title":"Quote marks in Bash"},"Magnetic_core_memory":{"Path":"./Magnetic_core_memory.md","Slug":"Magnetic_core_memory","ID":"Magnetic_core_memory","Meta":{"created":"Friday, September 27, 2024","tags":["computer-history","memory"]},"Title":"Magnetic core memory"},"Disk_info":{"Path":"./Disk_info.md","Slug":"Disk_info","ID":"Disk_info","Meta":{"tags":["Linux","disks","procedural","systems-programming"]},"Title":"Disk info routines"},"Formal_proofs_in_propositional_logic":{"Path":"./Formal_proofs_in_propositional_logic.md","Slug":"Formal_proofs_in_propositional_logic","ID":"Formal_proofs_in_propositional_logic","Meta":{"tags":["logic","propositional-logic"]},"Title":"Formal proofs in propositional logic"},"Type_hinting":{"Path":"./Type_hinting.md","Slug":"Type_hinting","ID":"Type_hinting","Meta":{"tags":["data-types","python"]},"Title":"Type hinting in Python"},"Push_buttons":{"Path":"./Push_buttons.md","Slug":"Push_buttons","ID":"Push_buttons","Meta":{"created":"Tuesday, June 25, 2024","id":"nsrv","tags":["electronics"]},"Title":"Push buttons"},"Memory_Management_Unit":{"Path":"./Memory_Management_Unit.md","Slug":"Memory_Management_Unit","ID":"Memory_Management_Unit","Meta":{"created":"Monday, July 08, 2024","tags":["Linux","memory"]},"Title":"Memory Management Unit (MMU)"},"CPU_architecture":{"Path":"./CPU_architecture.md","Slug":"CPU_architecture","ID":"CPU_architecture","Meta":{"tags":["CPU","computer-architecture"]},"Title":"CPU architecture"},"Working_with_numbers_in_Bash":{"Path":"./Working_with_numbers_in_Bash.md","Slug":"Working_with_numbers_in_Bash","ID":"Working_with_numbers_in_Bash","Meta":{"tags":["shell"]},"Title":"Working with numbers in Bash"},"Full_Node_API_example":{"Path":"./Full_Node_API_example.md","Slug":"Full_Node_API_example","ID":"Full_Node_API_example","Meta":{"tags":["APIs","REST","node-js"]},"Title":"Creating a RESTful API: Full example"},"AWS_CLI":{"Path":"./AWS_CLI.md","Slug":"AWS_CLI","ID":"AWS_CLI","Meta":{"tags":["AWS","procedural"]},"Title":"AWS CLI frequent commands"},"Ohms_Law":{"Path":"./Ohms_Law.md","Slug":"Ohms_Law","ID":"Ohms_Law","Meta":{"tags":["electricity","physics"]},"Title":"Ohm’s Law"},"Negative_exponents":{"Path":"./Negative_exponents.md","Slug":"Negative_exponents","ID":"Negative_exponents","Meta":{"tags":["algebra","exponents"]},"Title":"Negative exponents"},"Chipset_and_controllers":{"Path":"./Chipset_and_controllers.md","Slug":"Chipset_and_controllers","ID":"Chipset_and_controllers","Meta":{"tags":["computer-architecture","hardware"]},"Title":"Chipset and controllers"},"Create_timed_systemd_job":{"Path":"./Create_timed_systemd_job.md","Slug":"Create_timed_systemd_job","ID":"Create_timed_systemd_job","Meta":{"tags":["Linux","procedural","systemd","systems-programming"]},"Title":"Create timed systemd job"},"Matter_and_atoms":{"Path":"./Matter_and_atoms.md","Slug":"Matter_and_atoms","ID":"Matter_and_atoms","Meta":{"tags":["physics"]},"Title":"Matter and atoms"},"Create_an_SQL_table":{"Path":"./Create_an_SQL_table.md","Slug":"Create_an_SQL_table","ID":"Create_an_SQL_table","Meta":{"tags":["SQL","databases"]},"Title":"Create an SQL table"},"Binary_addition":{"Path":"./Binary_addition.md","Slug":"Binary_addition","ID":"Binary_addition","Meta":{"tags":["binary"]},"Title":"Binary addition"},"Bus":{"Path":"./Bus.md","Slug":"Bus","ID":"Bus","Meta":{"tags":["bus","computer-architecture"]},"Title":"Bus"},"Instruction_set_architectures":{"Path":"./Instruction_set_architectures.md","Slug":"Instruction_set_architectures","ID":"Instruction_set_architectures","Meta":{"tags":["CPU"]},"Title":"Instruction Set Architectures"},"Add_Subtract_Fractions":{"Path":"./Add_Subtract_Fractions.md","Slug":"Add_Subtract_Fractions","ID":"Add_Subtract_Fractions","Meta":{"tags":["fractions","prealgebra"]},"Title":"Adding and subtracting fractions"},"Logarithms":{"Path":"./Logarithms.md","Slug":"Logarithms","ID":"Logarithms","Meta":{"tags":["algebra"]},"Title":"Logarithms"},"Delete_a_branch":{"Path":"./Delete_a_branch.md","Slug":"Delete_a_branch","ID":"Delete_a_branch","Meta":{"tags":["git"]},"Title":"Delete a branch"},"Variable_indirection_in_Bash":{"Path":"./Variable_indirection_in_Bash.md","Slug":"Variable_indirection_in_Bash","ID":"Variable_indirection_in_Bash","Meta":{"tags":["shell"]},"Title":"Variable indirection"},"Listing_and_navigating_directories_in_the_Shell":{"Path":"./Listing_and_navigating_directories_in_the_Shell.md","Slug":"Listing_and_navigating_directories_in_the_Shell","ID":"Listing_and_navigating_directories_in_the_Shell","Meta":{"tags":["shell"]},"Title":"Listing and navigating directories in the shell"},"Deleting_Mongo_documents":{"Path":"./Deleting_Mongo_documents.md","Slug":"Deleting_Mongo_documents","ID":"Deleting_Mongo_documents","Meta":{"tags":["databases","mongo-db","mongoose","node-js"]},"Title":"MongoDB: deleting a document from a collection"},"Validating_Mongoose_schemas":{"Path":"./Validating_Mongoose_schemas.md","Slug":"Validating_Mongoose_schemas","ID":"Validating_Mongoose_schemas","Meta":{"tags":["databases","mongo-db","mongoose","node-js"]},"Title":"Validating Mongoose schemas"},"Map_and_filter_in_Python":{"Path":"./Map_and_filter_in_Python.md","Slug":"Map_and_filter_in_Python","ID":"Map_and_filter_in_Python","Meta":{"tags":["python"]},"Title":"Map and filter in Python"},"Conditional_statements_in_Python":{"Path":"./Conditional_statements_in_Python.md","Slug":"Conditional_statements_in_Python","ID":"Conditional_statements_in_Python","Meta":{"tags":["python"]},"Title":"Conditional statements in Python"},"Update_a_Mongo_document":{"Path":"./Update_a_Mongo_document.md","Slug":"Update_a_Mongo_document","ID":"Update_a_Mongo_document","Meta":{"tags":["databases","mongo-db","mongoose","node-js"]},"Title":"Update a MongoDB document"},"Law_of_Non_Contradiction":{"Path":"./Law_of_Non_Contradiction.md","Slug":"Law_of_Non_Contradiction","ID":"Law_of_Non_Contradiction","Meta":{"tags":["logic","propositional-logic"]},"Title":"Law of Non-Contradiction"},"Latches":{"Path":"./Latches.md","Slug":"Latches","ID":"Latches","Meta":{"tags":["binary","logic-gates","memory"]},"Title":"Latches"},"Testing_with_Jest":{"Path":"./Testing_with_Jest.md","Slug":"Testing_with_Jest","ID":"Testing_with_Jest","Meta":{"tags":["javascript","jest","testing"]},"Title":"Testing with Jest"},"Internet_Layer_of_Internet_Protocol":{"Path":"./Internet_Layer_of_Internet_Protocol.md","Slug":"Internet_Layer_of_Internet_Protocol","ID":"Internet_Layer_of_Internet_Protocol","Meta":{"created":"Thursday, August 15, 2024","tags":["internet","networks"]},"Title":"Internet Layer of the Internet Protocol Suite"},"Torrenting":{"Path":"./Torrenting.md","Slug":"Torrenting","ID":"Torrenting","Meta":{"created":"Saturday, August 03, 2024","tags":["networks","question"]},"Title":"Torrenting"},"Importing_MongoDB_data":{"Path":"./Importing_MongoDB_data.md","Slug":"Importing_MongoDB_data","ID":"Importing_MongoDB_data","Meta":{"tags":["databases","mongo-db","node-js"]},"Title":"Importing data to MongoDB"},"Inversion_of_operators":{"Path":"./Inversion_of_operators.md","Slug":"Inversion_of_operators","ID":"Inversion_of_operators","Meta":{"tags":["prealgebra"]},"Title":"Inversion of operators"},"Mutations_with_Apollo_Client":{"Path":"./Mutations_with_Apollo_Client.md","Slug":"Mutations_with_Apollo_Client","ID":"Mutations_with_Apollo_Client","Meta":{"tags":["graphql"]},"Title":"Mutations with Apollo Client"},"Lambdas_in_Python":{"Path":"./Lambdas_in_Python.md","Slug":"Lambdas_in_Python","ID":"Lambdas_in_Python","Meta":{"tags":["AWS","aws-lambda","python"]},"Title":"Lambdas in Python"},"AWS_architecture_hierarchy":{"Path":"./AWS_architecture_hierarchy.md","Slug":"AWS_architecture_hierarchy","ID":"AWS_architecture_hierarchy","Meta":{"last_modified":"Monday, February 19, 2024 | 19:17","created":"Monday, February 19, 2024 | 19:17","since":"just now","id":"oyubuqx2","tags":["AWS"]},"Title":"AWS architecture hierarchy"},"Docker_images":{"Path":"./Docker_images.md","Slug":"Docker_images","ID":"Docker_images","Meta":{"tags":["docker"]},"Title":"Docker images"},"Reset_to_remote_version":{"Path":"./Reset_to_remote_version.md","Slug":"Reset_to_remote_version","ID":"Reset_to_remote_version","Meta":{"tags":["git","procedural"]},"Title":"Reset to remote version of a branch"},"Signed_magnitude_representation":{"Path":"./Signed_magnitude_representation.md","Slug":"Signed_magnitude_representation","ID":"Signed_magnitude_representation","Meta":{"created":"Wednesday, March 20, 2024","id":"3wsh","tags":["binary"]},"Title":"Signed magnitude representation"},"Additive_identity":{"Path":"./Additive_identity.md","Slug":"Additive_identity","ID":"Additive_identity","Meta":{"tags":["theorems"]},"Title":"The Property of Additive Identity"},"http_in_Node":{"Path":"./http_in_Node.md","Slug":"http_in_Node","ID":"http_in_Node","Meta":{"tags":["node-js"]},"Title":"http module"},"Lists_and_arrays_in_Bash":{"Path":"./Lists_and_arrays_in_Bash.md","Slug":"Lists_and_arrays_in_Bash","ID":"Lists_and_arrays_in_Bash","Meta":{"tags":["data-structures","shell"]},"Title":"Arrays in Bash"},"Controlled_components_in_React":{"Path":"./Controlled_components_in_React.md","Slug":"Controlled_components_in_React","ID":"Controlled_components_in_React","Meta":{"tags":["javascript","react"]},"Title":"Controlled components"},"SAM":{"Path":"./SAM.md","Slug":"SAM","ID":"SAM","Meta":{"tags":["AWS"]},"Title":"AWS SAM"},"Modules_in_NodeJS":{"Path":"./Modules_in_NodeJS.md","Slug":"Modules_in_NodeJS","ID":"Modules_in_NodeJS","Meta":{"tags":["node-js"]},"Title":"Modules"},"Fetch_decode_execute":{"Path":"./Fetch_decode_execute.md","Slug":"Fetch_decode_execute","ID":"Fetch_decode_execute","Meta":{"tags":["CPU"]},"Title":"Fetch, decode, execute, store"},"Global_object_in_NodeJS":{"Path":"./Global_object_in_NodeJS.md","Slug":"Global_object_in_NodeJS","ID":"Global_object_in_NodeJS","Meta":{"tags":["node-js"]},"Title":"Global object"},"Proper_shebang_syntax":{"Path":"./Proper_shebang_syntax.md","Slug":"Proper_shebang_syntax","ID":"Proper_shebang_syntax","Meta":{"tags":["shell"]},"Title":"Proper shebang syntax"},"Prop_types_in_React":{"Path":"./Prop_types_in_React.md","Slug":"Prop_types_in_React","ID":"Prop_types_in_React","Meta":{"tags":["data-types","javascript","react"]},"Title":"Prop types"},"Observer_pattern":{"Path":"./Observer_pattern.md","Slug":"Observer_pattern","ID":"Observer_pattern","Meta":{"tags":["OOP","design-patterns"]},"Title":"Observer pattern"},"Network_debugging":{"Path":"./Network_debugging.md","Slug":"Network_debugging","ID":"Network_debugging","Meta":{"created":"Monday, June 17, 2024","id":"x44w","tags":["Linux","networks","procedural"]},"Title":"Network debugging"},"Theorems_and_empty_sets":{"Path":"./Theorems_and_empty_sets.md","Slug":"Theorems_and_empty_sets","ID":"Theorems_and_empty_sets","Meta":{"tags":["logic","propositional-logic"]},"Title":"Theorems and empty sets"},"Binary_encoding_of_text":{"Path":"./Binary_encoding_of_text.md","Slug":"Binary_encoding_of_text","ID":"Binary_encoding_of_text","Meta":{"tags":["binary"]},"Title":"Text encoding"},"The_memory_hierarchy":{"Path":"./The_memory_hierarchy.md","Slug":"The_memory_hierarchy","ID":"The_memory_hierarchy","Meta":{"created":"Friday, July 12, 2024","tags":["memory"]},"Title":"The memory hierarchy"},"Git_bisect":{"Path":"./Git_bisect.md","Slug":"Git_bisect","ID":"Git_bisect","Meta":{"tags":["git"]},"Title":"Bisect"},"Custom_types_in_TypeScript":{"Path":"./Custom_types_in_TypeScript.md","Slug":"Custom_types_in_TypeScript","ID":"Custom_types_in_TypeScript","Meta":{"tags":["typescript"]},"Title":"Custom types"},"Environmental_and_shell_variables":{"Path":"./Environmental_and_shell_variables.md","Slug":"Environmental_and_shell_variables","ID":"Environmental_and_shell_variables","Meta":{"tags":["shell"]},"Title":"Environmental and shell variables"},"Format_specifiers_in_C":{"Path":"./Format_specifiers_in_C.md","Slug":"Format_specifiers_in_C","ID":"Format_specifiers_in_C","Meta":{"created":"Thursday, February 29, 2024 | 17:41","id":"5faz2y2e","tags":["C"]},"Title":"Format specifiers in C"},"Truth_functional_connectives":{"Path":"./Truth_functional_connectives.md","Slug":"Truth_functional_connectives","ID":"Truth_functional_connectives","Meta":{"tags":["logic","propositional-logic"]},"Title":"Truth-functional connectives"},"Event_loop":{"Path":"./Event_loop.md","Slug":"Event_loop","ID":"Event_loop","Meta":{"tags":["node-js"]},"Title":"The Event Loop"},"HTTP_request_types":{"Path":"./HTTP_request_types.md","Slug":"HTTP_request_types","ID":"HTTP_request_types","Meta":{"tags":["REST"]},"Title":"HTTP request types"},"Basic_model_of_the_operating_system":{"Path":"./Basic_model_of_the_operating_system.md","Slug":"Basic_model_of_the_operating_system","ID":"Basic_model_of_the_operating_system","Meta":{"tags":["Linux","operating-systems"]},"Title":"Basic model of a nix operating system"},"Concise_subfield_mapping_JS":{"Path":"./Concise_subfield_mapping_JS.md","Slug":"Concise_subfield_mapping_JS","ID":"Concise_subfield_mapping_JS","Meta":{"created":"Friday, June 28, 2024","id":"dv3u","tags":[]},"Title":"Concise mapping of object subfileds in JS"},"Map_and_filter_to_reduce_in_JS":{"Path":"./Map_and_filter_to_reduce_in_JS.md","Slug":"Map_and_filter_to_reduce_in_JS","ID":"Map_and_filter_to_reduce_in_JS","Meta":{"tags":["javascript"]},"Title":"Expressing combined map and filter operations to a single reduce"},"Read_command__in_Bash":{"Path":"./Read_command__in_Bash.md","Slug":"Read_command__in_Bash","ID":"Read_command__in_Bash","Meta":{"tags":["shell"]},"Title":"read"},"Logical_equivalence":{"Path":"./Logical_equivalence.md","Slug":"Logical_equivalence","ID":"Logical_equivalence","Meta":{"tags":["logic","propositional-logic"]},"Title":"Logical equivalence"},"Compile_Python_app_to_single_executable":{"Path":"./Compile_Python_app_to_single_executable.md","Slug":"Compile_Python_app_to_single_executable","ID":"Compile_Python_app_to_single_executable","Meta":{"created":"Saturday, October 19, 2024","tags":["procedural","python"]},"Title":"Compile Python app to single executable"},"Heap_memory":{"Path":"./Heap_memory.md","Slug":"Heap_memory","ID":"Heap_memory","Meta":{"created":"Saturday, April 20, 2024","id":"18bl","tags":["C","memory"]},"Title":"Heap memory"},"Passing_arguments_to_Python_scripts":{"Path":"./Passing_arguments_to_Python_scripts.md","Slug":"Passing_arguments_to_Python_scripts","ID":"Passing_arguments_to_Python_scripts","Meta":{"created":"Wednesday, June 19, 2024","id":"44li","tags":["python"]},"Title":"Passing arguments to Python scripts"},"Identify_merged_branches":{"Path":"./Identify_merged_branches.md","Slug":"Identify_merged_branches","ID":"Identify_merged_branches","Meta":{"tags":["git"]},"Title":"Identify merged branches"},"Conditionals_in_Bash":{"Path":"./Conditionals_in_Bash.md","Slug":"Conditionals_in_Bash","ID":"Conditionals_in_Bash","Meta":{"tags":["shell"]},"Title":"Conditionals in Bash"},"React_Components":{"Path":"./React_Components.md","Slug":"React_Components","ID":"React_Components","Meta":{"tags":["react","typescript"]},"Title":"Components"},"User_Space":{"Path":"./User_Space.md","Slug":"User_Space","ID":"User_Space","Meta":{"tags":["operating-systems"]},"Title":"User space"},"systemd_status":{"Path":"./systemd_status.md","Slug":"systemd_status","ID":"systemd_status","Meta":{"created":"Thursday, February 29, 2024 | 18:19","id":"v5f6xkdv","tags":["Linux","procedural","systemd","systems-programming"]},"Title":"Get status of a specific unit"},"Printing_values_in_C":{"Path":"./Printing_values_in_C.md","Slug":"Printing_values_in_C","ID":"Printing_values_in_C","Meta":{"created":"Thursday, February 29, 2024 | 17:33","id":"3hcv0amc","tags":["C"]},"Title":"Printing values in C"},"Application_state_management_with_React_hooks":{"Path":"./Application_state_management_with_React_hooks.md","Slug":"Application_state_management_with_React_hooks","ID":"Application_state_management_with_React_hooks","Meta":{"tags":["javascript","react"]},"Title":"Application state management"},"Utilities_operators_flags":{"Path":"./Utilities_operators_flags.md","Slug":"Utilities_operators_flags","ID":"Utilities_operators_flags","Meta":{"tags":["shell"]},"Title":"Utilities, operators, flags in Bash"},"Setting_up_and_configuring_TypeScript":{"Path":"./Setting_up_and_configuring_TypeScript.md","Slug":"Setting_up_and_configuring_TypeScript","ID":"Setting_up_and_configuring_TypeScript","Meta":{"tags":["typescript"]},"Title":"Setup and configuration"},"Middleware_in_NodeJS":{"Path":"./Middleware_in_NodeJS.md","Slug":"Middleware_in_NodeJS","ID":"Middleware_in_NodeJS","Meta":{"tags":["middleware","node-js"]},"Title":"Middleware"},"Time_and_computers":{"Path":"./Time_and_computers.md","Slug":"Time_and_computers","ID":"Time_and_computers","Meta":{"created":"Sunday, April 28, 2024","id":"l29u","tags":["time","unix"]},"Title":"Time and computers"},"Boolean_functions":{"Path":"./Boolean_functions.md","Slug":"Boolean_functions","ID":"Boolean_functions","Meta":{"tags":["logic","nand-to-tetris","propositional-logic"]},"Title":"Boolean functions"},"Text_manipulation_in_Bash":{"Path":"./Text_manipulation_in_Bash.md","Slug":"Text_manipulation_in_Bash","ID":"Text_manipulation_in_Bash","Meta":{"tags":["shell"]},"Title":"Text manipulation"},"React_useEffect":{"Path":"./React_useEffect.md","Slug":"React_useEffect","ID":"React_useEffect","Meta":{"tags":["javascript","react"]},"Title":"useEffect"},"Update_existing_data_in_SQL_table":{"Path":"./Update_existing_data_in_SQL_table.md","Slug":"Update_existing_data_in_SQL_table","ID":"Update_existing_data_in_SQL_table","Meta":{"tags":["SQL","databases"]},"Title":"Update existing data with the SQL UPDATE command"},"Sets_in_Python":{"Path":"./Sets_in_Python.md","Slug":"Sets_in_Python","ID":"Sets_in_Python","Meta":{"tags":["data-structures","python"]},"Title":"Sets in Python"},"Memoization_in_React":{"Path":"./Memoization_in_React.md","Slug":"Memoization_in_React","ID":"Memoization_in_React","Meta":{"tags":["javascript","react"]},"Title":"Memoization with useCallback and useMemo"},"Routing_on_link_click_in_React":{"Path":"./Routing_on_link_click_in_React.md","Slug":"Routing_on_link_click_in_React","ID":"Routing_on_link_click_in_React","Meta":{"tags":["javascript","react","testing"]},"Title":"Test: Routing on link click"},"Lists_in_Python":{"Path":"./Lists_in_Python.md","Slug":"Lists_in_Python","ID":"Lists_in_Python","Meta":{"tags":["data-structures","python"]},"Title":"Lists in Python"},"Redirect_to_dev_null":{"Path":"./Redirect_to_dev_null.md","Slug":"Redirect_to_dev_null","ID":"Redirect_to_dev_null","Meta":{"tags":["shell"]},"Title":"Redirecting to /dev/null"},"What_are_disks":{"Path":"./What_are_disks.md","Slug":"What_are_disks","ID":"What_are_disks","Meta":{"tags":["computer-architecture","disks"]},"Title":"What are disks?"},"Components_props_classes":{"Path":"./Components_props_classes.md","Slug":"Components_props_classes","ID":"Components_props_classes","Meta":{"tags":["javascript","react"]},"Title":"Components and props with class-based components"},"Linux_disk_partitions":{"Path":"./Linux_disk_partitions.md","Slug":"Linux_disk_partitions","ID":"Linux_disk_partitions","Meta":{"tags":["Linux","disks","procedural"]},"Title":"Linux disk partitions"},"Compile_from_source":{"Path":"./Compile_from_source.md","Slug":"Compile_from_source","ID":"Compile_from_source","Meta":{"tags":["Linux","procedural"]},"Title":"Compile package from source"},"Functions_in_Python":{"Path":"./Functions_in_Python.md","Slug":"Functions_in_Python","ID":"Functions_in_Python","Meta":{"tags":["python"]},"Title":"Functions in Python"},"Flip_flops":{"Path":"./Flip_flops.md","Slug":"Flip_flops","ID":"Flip_flops","Meta":{"tags":["binary","logic-gates","memory"]},"Title":"Flip-Flops"},"Arrays":{"Path":"./Arrays.md","Slug":"Arrays","ID":"Arrays","Meta":{"tags":["data-structures"]},"Title":"Arrays"},"Relation_between_kernel_and_CPU":{"Path":"./Relation_between_kernel_and_CPU.md","Slug":"Relation_between_kernel_and_CPU","ID":"Relation_between_kernel_and_CPU","Meta":{"tags":["CPU","computer-architecture","operating-systems"]},"Title":"Relation between the kernel and CPU"},"Logical_consistency":{"Path":"./Logical_consistency.md","Slug":"Logical_consistency","ID":"Logical_consistency","Meta":{"tags":["logic","propositional-logic"]},"Title":"Logical consistency"},"Boolean_function_synthesis":{"Path":"./Boolean_function_synthesis.md","Slug":"Boolean_function_synthesis","ID":"Boolean_function_synthesis","Meta":{"tags":["logic","nand-to-tetris","propositional-logic"]},"Title":"Boolean function synthesis"},"Law_of_the_Excluded_Middle":{"Path":"./Law_of_the_Excluded_Middle.md","Slug":"Law_of_the_Excluded_Middle","ID":"Law_of_the_Excluded_Middle","Meta":{"tags":["logic","propositional-logic"]},"Title":"Law of the Excluded Middle"},"Working_with_CSVs_in_Python":{"Path":"./Working_with_CSVs_in_Python.md","Slug":"Working_with_CSVs_in_Python","ID":"Working_with_CSVs_in_Python","Meta":{"created":"Sunday, April 28, 2024","id":"sgtn","tags":["csv","python"]},"Title":"Working with CSVs in Python"},"Redirection_in_Bash":{"Path":"./Redirection_in_Bash.md","Slug":"Redirection_in_Bash","ID":"Redirection_in_Bash","Meta":{"tags":["shell"]},"Title":"Redirection"},"Expansions_and_substitutions":{"Path":"./Expansions_and_substitutions.md","Slug":"Expansions_and_substitutions","ID":"Expansions_and_substitutions","Meta":{"tags":["shell"]},"Title":"Expansions and substitutions"},"Truth_tables":{"Path":"./Truth_tables.md","Slug":"Truth_tables","ID":"Truth_tables","Meta":{"tags":["logic","propositional-logic"]},"Title":"Truth-tables"},"Complete_Mongo_example":{"Path":"./Complete_Mongo_example.md","Slug":"Complete_Mongo_example","ID":"Complete_Mongo_example","Meta":{"tags":["databases","mongo-db","mongoose","node-js"]},"Title":"MongoDB connection, set-up and data query: complete example"},"3_PUT":{"Path":"./3_PUT.md","Slug":"3_PUT","ID":"3_PUT","Meta":{"tags":["APIs","REST","node-js"]},"Title":"Creating a RESTful API: PUT requests"},"journald":{"Path":"./journald.md","Slug":"journald","ID":"journald","Meta":{"tags":["Linux","procedural","systems-programming"]},"Title":"journald"},"Logic_gates":{"Path":"./Logic_gates.md","Slug":"Logic_gates","ID":"Logic_gates","Meta":{"tags":["##","binary","disjunction)","logic-gates"]},"Title":"Logic gates"},"Viewing_remote_changes_without_merging":{"Path":"./Viewing_remote_changes_without_merging.md","Slug":"Viewing_remote_changes_without_merging","ID":"Viewing_remote_changes_without_merging","Meta":{"tags":["git"]},"Title":"Viewing remote changes without merging"},"Handling_negative_fractions":{"Path":"./Handling_negative_fractions.md","Slug":"Handling_negative_fractions","ID":"Handling_negative_fractions","Meta":{"tags":["fractions","prealgebra"]},"Title":"Negative fractions"},"Syllogism":{"Path":"./Syllogism.md","Slug":"Syllogism","ID":"Syllogism","Meta":{"tags":["logic","propositional-logic"]},"Title":"Syllogism"},"IO_in_Python":{"Path":"./IO_in_Python.md","Slug":"IO_in_Python","ID":"IO_in_Python","Meta":{"tags":["python"]},"Title":"IO in Python"},"Create_Mongo_database":{"Path":"./Create_Mongo_database.md","Slug":"Create_Mongo_database","ID":"Create_Mongo_database","Meta":{"tags":["databases","mongo-db","mongoose","node-js"]},"Title":"Creating a MongoDB database"},"Mainframe_computers":{"Path":"./Mainframe_computers.md","Slug":"Mainframe_computers","ID":"Mainframe_computers","Meta":{"created":"Friday, September 27, 2024","tags":["computer-history"]},"Title":"Mainframe computers"},"2_POST":{"Path":"./2_POST.md","Slug":"2_POST","ID":"2_POST","Meta":{"tags":["APIs","REST","node-js"]},"Title":"Creating a RESTful API: POST requests"},"Further_examples_of_TS_generics":{"Path":"./Further_examples_of_TS_generics.md","Slug":"Further_examples_of_TS_generics","ID":"Further_examples_of_TS_generics","Meta":{"tags":["typescript"]},"Title":"Further examples of generics in TypeScript"},"Network_card":{"Path":"./Network_card.md","Slug":"Network_card","ID":"Network_card","Meta":{"created":"Tuesday, August 06, 2024","tags":["hardware","networks"]},"Title":"Network card"},"Electromagnetism":{"Path":"./Electromagnetism.md","Slug":"Electromagnetism","ID":"Electromagnetism","Meta":{"tags":["electricity","electromagnetism","physics"]},"Title":"Electromagnetism"},"Lifecycle_methods":{"Path":"./Lifecycle_methods.md","Slug":"Lifecycle_methods","ID":"Lifecycle_methods","Meta":{"tags":["javascript","react"]},"Title":"Lifecycle methods"},"MongoDB_Introduction":{"Path":"./MongoDB_Introduction.md","Slug":"MongoDB_Introduction","ID":"MongoDB_Introduction","Meta":{"tags":["databases","mongo-db"]},"Title":"MongoDB: Introduction"},"Naming_conventions":{"Path":"./Naming_conventions.md","Slug":"Naming_conventions","ID":"Naming_conventions","Meta":{"tags":["python"]},"Title":"Python naming conventions"},"Primes_and_composites":{"Path":"./Primes_and_composites.md","Slug":"Primes_and_composites","ID":"Primes_and_composites","Meta":{"tags":["number-theory","prealgebra"]},"Title":"Prime and composite numbers"},"Cells_and_batteries":{"Path":"./Cells_and_batteries.md","Slug":"Cells_and_batteries","ID":"Cells_and_batteries","Meta":{"tags":["electricity","physics"]},"Title":"Cells and batteries"},"Integrated_circuits":{"Path":"./Integrated_circuits.md","Slug":"Integrated_circuits","ID":"Integrated_circuits","Meta":{"tags":["electronics","logic-gates"]},"Title":"Integrated circuits"},"Filesystems":{"Path":"./Filesystems.md","Slug":"Filesystems","ID":"Filesystems","Meta":{"tags":["computer-architecture","disks","operating-systems"]},"Title":"Filesystems"},"MAC_addresses":{"Path":"./MAC_addresses.md","Slug":"MAC_addresses","ID":"MAC_addresses","Meta":{"created":"Tuesday, August 06, 2024","tags":["networks"]},"Title":"MAC addresses"},"Stale_branches_and_pruning":{"Path":"./Stale_branches_and_pruning.md","Slug":"Stale_branches_and_pruning","ID":"Stale_branches_and_pruning","Meta":{"tags":["git"]},"Title":"Stale branches and pruning"},"Coulombs_Laws":{"Path":"./Coulombs_Laws.md","Slug":"Coulombs_Laws","ID":"Coulombs_Laws","Meta":{"tags":["electricity","physics"]},"Title":"Coulombs Laws"},"Pacman":{"Path":"./Pacman.md","Slug":"Pacman","ID":"Pacman","Meta":{"tags":["Linux","arch-linux","procedural"]},"Title":"Pacman"},"VirtualMemory":{"Path":"./VirtualMemory.md","Slug":"VirtualMemory","ID":"VirtualMemory","Meta":{"tags":["Linux","kernel","memory"]},"Title":"Virtual memory"},"Working_with_JSON_in_Python":{"Path":"./Working_with_JSON_in_Python.md","Slug":"Working_with_JSON_in_Python","ID":"Working_with_JSON_in_Python","Meta":{"created":"Tuesday, June 25, 2024","id":"mjia","tags":["JSON","python"]},"Title":"Working with JSON in Python"},"Exponents":{"Path":"./Exponents.md","Slug":"Exponents","ID":"Exponents","Meta":{"tags":["algebra","exponents"]},"Title":"Exponents"},"Expressing_whole_numbers_as_fractions":{"Path":"./Expressing_whole_numbers_as_fractions.md","Slug":"Expressing_whole_numbers_as_fractions","ID":"Expressing_whole_numbers_as_fractions","Meta":{"tags":["fractions","prealgebra"]},"Title":"Expressing whole numbers as fractions"},"Retrieve_data_from_SQL_table":{"Path":"./Retrieve_data_from_SQL_table.md","Slug":"Retrieve_data_from_SQL_table","ID":"Retrieve_data_from_SQL_table","Meta":{"tags":["SQL","databases"]},"Title":"Retrieve data from table with SQL SELECT statement"},"Package_management_in_NodeJS":{"Path":"./Package_management_in_NodeJS.md","Slug":"Package_management_in_NodeJS","ID":"Package_management_in_NodeJS","Meta":{"tags":["node-js"]},"Title":"Package management"},"Reiteration":{"Path":"./Reiteration.md","Slug":"Reiteration","ID":"Reiteration","Meta":{"tags":["logic","propositional-logic"]},"Title":"Reiteration"},"Command_pattern":{"Path":"./Command_pattern.md","Slug":"Command_pattern","ID":"Command_pattern","Meta":{"tags":["design-patterns"]},"Title":"Command pattern"},"Register_and_cache_memory":{"Path":"./Register_and_cache_memory.md","Slug":"Register_and_cache_memory","ID":"Register_and_cache_memory","Meta":{"created":"Friday, July 12, 2024","tags":["CPU","memory"]},"Title":"Register and cache memory"},"Network_scanning":{"Path":"./Network_scanning.md","Slug":"Network_scanning","ID":"Network_scanning","Meta":{"created":"Monday, June 10, 2024","id":"ippn","tags":["Linux","networks","procedural"]},"Title":"Network scanning"},"Network_requests_in_Python":{"Path":"./Network_requests_in_Python.md","Slug":"Network_requests_in_Python","ID":"Network_requests_in_Python","Meta":{"tags":["APIs","networks","python"]},"Title":"Making network requests in Python"},"Guide_to_YAML":{"Path":"./Guide_to_YAML.md","Slug":"Guide_to_YAML","ID":"Guide_to_YAML","Meta":{"tags":["yaml"]},"Title":"Guide to YAML"},"Validity_and_entailment":{"Path":"./Validity_and_entailment.md","Slug":"Validity_and_entailment","ID":"Validity_and_entailment","Meta":{"tags":["logic","propositional-logic"]},"Title":"Validity and entailment"},"GPU_versus_CPU":{"Path":"./GPU_versus_CPU.md","Slug":"GPU_versus_CPU","ID":"GPU_versus_CPU","Meta":{"created":"Sunday, September 22, 2024","tags":["computer-architecture"]},"Title":"GPU versus CPU"},"Creating_memory_with_NAND":{"Path":"./Creating_memory_with_NAND.md","Slug":"Creating_memory_with_NAND","ID":"Creating_memory_with_NAND","Meta":{"tags":["binary","logic-gates","memory"]},"Title":"Creating memory with NAND gates"},"Joins_in_SQL":{"Path":"./Joins_in_SQL.md","Slug":"Joins_in_SQL","ID":"Joins_in_SQL","Meta":{"tags":["SQL","databases"]},"Title":"Joins in SQL"},"Disjunction_Elimination":{"Path":"./Disjunction_Elimination.md","Slug":"Disjunction_Elimination","ID":"Disjunction_Elimination","Meta":{"tags":["logic","propositional-logic"]},"Title":"Disjunction Elimination"},"Application_structure":{"Path":"./Application_structure.md","Slug":"Application_structure","ID":"Application_structure","Meta":{"tags":["javascript","react"]},"Title":"React application structure"},"Basic_prop_passing_in_React":{"Path":"./Basic_prop_passing_in_React.md","Slug":"Basic_prop_passing_in_React","ID":"Basic_prop_passing_in_React","Meta":{"tags":["javascript","react","testing"]},"Title":"Test: Basic prop passing"},"Node_and_MySQL_db":{"Path":"./Node_and_MySQL_db.md","Slug":"Node_and_MySQL_db","ID":"Node_and_MySQL_db","Meta":{"tags":["SQL","databases","docker","node-js"]},"Title":"Docker example: NodeJS backend with MySQL database"},"Tuples_in_Python":{"Path":"./Tuples_in_Python.md","Slug":"Tuples_in_Python","ID":"Tuples_in_Python","Meta":{"tags":["data-structures","python"]},"Title":"Tuples in Python"},"Grep":{"Path":"./Grep.md","Slug":"Grep","ID":"Grep","Meta":{"tags":["shell"]},"Title":"Grep"},"Cron":{"Path":"./Cron.md","Slug":"Cron","ID":"Cron","Meta":{"tags":["Linux","procedural","shell"]},"Title":"Cron"},"Schema_Definition_Language_in_GraphQL":{"Path":"./Schema_Definition_Language_in_GraphQL.md","Slug":"Schema_Definition_Language_in_GraphQL","ID":"Schema_Definition_Language_in_GraphQL","Meta":{"tags":["graphql"]},"Title":"Schema Definition Language"},"Syntax_of_propositional_logic":{"Path":"./Syntax_of_propositional_logic.md","Slug":"Syntax_of_propositional_logic","ID":"Syntax_of_propositional_logic","Meta":{"tags":["logic","propositional-logic"]},"Title":"Syntax of propositional logic"},"Numbers_in_Python":{"Path":"./Numbers_in_Python.md","Slug":"Numbers_in_Python","ID":"Numbers_in_Python","Meta":{"tags":["data-types","python"]},"Title":"Numbers in Python"},"Binary_encoding":{"Path":"./Binary_encoding.md","Slug":"Binary_encoding","ID":"Binary_encoding","Meta":{"tags":["binary"]},"Title":"Binary encoding"},"Bitwise_operators":{"Path":"./Bitwise_operators.md","Slug":"Bitwise_operators","ID":"Bitwise_operators","Meta":{"created":"Saturday, April 20, 2024","id":"t127","tags":["binary"]},"Title":"Bitwise operators"},"Factory_pattern":{"Path":"./Factory_pattern.md","Slug":"Factory_pattern","ID":"Factory_pattern","Meta":{"tags":["OOP","design-patterns"]},"Title":"Factory pattern"},"Call_stack":{"Path":"./Call_stack.md","Slug":"Call_stack","ID":"Call_stack","Meta":{"tags":["javascript","memory"]},"Title":"The call-stack"},"Connecting_a_frontend_to_a_Docker_backend":{"Path":"./Connecting_a_frontend_to_a_Docker_backend.md","Slug":"Connecting_a_frontend_to_a_Docker_backend","ID":"Connecting_a_frontend_to_a_Docker_backend","Meta":{"tags":["docker","node-js"]},"Title":"Connecting a frontend to a Docker backend"},"Views_in_relational_databases":{"Path":"./Views_in_relational_databases.md","Slug":"Views_in_relational_databases","ID":"Views_in_relational_databases","Meta":{"tags":["databases"]},"Title":"Views in relational databases"},"jq":{"Path":"./jq.md","Slug":"jq","ID":"jq","Meta":{"tags":["json","shell"]},"Title":"jq"},"Classes_in_Python":{"Path":"./Classes_in_Python.md","Slug":"Classes_in_Python","ID":"Classes_in_Python","Meta":{"tags":["OOP","python"]},"Title":"Classes in Python"},"DynamoDB_data_structure":{"Path":"./DynamoDB_data_structure.md","Slug":"DynamoDB_data_structure","ID":"DynamoDB_data_structure","Meta":{"created":"Sunday, June 09, 2024","id":"xowl","tags":["AWS","SQL","databases","dynamodb"]},"Title":"DynamoDB"},"Voltage_sources":{"Path":"./Voltage_sources.md","Slug":"Voltage_sources","ID":"Voltage_sources","Meta":{"tags":["electricity","physics"]},"Title":"Voltage sources"},"Object_language_and_meta_language":{"Path":"./Object_language_and_meta_language.md","Slug":"Object_language_and_meta_language","ID":"Object_language_and_meta_language","Meta":{"tags":["logic","propositional-logic"]},"Title":"Object and metalanguages"},"Fetch_from_Secrets_Manager":{"Path":"./Fetch_from_Secrets_Manager.md","Slug":"Fetch_from_Secrets_Manager","ID":"Fetch_from_Secrets_Manager","Meta":{"tags":["AWS"]},"Title":"Fetch from Secrets Manager"},"Forms_in_React":{"Path":"./Forms_in_React.md","Slug":"Forms_in_React","ID":"Forms_in_React","Meta":{"tags":["javascript","react"]},"Title":"Forms using hooks"},"Rules_for_operations_on_like_and_unlike_terms":{"Path":"./Rules_for_operations_on_like_and_unlike_terms.md","Slug":"Rules_for_operations_on_like_and_unlike_terms","ID":"Rules_for_operations_on_like_and_unlike_terms","Meta":{"tags":["prealgebra"]},"Title":"Rules for operations on like and unlike terms"},"Managing_environments_in_NodeJS":{"Path":"./Managing_environments_in_NodeJS.md","Slug":"Managing_environments_in_NodeJS","ID":"Managing_environments_in_NodeJS","Meta":{"tags":["node-js"]},"Title":"Managing environments"},"Insert_data_into_SQL_table":{"Path":"./Insert_data_into_SQL_table.md","Slug":"Insert_data_into_SQL_table","ID":"Insert_data_into_SQL_table","Meta":{"tags":["SQL","databases"]},"Title":"Insert data into table with SQL INSERT statement"},"Strategies_for_constructing_proofs":{"Path":"./Strategies_for_constructing_proofs.md","Slug":"Strategies_for_constructing_proofs","ID":"Strategies_for_constructing_proofs","Meta":{"tags":["logic","propositional-logic"]},"Title":"Strategies for constructing proofs in propositional logic"},"Lambda_directory_structure":{"Path":"./Lambda_directory_structure.md","Slug":"Lambda_directory_structure","ID":"Lambda_directory_structure","Meta":{"tags":["AWS","aws-lambda"]},"Title":"Lambda directory structure"},"Python_application_structure":{"Path":"./Python_application_structure.md","Slug":"Python_application_structure","ID":"Python_application_structure","Meta":{"created":"Tuesday, August 27, 2024","tags":["python"]},"Title":"Python application structure"},"Single_file_Python_scripts":{"Path":"./Single_file_Python_scripts.md","Slug":"Single_file_Python_scripts","ID":"Single_file_Python_scripts","Meta":{"created":"Friday, April 26, 2024","id":"atzw","tags":[]},"Title":"Single file Python scripts"},"Docker_Compose":{"Path":"./Docker_Compose.md","Slug":"Docker_Compose","ID":"Docker_Compose","Meta":{"tags":["docker"]},"Title":"Docker Compose"},"Turing_completeness":{"Path":"./Turing_completeness.md","Slug":"Turing_completeness","ID":"Turing_completeness","Meta":{"created":"Friday, September 13, 2024","tags":["Turing","theory-of-computation"]},"Title":"Turing Completeness"},"DynamoDB_SDK_commands":{"Path":"./DynamoDB_SDK_commands.md","Slug":"DynamoDB_SDK_commands","ID":"DynamoDB_SDK_commands","Meta":{"created":"Sunday, June 23, 2024","id":"8b6h","tags":["AWS","databases","dynamodb"]},"Title":"DynamoDB SDK commands"},"Creating_a_Mongo_schema_and_model":{"Path":"./Creating_a_Mongo_schema_and_model.md","Slug":"Creating_a_Mongo_schema_and_model","ID":"Creating_a_Mongo_schema_and_model","Meta":{"tags":["databases","mongo-db","mongoose","node-js"]},"Title":"Creating a schema and model"},"Swap_space":{"Path":"./Swap_space.md","Slug":"Swap_space","ID":"Swap_space","Meta":{"tags":["Linux","disks","memory","operating-systems"]},"Title":"Swap space"},"Role_of_memory_in_computation":{"Path":"./Role_of_memory_in_computation.md","Slug":"Role_of_memory_in_computation","ID":"Role_of_memory_in_computation","Meta":{"created":"Friday, July 12, 2024","tags":["memory"]},"Title":"The role of memory in computation"},"Test_values_in_Bash":{"Path":"./Test_values_in_Bash.md","Slug":"Test_values_in_Bash","ID":"Test_values_in_Bash","Meta":{"tags":["regex","shell"]},"Title":"Test values in Bash"},"Querying_a_Mongo_collection":{"Path":"./Querying_a_Mongo_collection.md","Slug":"Querying_a_Mongo_collection","ID":"Querying_a_Mongo_collection","Meta":{"tags":["databases","mongo-db","mongoose","node-js"]},"Title":"Query a Mongo collection with Mongoose"},"Function_overloads":{"Path":"./Function_overloads.md","Slug":"Function_overloads","ID":"Function_overloads","Meta":{"tags":["typescript"]},"Title":"Function overloads"},"Non_null_assertion_in_TypeScript":{"Path":"./Non_null_assertion_in_TypeScript.md","Slug":"Non_null_assertion_in_TypeScript","ID":"Non_null_assertion_in_TypeScript","Meta":{"tags":["typescript"]},"Title":"Non-null assertion"},"Algorithmic_complexity":{"Path":"./Algorithmic_complexity.md","Slug":"Algorithmic_complexity","ID":"Algorithmic_complexity","Meta":{"tags":["algorithms"]},"Title":"Algorithmic complexity"},"Local_AWS_development_with_SAM":{"Path":"./Local_AWS_development_with_SAM.md","Slug":"Local_AWS_development_with_SAM","ID":"Local_AWS_development_with_SAM","Meta":{"tags":["AWS","docker"]},"Title":"Local AWS development with SAM"},"Class_inheritance_in_Python":{"Path":"./Class_inheritance_in_Python.md","Slug":"Class_inheritance_in_Python","ID":"Class_inheritance_in_Python","Meta":{"tags":["OOP","python"]},"Title":"Class inheritance in Python"},"Docker_architecture":{"Path":"./Docker_architecture.md","Slug":"Docker_architecture","ID":"Docker_architecture","Meta":{"tags":["containerization","docker"]},"Title":"Docker architecture"},"LEDs":{"Path":"./LEDs.md","Slug":"LEDs","ID":"LEDs","Meta":{"tags":["electronics"]},"Title":"LEDs"},"v8":{"Path":"./v8.md","Slug":"v8","ID":"v8","Meta":{"tags":["node-js"]},"Title":"v8"},"Solving_equations":{"Path":"./Solving_equations.md","Slug":"Solving_equations","ID":"Solving_equations","Meta":{"tags":["algebra"]},"Title":"Solving equations"},"Secrets_or_env_vars_in_AWS":{"Path":"./Secrets_or_env_vars_in_AWS.md","Slug":"Secrets_or_env_vars_in_AWS","ID":"Secrets_or_env_vars_in_AWS","Meta":{"tags":["AWS","aws-lambda"]},"Title":"Secrets or environment variables?"},"Defining_a_computer":{"Path":"./Defining_a_computer.md","Slug":"Defining_a_computer","ID":"Defining_a_computer","Meta":{"tags":["1","Lovelace","theory-of-computation"]},"Title":"Defining a computer"},"Headless_Raspi_network_setup":{"Path":"./Headless_Raspi_network_setup.md","Slug":"Headless_Raspi_network_setup","ID":"Headless_Raspi_network_setup","Meta":{"created":"Wednesday, June 12, 2024","id":"hb10","tags":["Linux","networks","procedural","raspberry-pi"]},"Title":"Headless network setup"},"Mixed_and_improper_fractions":{"Path":"./Mixed_and_improper_fractions.md","Slug":"Mixed_and_improper_fractions","ID":"Mixed_and_improper_fractions","Meta":{"tags":["fractions","prealgebra"]},"Title":"Mixed and improper fractions"},"The_History_of_Computing_Swade":{"Path":"./The_History_of_Computing_Swade.md","Slug":"The_History_of_Computing_Swade","ID":"The_History_of_Computing_Swade","Meta":{"created":"Friday, August 23, 2024","tags":["Babbage)","Leibniz","Lovelace","Pascal","Turing","computer-history","literature","vonNeumann"]},"Title":"History of Computing (Swade, 2022 )"},"Binary_units_of_measurement":{"Path":"./Binary_units_of_measurement.md","Slug":"Binary_units_of_measurement","ID":"Binary_units_of_measurement","Meta":{"tags":["binary"]},"Title":"Binary units of measurement"},"Database_options_on_AWS":{"Path":"./Database_options_on_AWS.md","Slug":"Database_options_on_AWS","ID":"Database_options_on_AWS","Meta":{"tags":["AWS","databases","dynamodb"]},"Title":"Database options"},"Child_to_parent_data_flow_in_React":{"Path":"./Child_to_parent_data_flow_in_React.md","Slug":"Child_to_parent_data_flow_in_React","ID":"Child_to_parent_data_flow_in_React","Meta":{"tags":["javascript","react"]},"Title":"Child to parent data flow"},"Match_statements_in_Python":{"Path":"./Match_statements_in_Python.md","Slug":"Match_statements_in_Python","ID":"Match_statements_in_Python","Meta":{"tags":["python"]},"Title":"Match statements in Python"},"Containerization":{"Path":"./Containerization.md","Slug":"Containerization","ID":"Containerization","Meta":{"tags":["Linux","containerization","docker"]},"Title":"Containerizaton"},"Multiplicative_identity":{"Path":"./Multiplicative_identity.md","Slug":"Multiplicative_identity","ID":"Multiplicative_identity","Meta":{"tags":["prealgebra","theorems"]},"Title":"The Property of Multiplicative Identity"},"Docker_general_overview":{"Path":"./Docker_general_overview.md","Slug":"Docker_general_overview","ID":"Docker_general_overview","Meta":{"tags":["containerization","docker"]},"Title":"Docker: general overview"},"Magnetic_drum_memory":{"Path":"./Magnetic_drum_memory.md","Slug":"Magnetic_drum_memory","ID":"Magnetic_drum_memory","Meta":{"created":"Tuesday, September 24, 2024","tags":["computer-history","memory"]},"Title":"Magnetic drum memory"},"Current":{"Path":"./Current.md","Slug":"Current","ID":"Current","Meta":{"tags":["electricity","physics"]},"Title":"Current"},"systemd":{"Path":"./systemd.md","Slug":"systemd","ID":"systemd","Meta":{"tags":["Linux","operating-systems","procedural","systemd","systems-programming"]},"Title":"systemd"},"Queue":{"Path":"./Queue.md","Slug":"Queue","ID":"Queue","Meta":{"tags":["data-structures"]},"Title":"Queues"},"Difference_between_remote_origin_and_head":{"Path":"./Difference_between_remote_origin_and_head.md","Slug":"Difference_between_remote_origin_and_head","ID":"Difference_between_remote_origin_and_head","Meta":{"tags":["git"]},"Title":"Difference between remote, origin, HEAD"},"Data_types_in_MySQL":{"Path":"./Data_types_in_MySQL.md","Slug":"Data_types_in_MySQL","ID":"Data_types_in_MySQL","Meta":{"tags":["SQL","data-types","databases"]},"Title":"Data types in MySQL"},"Cherry_picking":{"Path":"./Cherry_picking.md","Slug":"Cherry_picking","ID":"Cherry_picking","Meta":{"tags":["git"]},"Title":"Cherry-picking a commit"},"Iterating_in_React":{"Path":"./Iterating_in_React.md","Slug":"Iterating_in_React","ID":"Iterating_in_React","Meta":{"tags":["javascript","react"]},"Title":"Iterating through data"},"Elastic_Compute_Cloud":{"Path":"./Elastic_Compute_Cloud.md","Slug":"Elastic_Compute_Cloud","ID":"Elastic_Compute_Cloud","Meta":{"last_modified":"Monday, February 19, 2024 | 18:58","created":"Monday, February 19, 2024 | 18:58","since":"just now","id":null,"tags":["AWS"]},"Title":"Elastic Compute Cloud (EC2)"},"Negation_Elimination":{"Path":"./Negation_Elimination.md","Slug":"Negation_Elimination","ID":"Negation_Elimination","Meta":{"tags":["logic","propositional-logic"]},"Title":"Negation Elimination"},"Variables_in_C":{"Path":"./Variables_in_C.md","Slug":"Variables_in_C","ID":"Variables_in_C","Meta":{"created":"Thursday, February 29, 2024 | 17:20","id":"r4i16p1x","tags":["C"]},"Title":"Variables in C"},"Binary_number_system":{"Path":"./Binary_number_system.md","Slug":"Binary_number_system","ID":"Binary_number_system","Meta":{"tags":["binary","number-systems"]},"Title":"Binary number system"},"Useful_operators_in_SQL":{"Path":"./Useful_operators_in_SQL.md","Slug":"Useful_operators_in_SQL","ID":"Useful_operators_in_SQL","Meta":{"tags":["SQL","databases"]},"Title":"Useful operators in SQL"},"Magnetic_tape":{"Path":"./Magnetic_tape.md","Slug":"Magnetic_tape","ID":"Magnetic_tape","Meta":{"created":"Monday, September 23, 2024","tags":["computer-history","storage"]},"Title":"Magnetic tape"},"Sliding_window":{"Path":"./Sliding_window.md","Slug":"Sliding_window","ID":"Sliding_window","Meta":{"tags":["design-patterns"]},"Title":"Sliding window"},"Distributivity":{"Path":"./Distributivity.md","Slug":"Distributivity","ID":"Distributivity","Meta":{"tags":["prealgebra","theorems"]},"Title":"The Distributive Property of Multiplication"},"What_is_memory":{"Path":"./What_is_memory.md","Slug":"What_is_memory","ID":"What_is_memory","Meta":{"created":"Friday, July 12, 2024","tags":["memory"]},"Title":"What is memory ?"},"Order_of_operations":{"Path":"./Order_of_operations.md","Slug":"Order_of_operations","ID":"Order_of_operations","Meta":{"tags":["prealgebra"]},"Title":"Order of operations"},"Lambda_programming_model":{"Path":"./Lambda_programming_model.md","Slug":"Lambda_programming_model","ID":"Lambda_programming_model","Meta":{"tags":["AWS","aws-lambda"]},"Title":"AWS Lambda programming model"},"Invoking_the_shell_in_Python":{"Path":"./Invoking_the_shell_in_Python.md","Slug":"Invoking_the_shell_in_Python","ID":"Invoking_the_shell_in_Python","Meta":{"created":"Monday, April 29, 2024","id":"cfr4","tags":["python","shell"]},"Title":"Invoking the shell in Python"},"Nodemon":{"Path":"./Nodemon.md","Slug":"Nodemon","ID":"Nodemon","Meta":{"tags":["node-js"]},"Title":"Nodemon"},"Atomic_and_molecular_propositions":{"Path":"./Atomic_and_molecular_propositions.md","Slug":"Atomic_and_molecular_propositions","ID":"Atomic_and_molecular_propositions","Meta":{"tags":["logic","propositional-logic"]},"Title":"Atomic and molecular propositions"},"Tags_in_Git":{"Path":"./Tags_in_Git.md","Slug":"Tags_in_Git","ID":"Tags_in_Git","Meta":{"tags":["git"]},"Title":"Tags in Git"},"Transport_Layer_of_Internet_Protocol":{"Path":"./Transport_Layer_of_Internet_Protocol.md","Slug":"Transport_Layer_of_Internet_Protocol","ID":"Transport_Layer_of_Internet_Protocol","Meta":{"created":"Tuesday, September 03, 2024","tags":["internet","networks","ports"]},"Title":"Transport Layer of the Internet Protocol"},"Formal_conventions":{"Path":"./Formal_conventions.md","Slug":"Formal_conventions","ID":"Formal_conventions","Meta":{"tags":["prealgebra"]},"Title":"Formal conventions"},"User_management_in_Linux":{"Path":"./User_management_in_Linux.md","Slug":"User_management_in_Linux","ID":"User_management_in_Linux","Meta":{"tags":["Linux","procedural"]},"Title":"User management"},"Creating_a_Docker_image":{"Path":"./Creating_a_Docker_image.md","Slug":"Creating_a_Docker_image","ID":"Creating_a_Docker_image","Meta":{"tags":["'","docker"]},"Title":"Creating a Docker image"},"DynamoDB_CLI_commands":{"Path":"./DynamoDB_CLI_commands.md","Slug":"DynamoDB_CLI_commands","ID":"DynamoDB_CLI_commands","Meta":{"created":"Saturday, June 22, 2024","id":"l045","tags":["AWS","databases","dynamodb"]},"Title":"DynamoDB CLI commands"},"Frequency_counters":{"Path":"./Frequency_counters.md","Slug":"Frequency_counters","ID":"Frequency_counters","Meta":{"tags":["data-structures"]},"Title":"Frequency counters"},"Network_protocols":{"Path":"./Network_protocols.md","Slug":"Network_protocols","ID":"Network_protocols","Meta":{"created":"Saturday, August 03, 2024","tags":["networks"]},"Title":"Network protocols"},"5__Integrating_the_Mongo_database":{"Path":"./5__Integrating_the_Mongo_database.md","Slug":"5__Integrating_the_Mongo_database","ID":"5__Integrating_the_Mongo_database","Meta":{"tags":["APIs","REST","databases","mongo-db","node-js"]},"Title":"Creating a RESTful API: Integrating the database"},"Foreign_keys_in_SQL":{"Path":"./Foreign_keys_in_SQL.md","Slug":"Foreign_keys_in_SQL","ID":"Foreign_keys_in_SQL","Meta":{"tags":["SQL","databases"]},"Title":"Creating views with foreign keys"},"Ports_in_NodeJS":{"Path":"./Ports_in_NodeJS.md","Slug":"Ports_in_NodeJS","ID":"Ports_in_NodeJS","Meta":{"tags":["node-js"]},"Title":"Ports"},"Basic_properties_of_sets":{"Path":"./Basic_properties_of_sets.md","Slug":"Basic_properties_of_sets","ID":"Basic_properties_of_sets","Meta":{"tags":["set-theory"]},"Title":"Basic properties of sets"},"Algebra_key_terms":{"Path":"./Algebra_key_terms.md","Slug":"Algebra_key_terms","ID":"Algebra_key_terms","Meta":{"tags":["algebra"]},"Title":"Algebra key terms"},"Loops_in_Python":{"Path":"./Loops_in_Python.md","Slug":"Loops_in_Python","ID":"Loops_in_Python","Meta":{"tags":["python"]},"Title":"Loops in Python"},"Packet_switching_British_precursors":{"Path":"./Packet_switching_British_precursors.md","Slug":"Packet_switching_British_precursors","ID":"Packet_switching_British_precursors","Meta":{"created":"Friday, August 09, 2024","tags":[]},"Title":"Packet switching British precursors"},"Dates_in_Python":{"Path":"./Dates_in_Python.md","Slug":"Dates_in_Python","ID":"Dates_in_Python","Meta":{"tags":["python","time"]},"Title":"Dates in Python"},"Save_readonly_Vim_file":{"Path":"./Save_readonly_Vim_file.md","Slug":"Save_readonly_Vim_file","ID":"Save_readonly_Vim_file","Meta":{"tags":["Linux","procedural"]},"Title":"Save read only Vim file"},"Logical_truth_and_falsity":{"Path":"./Logical_truth_and_falsity.md","Slug":"Logical_truth_and_falsity","ID":"Logical_truth_and_falsity","Meta":{"tags":["logic","propositional-logic"]},"Title":"Logical truth and falsity"},"Shell_sessions":{"Path":"./Shell_sessions.md","Slug":"Shell_sessions","ID":"Shell_sessions","Meta":{"tags":["shell"]},"Title":"Shell sessions"},"Symlinks":{"Path":"./Symlinks.md","Slug":"Symlinks","ID":"Symlinks","Meta":{"tags":["Linux","procedural","shell"]},"Title":"Symlinks"},"Components_props_hooks_in_React":{"Path":"./Components_props_hooks_in_React.md","Slug":"Components_props_hooks_in_React","ID":"Components_props_hooks_in_React","Meta":{"tags":["javascript","react"]},"Title":"Components and props with hooks"},"Disjunction_Introduction":{"Path":"./Disjunction_Introduction.md","Slug":"Disjunction_Introduction","ID":"Disjunction_Introduction","Meta":{"tags":["logic","propositional-logic"]},"Title":"Disjunction Introduction"},"python_advent_learnings":{"Path":"./python_advent_learnings.md","Slug":"python_advent_learnings","ID":"python_advent_learnings","Meta":{"tags":[]},"Title":"Python advent learnings"},"Accessing_metadata_about_SQL_database":{"Path":"./Accessing_metadata_about_SQL_database.md","Slug":"Accessing_metadata_about_SQL_database","ID":"Accessing_metadata_about_SQL_database","Meta":{"tags":["SQL","databases"]},"Title":"Accessing metadata about SQL database"},"Semantic_versioning":{"Path":"./Semantic_versioning.md","Slug":"Semantic_versioning","ID":"Semantic_versioning","Meta":{"tags":[]},"Title":"Semantic versioning"},"Union_types_in_TS":{"Path":"./Union_types_in_TS.md","Slug":"Union_types_in_TS","ID":"Union_types_in_TS","Meta":{"tags":["typescript"]},"Title":"Union types"},"Increasing_fractions_to_their_highest_terms":{"Path":"./Increasing_fractions_to_their_highest_terms.md","Slug":"Increasing_fractions_to_their_highest_terms","ID":"Increasing_fractions_to_their_highest_terms","Meta":{"tags":["fractions","prealgebra"]},"Title":"Increasing fractions to their highest terms"},"Unknown_type_in_TS":{"Path":"./Unknown_type_in_TS.md","Slug":"Unknown_type_in_TS","ID":"Unknown_type_in_TS","Meta":{"tags":["typescript"]},"Title":"Unknown"},"Built_in_React_hooks":{"Path":"./Built_in_React_hooks.md","Slug":"Built_in_React_hooks","ID":"Built_in_React_hooks","Meta":{"tags":["react","typescript"]},"Title":"Typing built-in hooks"},"Sorting_lists_in_Python":{"Path":"./Sorting_lists_in_Python.md","Slug":"Sorting_lists_in_Python","ID":"Sorting_lists_in_Python","Meta":{"tags":["python"]},"Title":"Sorting lists in Python"},"Handle_multiple_endpoints_single_lambda":{"Path":"./Handle_multiple_endpoints_single_lambda.md","Slug":"Handle_multiple_endpoints_single_lambda","ID":"Handle_multiple_endpoints_single_lambda","Meta":{"tags":["AWS","aws-lambda"]},"Title":"Handle multiple API Gateway endpoints in a single lambda"},"Williams_Tube_memory":{"Path":"./Williams_Tube_memory.md","Slug":"Williams_Tube_memory","ID":"Williams_Tube_memory","Meta":{"created":"Tuesday, September 17, 2024","tags":["computer-history","memory"]},"Title":"Williams Tube memory"},"Signed_and_unsigned_numbers":{"Path":"./Signed_and_unsigned_numbers.md","Slug":"Signed_and_unsigned_numbers","ID":"Signed_and_unsigned_numbers","Meta":{"tags":["binary"]},"Title":"Signed and unsigned numbers"},"Apollo_Client":{"Path":"./Apollo_Client.md","Slug":"Apollo_Client","ID":"Apollo_Client","Meta":{"tags":["graphql"]},"Title":"Apollo Client"},"Python_modules_and_imports":{"Path":"./Python_modules_and_imports.md","Slug":"Python_modules_and_imports","ID":"Python_modules_and_imports","Meta":{"tags":["OOP","python"]},"Title":"Python modules"},"Machine_code":{"Path":"./Machine_code.md","Slug":"Machine_code","ID":"Machine_code","Meta":{"created":"Monday, March 11, 2024","id":"iqh8","tags":["CPU","binary","computer-architecture","hardware"]},"Title":"Machine code"},"API_Gateway":{"Path":"./API_Gateway.md","Slug":"API_Gateway","ID":"API_Gateway","Meta":{"tags":["APIs","AWS"]},"Title":"AWS API Gateway"},"File_permissions_and_execution_in_Bash":{"Path":"./File_permissions_and_execution_in_Bash.md","Slug":"File_permissions_and_execution_in_Bash","ID":"File_permissions_and_execution_in_Bash","Meta":{"tags":["shell"]},"Title":"File permissions and executables"},"Python_data_types":{"Path":"./Python_data_types.md","Slug":"Python_data_types","ID":"Python_data_types","Meta":{"tags":["data-types","python"]},"Title":"Python data-types"},"Untitled":{"Path":"./Untitled.md","Slug":"Untitled","ID":"Untitled","Meta":{"created":"Sunday, September 22, 2024","tags":[]},"Title":"Untitled"},"Daemons":{"Path":"./Daemons.md","Slug":"Daemons","ID":"Daemons","Meta":{"tags":["operating-systems"]},"Title":"Daemons"},"The_Little_Man_computer":{"Path":"./The_Little_Man_computer.md","Slug":"The_Little_Man_computer","ID":"The_Little_Man_computer","Meta":{"tags":["CPU"]},"Title":"The Little Man Computer"},"Four_bit_adder":{"Path":"./Four_bit_adder.md","Slug":"Four_bit_adder","ID":"Four_bit_adder","Meta":{"tags":["binary","logic-gates"]},"Title":"Four-bit adder"},"Docker_containers":{"Path":"./Docker_containers.md","Slug":"Docker_containers","ID":"Docker_containers","Meta":{"tags":["containerization","docker"]},"Title":"Docker containers"},"Messaging_services":{"Path":"./Messaging_services.md","Slug":"Messaging_services","ID":"Messaging_services","Meta":{"tags":["AWS"]},"Title":"AWS Messaging services"},"Prime_factorization":{"Path":"./Prime_factorization.md","Slug":"Prime_factorization","ID":"Prime_factorization","Meta":{"tags":["number-theory","prealgebra"]},"Title":"Prime factorisation"},"Link_Layer_of_Internet_Protocol":{"Path":"./Link_Layer_of_Internet_Protocol.md","Slug":"Link_Layer_of_Internet_Protocol","ID":"Link_Layer_of_Internet_Protocol","Meta":{"created":"Tuesday, August 06, 2024","tags":["internet","networks"]},"Title":"Link Layer of the Internet Protocol Suite"},"Dependency_injection":{"Path":"./Dependency_injection.md","Slug":"Dependency_injection","ID":"Dependency_injection","Meta":{"tags":["OOP"]},"Title":"Dependency injection"},"Testing_Python_code":{"Path":"./Testing_Python_code.md","Slug":"Testing_Python_code","ID":"Testing_Python_code","Meta":{"tags":["python","testing"]},"Title":"Testing Python code"},"React_useReducer":{"Path":"./React_useReducer.md","Slug":"React_useReducer","ID":"React_useReducer","Meta":{"tags":["javascript","react"]},"Title":"useReducer"},"Multiple_pointers":{"Path":"./Multiple_pointers.md","Slug":"Multiple_pointers","ID":"Multiple_pointers","Meta":{"tags":["design-patterns"]},"Title":"Multiple pointers"},"0_Introduction":{"Path":"./0_Introduction.md","Slug":"0_Introduction","ID":"0_Introduction","Meta":{"tags":["APIs","REST","node-js"]},"Title":"Creating a RESTful API: Introduction"},"Prototypical_inheritance":{"Path":"./Prototypical_inheritance.md","Slug":"Prototypical_inheritance","ID":"Prototypical_inheritance","Meta":{"tags":[")","OOP","javascript"]},"Title":"Prototypical inheritance"},"Formatting_output_text_in_Bash":{"Path":"./Formatting_output_text_in_Bash.md","Slug":"Formatting_output_text_in_Bash","ID":"Formatting_output_text_in_Bash","Meta":{"tags":["shell"]},"Title":"Formatting output text in Bash"},"Associativity":{"Path":"./Associativity.md","Slug":"Associativity","ID":"Associativity","Meta":{"tags":["prealgebra","theorems"]},"Title":"The Associative Property of Addition and Multiplication"},"React_useContext":{"Path":"./React_useContext.md","Slug":"React_useContext","ID":"React_useContext","Meta":{"tags":["javascript","react"]},"Title":"useContext"},"Generics_in_TypeScript":{"Path":"./Generics_in_TypeScript.md","Slug":"Generics_in_TypeScript","ID":"Generics_in_TypeScript","Meta":{"tags":["typescript"]},"Title":"Generics"},"Voltage":{"Path":"./Voltage.md","Slug":"Voltage","ID":"Voltage","Meta":{"tags":["electricity","physics"]},"Title":"Voltage"},"Creating_a_Linux_partition_table":{"Path":"./Creating_a_Linux_partition_table.md","Slug":"Creating_a_Linux_partition_table","ID":"Creating_a_Linux_partition_table","Meta":{"created":"Monday, May 06, 2024","tags":["Linux","disks"]},"Title":"Creating a Linux partition table"},"Equivalent_fractions":{"Path":"./Equivalent_fractions.md","Slug":"Equivalent_fractions","ID":"Equivalent_fractions","Meta":{"tags":["fractions","prealgebra"]},"Title":"Equivalent fractions"},"Biconditional_Introduction":{"Path":"./Biconditional_Introduction.md","Slug":"Biconditional_Introduction","ID":"Biconditional_Introduction","Meta":{"tags":["logic"]},"Title":"Biconditional introduction"},"Twos_complement":{"Path":"./Twos_complement.md","Slug":"Twos_complement","ID":"Twos_complement","Meta":{"created":"Tuesday, March 19, 2024","id":"gktb","tags":["binary"]},"Title":"Two’s complement"},"Multiplexers_and_demultiplexers":{"Path":"./Multiplexers_and_demultiplexers.md","Slug":"Multiplexers_and_demultiplexers","ID":"Multiplexers_and_demultiplexers","Meta":{"tags":["binary","logic-gates","nand-to-tetris"]},"Title":"Multiplexers (MUX) and demultiplexers (DMUX)"},"Factors_and_divisors":{"Path":"./Factors_and_divisors.md","Slug":"Factors_and_divisors","ID":"Factors_and_divisors","Meta":{"tags":["prealgebra"]},"Title":"Factors and divisors"},"Using_GraphQL_with_Node":{"Path":"./Using_GraphQL_with_Node.md","Slug":"Using_GraphQL_with_Node","ID":"Using_GraphQL_with_Node","Meta":{"tags":["graphql","node-js"]},"Title":"Using GraphQL with Node.js"},"Peer_to_peer_network":{"Path":"./Peer_to_peer_network.md","Slug":"Peer_to_peer_network","ID":"Peer_to_peer_network","Meta":{"created":"Friday, August 09, 2024","tags":["networks"]},"Title":"Peer to peer network"},"AWS_SAM_and_Docker":{"Path":"./AWS_SAM_and_Docker.md","Slug":"AWS_SAM_and_Docker","ID":"AWS_SAM_and_Docker","Meta":{"tags":["AWS","docker"]},"Title":"AWS SAM and Docker"},"1726814727_LUWV":{"Path":"./1726814727_LUWV.md","Slug":"1726814727_LUWV","ID":"1726814727_LUWV","Meta":{"tags":[]},"Title":"Turing Mach"},"Docker_storage":{"Path":"./Docker_storage.md","Slug":"Docker_storage","ID":"Docker_storage","Meta":{"tags":["docker"]},"Title":"Docker storage"},"Network_hosts":{"Path":"./Network_hosts.md","Slug":"Network_hosts","ID":"Network_hosts","Meta":{"created":"Saturday, August 03, 2024","tags":["networks"]},"Title":"Network hosts"},"Hardware_abstraction_and_modularity":{"Path":"./Hardware_abstraction_and_modularity.md","Slug":"Hardware_abstraction_and_modularity","ID":"Hardware_abstraction_and_modularity","Meta":{"tags":["nand-to-tetris"]},"Title":"Hardware abstraction and modularity"},"Git_rebasing":{"Path":"./Git_rebasing.md","Slug":"Git_rebasing","ID":"Git_rebasing","Meta":{"tags":["git"]},"Title":"Rebasing"},"Boot_process":{"Path":"./Boot_process.md","Slug":"Boot_process","ID":"Boot_process","Meta":{"tags":["disks","operating-systems"]},"Title":"The boot process"},"Adding_documents_to_a_Mongo_collection":{"Path":"./Adding_documents_to_a_Mongo_collection.md","Slug":"Adding_documents_to_a_Mongo_collection","ID":"Adding_documents_to_a_Mongo_collection","Meta":{"tags":["databases","mongo-db","mongoose","node-js"]},"Title":"Adding documents to a collection"},"DRAM_and_SRAM_memory":{"Path":"./DRAM_and_SRAM_memory.md","Slug":"DRAM_and_SRAM_memory","ID":"DRAM_and_SRAM_memory","Meta":{"created":"Friday, July 12, 2024","tags":["hardware","memory"]},"Title":"DRAM and SRAM memory"},"Transistors":{"Path":"./Transistors.md","Slug":"Transistors","ID":"Transistors","Meta":{"tags":["binary","electronics","logic-gates"]},"Title":"Transistors"},"Delay_line_memory":{"Path":"./Delay_line_memory.md","Slug":"Delay_line_memory","ID":"Delay_line_memory","Meta":{"created":"Wednesday, September 18, 2024","tags":["computer-history","memory","vonNeumann"]},"Title":"Delay line memory"},"Find_Bash_command":{"Path":"./Find_Bash_command.md","Slug":"Find_Bash_command","ID":"Find_Bash_command","Meta":{"tags":["shell"]},"Title":"find"},"Docker_compose_and_Dockerfile_difference":{"Path":"./Docker_compose_and_Dockerfile_difference.md","Slug":"Docker_compose_and_Dockerfile_difference","ID":"Docker_compose_and_Dockerfile_difference","Meta":{"created":"Tuesday, March 26, 2024","id":"fw56","tags":["docker"]},"Title":"Docker compose and Dockerfile difference"},"NodeJS_scripts":{"Path":"./NodeJS_scripts.md","Slug":"NodeJS_scripts","ID":"NodeJS_scripts","Meta":{"created":"Friday, April 26, 2024","tags":["node-js"]},"Title":"NodeJS scripts"},"Multiplying_fractions":{"Path":"./Multiplying_fractions.md","Slug":"Multiplying_fractions","ID":"Multiplying_fractions","Meta":{"tags":["arithmetic","fractions","prealgebra"]},"Title":"Multiplying fractions"},"OpenSearch":{"Path":"./OpenSearch.md","Slug":"OpenSearch","ID":"OpenSearch","Meta":{"tags":["AWS"]},"Title":"OpenSearch"},"Hardware_simulation":{"Path":"./Hardware_simulation.md","Slug":"Hardware_simulation","ID":"Hardware_simulation","Meta":{"tags":["nand-to-tetris"]},"Title":"Hardware simulation"},"React_useState":{"Path":"./React_useState.md","Slug":"React_useState","ID":"React_useState","Meta":{"tags":["javascript","react"]},"Title":"useState"},"Hardware_Description_Language":{"Path":"./Hardware_Description_Language.md","Slug":"Hardware_Description_Language","ID":"Hardware_Description_Language","Meta":{"tags":["nand-to-tetris"]},"Title":"Hardware Description Language"},"Case_statements_in_Bash":{"Path":"./Case_statements_in_Bash.md","Slug":"Case_statements_in_Bash","ID":"Case_statements_in_Bash","Meta":{"tags":["shell"]},"Title":"Case statements in Bash"},"Prefixes_for_units_of_electrical_measurement":{"Path":"./Prefixes_for_units_of_electrical_measurement.md","Slug":"Prefixes_for_units_of_electrical_measurement","ID":"Prefixes_for_units_of_electrical_measurement","Meta":{"tags":["electricity","exponents","physics"]},"Title":"Prefixes for unit of electrical measurement"},"Clock_signals":{"Path":"./Clock_signals.md","Slug":"Clock_signals","ID":"Clock_signals","Meta":{"tags":["binary","electromagnetism","hardware","memory"]},"Title":"Clock signals"},"Turing_machines":{"Path":"./Turing_machines.md","Slug":"Turing_machines","ID":"Turing_machines","Meta":{"tags":["Turing","theory-of-computation"]},"Title":"Turing Machines"},"Reciprocals":{"Path":"./Reciprocals.md","Slug":"Reciprocals","ID":"Reciprocals","Meta":{"tags":["fractions","prealgebra","theorems"]},"Title":"Recipricols"},"Custom_React_hook_examples":{"Path":"./Custom_React_hook_examples.md","Slug":"Custom_React_hook_examples","ID":"Custom_React_hook_examples","Meta":{"tags":["javascript","react"]},"Title":"Custom hook examples"},"Passing_arguments_and_options_to_Bash_scripts":{"Path":"./Passing_arguments_and_options_to_Bash_scripts.md","Slug":"Passing_arguments_and_options_to_Bash_scripts","ID":"Passing_arguments_and_options_to_Bash_scripts","Meta":{"tags":["shell"]},"Title":"Passing arguments and options to Bash scripts"},"Primitive_types":{"Path":"./Primitive_types.md","Slug":"Primitive_types","ID":"Primitive_types","Meta":{"tags":["data-types","typescript"]},"Title":"Primitive types"},"Integers":{"Path":"./Integers.md","Slug":"Integers","ID":"Integers","Meta":{"tags":["prealgebra"]},"Title":"Integers"},"Network_fundamentals":{"Path":"./Network_fundamentals.md","Slug":"Network_fundamentals","ID":"Network_fundamentals","Meta":{"created":"Saturday, August 03, 2024","tags":["network-protocols","networks"]},"Title":"Network fundamentals"},"Truth_trees":{"Path":"./Truth_trees.md","Slug":"Truth_trees","ID":"Truth_trees","Meta":{"tags":["logic","propositional-logic"]},"Title":"Truth trees"},"Dictionaries_in_Python":{"Path":"./Dictionaries_in_Python.md","Slug":"Dictionaries_in_Python","ID":"Dictionaries_in_Python","Meta":{"tags":["data-structures","python"]},"Title":"Dictionaries in Python"},"Virtual_private_cloud":{"Path":"./Virtual_private_cloud.md","Slug":"Virtual_private_cloud","ID":"Virtual_private_cloud","Meta":{"created":"Tuesday, February 20, 2024 | 08:31","id":"mdw5fe5a","tags":["AWS","networks"]},"Title":"Virtual Private Cloud"},"Journey_of_GraphQL_query":{"Path":"./Journey_of_GraphQL_query.md","Slug":"Journey_of_GraphQL_query","ID":"Journey_of_GraphQL_query","Meta":{"tags":["graphql"]},"Title":"The journey of a GraphQL query"},"Database_indices":{"Path":"./Database_indices.md","Slug":"Database_indices","ID":"Database_indices","Meta":{"tags":["databases"]},"Title":"database indices"},"Threads":{"Path":"./Threads.md","Slug":"Threads","ID":"Threads","Meta":{"created":"Wednesday, June 26, 2024","id":"zadl","tags":["operating-systems"]},"Title":"Threads"},"Three_bit_counter":{"Path":"./Three_bit_counter.md","Slug":"Three_bit_counter","ID":"Three_bit_counter","Meta":{"tags":["binary","logic-gates","memory"]},"Title":"3-bit Counter"},"Variables_and_data_types_in_Bash":{"Path":"./Variables_and_data_types_in_Bash.md","Slug":"Variables_and_data_types_in_Bash","ID":"Variables_and_data_types_in_Bash","Meta":{"tags":["shell"]},"Title":"Variables and datatypes in Bash"},"Module_pattern":{"Path":"./Module_pattern.md","Slug":"Module_pattern","ID":"Module_pattern","Meta":{"tags":["OOP","design-patterns"]},"Title":"Module pattern"},"Strings_in_Python":{"Path":"./Strings_in_Python.md","Slug":"Strings_in_Python","ID":"Strings_in_Python","Meta":{"tags":["data-types","python"]},"Title":"Strings in Python"},"Corresponding_material_and_biconditional":{"Path":"./Corresponding_material_and_biconditional.md","Slug":"Corresponding_material_and_biconditional","ID":"Corresponding_material_and_biconditional","Meta":{"tags":["logic","propositional-logic"]},"Title":"Corresponding material conditional to show validity"},"Troubleshooting_MongoDB":{"Path":"./Troubleshooting_MongoDB.md","Slug":"Troubleshooting_MongoDB","ID":"Troubleshooting_MongoDB","Meta":{"tags":["mongo-db"]},"Title":"Troubleshooting MongoDB connection issues"},"Ground":{"Path":"./Ground.md","Slug":"Ground","ID":"Ground","Meta":{"tags":["electricity","physics"]},"Title":"Ground"},"Fundamental_Theorem_of_Arithmetic":{"Path":"./Fundamental_Theorem_of_Arithmetic.md","Slug":"Fundamental_Theorem_of_Arithmetic","ID":"Fundamental_Theorem_of_Arithmetic","Meta":{"tags":["prealgebra","theorems"]},"Title":"Fundamental Theorem of Arithmetic"},"Lambda_handler_function":{"Path":"./Lambda_handler_function.md","Slug":"Lambda_handler_function","ID":"Lambda_handler_function","Meta":{"tags":["AWS","aws-lambda"]},"Title":"AWS Lambda handler function"},"fs":{"Path":"./fs.md","Slug":"fs","ID":"fs","Meta":{"tags":["node-js"]},"Title":"fs module"},"Biconditional_Elimination":{"Path":"./Biconditional_Elimination.md","Slug":"Biconditional_Elimination","ID":"Biconditional_Elimination","Meta":{"tags":["logic"]},"Title":"Biconditional Elimination"},"Application_Layer_of_Internet_Protocol":{"Path":"./Application_Layer_of_Internet_Protocol.md","Slug":"Application_Layer_of_Internet_Protocol","ID":"Application_Layer_of_Internet_Protocol","Meta":{"created":"Friday, September 06, 2024","tags":["internet","networks"]},"Title":"Application Layer of the Internet Protocol"},"Validation_in_NodeJS":{"Path":"./Validation_in_NodeJS.md","Slug":"Validation_in_NodeJS","ID":"Validation_in_NodeJS","Meta":{"tags":["APIs","REST","node-js"]},"Title":"Creating a RESTful API: Validation"},"Boolean_algebra":{"Path":"./Boolean_algebra.md","Slug":"Boolean_algebra","ID":"Boolean_algebra","Meta":{"tags":["algebra","logic","nand-to-tetris","propositional-logic"]},"Title":"Boolean algebra"},"Substrings_in_Bash":{"Path":"./Substrings_in_Bash.md","Slug":"Substrings_in_Bash","ID":"Substrings_in_Bash","Meta":{"tags":["shell"]},"Title":"Substrings in Bash"},"React_errors":{"Path":"./React_errors.md","Slug":"React_errors","ID":"React_errors","Meta":{"tags":["javascript","react"]},"Title":"Errors"},"Zip_function_in_Python":{"Path":"./Zip_function_in_Python.md","Slug":"Zip_function_in_Python","ID":"Zip_function_in_Python","Meta":{"tags":["data-structures","python"]},"Title":"zip"},"Docker_CLI":{"Path":"./Docker_CLI.md","Slug":"Docker_CLI","ID":"Docker_CLI","Meta":{"created":"Saturday, March 30, 2024","id":"6g54","tags":["docker","shell"]},"Title":"Docker CLI"},"Regular_expressions_in_SQL":{"Path":"./Regular_expressions_in_SQL.md","Slug":"Regular_expressions_in_SQL","ID":"Regular_expressions_in_SQL","Meta":{"tags":["SQL","databases","regex"]},"Title":"Regular expressions in SQL"},"Rename_a_branch":{"Path":"./Rename_a_branch.md","Slug":"Rename_a_branch","ID":"Rename_a_branch","Meta":{"tags":["git","procedural"]},"Title":"Rename a branch"},"Processes":{"Path":"./Processes.md","Slug":"Processes","ID":"Processes","Meta":{"created":"Friday, June 21, 2024","id":"t70u","tags":["Linux","operating-systems"]},"Title":"Processes"},"The_kernel":{"Path":"./The_kernel.md","Slug":"The_kernel","ID":"The_kernel","Meta":{"tags":["computer-architecture","memory","operating-systems","systems-programming"]},"Title":"The kernel"},"Python_package_management":{"Path":"./Python_package_management.md","Slug":"Python_package_management","ID":"Python_package_management","Meta":{"tags":["data-types","python"]},"Title":"Package management"},"Restructure_URLs_lambda":{"Path":"./Restructure_URLs_lambda.md","Slug":"Restructure_URLs_lambda","ID":"Restructure_URLs_lambda","Meta":{"tags":["AWS","aws-lambda"]},"Title":"AWS Lambda examples"},"Awk":{"Path":"./Awk.md","Slug":"Awk","ID":"Awk","Meta":{"tags":["awk","shell"]},"Title":"Awk"},"Stacks":{"Path":"./Stacks.md","Slug":"Stacks","ID":"Stacks","Meta":{"tags":["data-structures"]},"Title":"Stacks"},"Process_module_in_NodeJS":{"Path":"./Process_module_in_NodeJS.md","Slug":"Process_module_in_NodeJS","ID":"Process_module_in_NodeJS","Meta":{"tags":["node-js"]},"Title":"The process module in Node.js"},"Practical_walkthrough_Lambda_creation_within_AWS":{"Path":"./Practical_walkthrough_Lambda_creation_within_AWS.md","Slug":"Practical_walkthrough_Lambda_creation_within_AWS","ID":"Practical_walkthrough_Lambda_creation_within_AWS","Meta":{"tags":["AWS","aws-lambda","node-js"]},"Title":"Practical walkthrough of creating a Lambda function via the AWS Management Console"},"Classes":{"Path":"./Classes.md","Slug":"Classes","ID":"Classes","Meta":{"tags":["OOP","typescript"]},"Title":"Classes"},"Split_into_array_in_Bash":{"Path":"./Split_into_array_in_Bash.md","Slug":"Split_into_array_in_Bash","ID":"Split_into_array_in_Bash","Meta":{"tags":["shell"]},"Title":"Splitting input into an array"},"Intro_to_the_Unix_shell":{"Path":"./Intro_to_the_Unix_shell.md","Slug":"Intro_to_the_Unix_shell","ID":"Intro_to_the_Unix_shell","Meta":{"tags":["shell"]},"Title":"Introduction to the Unix shell"},"Wildcards_in_SQL":{"Path":"./Wildcards_in_SQL.md","Slug":"Wildcards_in_SQL","ID":"Wildcards_in_SQL","Meta":{"tags":["SQL","databases"]},"Title":"Wildcards in SQL"},"Killing_processes":{"Path":"./Killing_processes.md","Slug":"Killing_processes","ID":"Killing_processes","Meta":{"tags":["procedural","shell"]},"Title":"Killing processes"},"Singleton_pattern":{"Path":"./Singleton_pattern.md","Slug":"Singleton_pattern","ID":"Singleton_pattern","Meta":{"tags":["OOP","design-patterns"]},"Title":"Singleton pattern"},"Comparing_React_classes_to_hooks":{"Path":"./Comparing_React_classes_to_hooks.md","Slug":"Comparing_React_classes_to_hooks","ID":"Comparing_React_classes_to_hooks","Meta":{"tags":["javascript","react"]},"Title":"Comparing class components to hook-based components"},"Operating_system_API":{"Path":"./Operating_system_API.md","Slug":"Operating_system_API","ID":"Operating_system_API","Meta":{"created":"Wednesday, July 17, 2024","tags":["operating-systems"]},"Title":"Operating system API"},"Internet_fundamentals":{"Path":"./Internet_fundamentals.md","Slug":"Internet_fundamentals","ID":"Internet_fundamentals","Meta":{"created":"Saturday, August 03, 2024","tags":["networks"]},"Title":"Internet fundamentals"},"Logical_indeterminacy":{"Path":"./Logical_indeterminacy.md","Slug":"Logical_indeterminacy","ID":"Logical_indeterminacy","Meta":{"tags":["logic","propositional-logic"]},"Title":"Logical indeterminacy"},"Props_in_React":{"Path":"./Props_in_React.md","Slug":"Props_in_React","ID":"Props_in_React","Meta":{"tags":["react","typescript"]},"Title":"Props"},"Arithmetic_Logic_Unit":{"Path":"./Arithmetic_Logic_Unit.md","Slug":"Arithmetic_Logic_Unit","ID":"Arithmetic_Logic_Unit","Meta":{"tags":["CPU"]},"Title":"Arithmetic Logic Unit (ALU)"},"1_GET":{"Path":"./1_GET.md","Slug":"1_GET","ID":"1_GET","Meta":{"tags":["APIs","REST","node-js"]},"Title":"Creating a RESTful API: GET requests"},"Soundness":{"Path":"./Soundness.md","Slug":"Soundness","ID":"Soundness","Meta":{"tags":["logic","propositional-logic"]},"Title":"Soundness"},"Dividing_fractions":{"Path":"./Dividing_fractions.md","Slug":"Dividing_fractions","ID":"Dividing_fractions","Meta":{"tags":["fractions","prealgebra"]},"Title":"Dividing fractions"},"Relays":{"Path":"./Relays.md","Slug":"Relays","ID":"Relays","Meta":{"created":"Monday, September 09, 2024","tags":["electronics"]},"Title":"Relays"},"Binary_arithmetic":{"Path":"./Binary_arithmetic.md","Slug":"Binary_arithmetic","ID":"Binary_arithmetic","Meta":{"tags":["binary"]},"Title":"Binary multiplication"},"Stack_memory":{"Path":"./Stack_memory.md","Slug":"Stack_memory","ID":"Stack_memory","Meta":{"created":"Tuesday, April 16, 2024","id":"1fig","tags":["memory"]},"Title":"Stack memory"},"Axioms_of_set_theory":{"Path":"./Axioms_of_set_theory.md","Slug":"Axioms_of_set_theory","ID":"Axioms_of_set_theory","Meta":{"tags":["set-theory","theorems"]},"Title":"Axioms of set theory"},"Delete_records_in_an_SQL_table":{"Path":"./Delete_records_in_an_SQL_table.md","Slug":"Delete_records_in_an_SQL_table","ID":"Delete_records_in_an_SQL_table","Meta":{"tags":["SQL","databases"]},"Title":"Deleting data in SQL"},"Module_wrapping_at_runtime":{"Path":"./Module_wrapping_at_runtime.md","Slug":"Module_wrapping_at_runtime","ID":"Module_wrapping_at_runtime","Meta":{"tags":["node-js"]},"Title":"Module wrapping at runtime in NodeJS"},"S3":{"Path":"./S3.md","Slug":"S3","ID":"S3","Meta":{"tags":["AWS"]},"Title":"S3"},"Enums":{"Path":"./Enums.md","Slug":"Enums","ID":"Enums","Meta":{"tags":["typescript"]},"Title":"Enums"},"CloudWatch":{"Path":"./CloudWatch.md","Slug":"CloudWatch","ID":"CloudWatch","Meta":{"tags":["AWS"]},"Title":"AWS CloudWatch"},"List_comprehension_in_Python":{"Path":"./List_comprehension_in_Python.md","Slug":"List_comprehension_in_Python","ID":"List_comprehension_in_Python","Meta":{"tags":["python"]},"Title":"List comprehension"},"Morgan":{"Path":"./Morgan.md","Slug":"Morgan","ID":"Morgan","Meta":{"tags":["middleware","node-js"]},"Title":"Morgan"},"Loops_in_bash":{"Path":"./Loops_in_bash.md","Slug":"Loops_in_bash","ID":"Loops_in_bash","Meta":{"tags":["shell"]},"Title":"Loops in Bash"},"Recursion":{"Path":"./Recursion.md","Slug":"Recursion","ID":"Recursion","Meta":{"tags":["algorithms","data-structures","recursion"]},"Title":"Recursion"},"ROM_versus_disk_loading":{"Path":"./ROM_versus_disk_loading.md","Slug":"ROM_versus_disk_loading","ID":"ROM_versus_disk_loading","Meta":{"created":"Monday, June 24, 2024","id":"rmvm","tags":["computer-architecture","memory"]},"Title":"ROM versus disk loading"},"Connect_to_Mongo_database":{"Path":"./Connect_to_Mongo_database.md","Slug":"Connect_to_Mongo_database","ID":"Connect_to_Mongo_database","Meta":{"tags":["databases","mongo-db","mongoose","node-js"]},"Title":"Connect to a database with Mongoose"},"Motherboard":{"Path":"./Motherboard.md","Slug":"Motherboard","ID":"Motherboard","Meta":{"tags":["computer-architecture","hardware"]},"Title":"Motherboard"},"Memory_versus_processor":{"Path":"./Memory_versus_processor.md","Slug":"Memory_versus_processor","ID":"Memory_versus_processor","Meta":{"created":"Thursday, August 01, 2024","tags":["question"]},"Title":"Memory versus processor"},"RESTful_APIs":{"Path":"./RESTful_APIs.md","Slug":"RESTful_APIs","ID":"RESTful_APIs","Meta":{"tags":["APIs","REST"]},"Title":"RESTful APIs"},"Relational_database_architecture":{"Path":"./Relational_database_architecture.md","Slug":"Relational_database_architecture","ID":"Relational_database_architecture","Meta":{"tags":["databases"]},"Title":"Relational database architecture"},"Electrons":{"Path":"./Electrons.md","Slug":"Electrons","ID":"Electrons","Meta":{"tags":["electricity","physics"]},"Title":"Electrons"},"Half_adder_and_full_adder":{"Path":"./Half_adder_and_full_adder.md","Slug":"Half_adder_and_full_adder","ID":"Half_adder_and_full_adder","Meta":{"tags":["binary","logic-gates"]},"Title":"The half adder and full adder"},"Analogue_and_digital":{"Path":"./Analogue_and_digital.md","Slug":"Analogue_and_digital","ID":"Analogue_and_digital","Meta":{"tags":["analogue"]},"Title":"Analogue and digital"},"Logical_possibility_and_necessity":{"Path":"./Logical_possibility_and_necessity.md","Slug":"Logical_possibility_and_necessity","ID":"Logical_possibility_and_necessity","Meta":{"tags":["logic","propositional-logic"]},"Title":"Logical possibility and necessity"},"Commutativity":{"Path":"./Commutativity.md","Slug":"Commutativity","ID":"Commutativity","Meta":{"tags":["algebra","number-theory","theorems"]},"Title":"The Commutative Property of Addition and Multiplication"},"Apollo_Server":{"Path":"./Apollo_Server.md","Slug":"Apollo_Server","ID":"Apollo_Server","Meta":{"tags":["APIs","REST","graphql"]},"Title":"Apollo Server"},"Error_handling_in_Python":{"Path":"./Error_handling_in_Python.md","Slug":"Error_handling_in_Python","ID":"Error_handling_in_Python","Meta":{"tags":["python"]},"Title":"Error handling and exceptions in Python"},"Data_types_in_Bash":{"Path":"./Data_types_in_Bash.md","Slug":"Data_types_in_Bash","ID":"Data_types_in_Bash","Meta":{"tags":["data-types","shell"]},"Title":"Data types in Bash"},"Basics_of_web_components":{"Path":"./Basics_of_web_components.md","Slug":"Basics_of_web_components","ID":"Basics_of_web_components","Meta":{"tags":[]},"Title":"Basics of Web Components"},"Role_of_unique_key_in_relational_databases":{"Path":"./Role_of_unique_key_in_relational_databases.md","Slug":"Role_of_unique_key_in_relational_databases","ID":"Role_of_unique_key_in_relational_databases","Meta":{"tags":["databases"]},"Title":"Unique key"},"The_PATH":{"Path":"./The_PATH.md","Slug":"The_PATH","ID":"The_PATH","Meta":{"tags":["shell"]},"Title":"The $PATH"},"Conjunction_Introduction":{"Path":"./Conjunction_Introduction.md","Slug":"Conjunction_Introduction","ID":"Conjunction_Introduction","Meta":{"tags":["logic","propositional-logic"]},"Title":"Conjunction Introduction"},"Lambda_triggers":{"Path":"./Lambda_triggers.md","Slug":"Lambda_triggers","ID":"Lambda_triggers","Meta":{"tags":["AWS","aws-lambda"]},"Title":"AWS Lambda triggers"},"Devices":{"Path":"./Devices.md","Slug":"Devices","ID":"Devices","Meta":{"tags":["Linux","computer-architecture"]},"Title":"Devices"},"Structuring_Express_applications":{"Path":"./Structuring_Express_applications.md","Slug":"Structuring_Express_applications","ID":"Structuring_Express_applications","Meta":{"tags":["APIs","REST","node-js"]},"Title":"Structuring Express applications"},"Maps_and_sets_in_JS":{"Path":"./Maps_and_sets_in_JS.md","Slug":"Maps_and_sets_in_JS","ID":"Maps_and_sets_in_JS","Meta":{"tags":["javascript"]},"Title":"Maps and Sets"},"ps":{"Path":"./ps.md","Slug":"ps","ID":"ps","Meta":{"tags":["Linux","shell"]},"Title":"Processes (ps)"},"Reducing_fractions":{"Path":"./Reducing_fractions.md","Slug":"Reducing_fractions","ID":"Reducing_fractions","Meta":{"tags":["fractions","prealgebra"]},"Title":"Reducing fractions to their lowest terms"},"DeMorgan's_Laws":{"Path":"./DeMorgan's_Laws.md","Slug":"DeMorgan's_Laws","ID":"DeMorgan's_Laws","Meta":{"tags":["##","logic","propositional-logic","theorems"]},"Title":"DeMorgan’s Laws"},"Resistance":{"Path":"./Resistance.md","Slug":"Resistance","ID":"Resistance","Meta":{"tags":["electricity","physics"]},"Title":"Resistance"},"Python_interpreter":{"Path":"./Python_interpreter.md","Slug":"Python_interpreter","ID":"Python_interpreter","Meta":{"tags":["python"]},"Title":"Python interpreter"},"IP_addresses":{"Path":"./IP_addresses.md","Slug":"IP_addresses","ID":"IP_addresses","Meta":{"created":"Friday, August 16, 2024","tags":["internet","networks"]},"Title":"IP addresses"},"Key_characteristics_of_GraphQL":{"Path":"./Key_characteristics_of_GraphQL.md","Slug":"Key_characteristics_of_GraphQL","ID":"Key_characteristics_of_GraphQL","Meta":{"tags":["APIs","graphql"]},"Title":"Key characteristics of GraphQL"},"Memory_addresses":{"Path":"./Memory_addresses.md","Slug":"Memory_addresses","ID":"Memory_addresses","Meta":{"created":"Friday, July 12, 2024","tags":["memory"]},"Title":"Memory addresses"},"Example_scenario_internet_data_transfer":{"Path":"./Example_scenario_internet_data_transfer.md","Slug":"Example_scenario_internet_data_transfer","ID":"Example_scenario_internet_data_transfer","Meta":{"created":"Friday, September 06, 2024","tags":["internet","networks"]},"Title":"Example scenario of data transfer accross the internet"},"The_Pragmatic_Programmer_1999":{"Path":"./The_Pragmatic_Programmer_1999.md","Slug":"The_Pragmatic_Programmer_1999","ID":"The_Pragmatic_Programmer_1999","Meta":{"tags":[]},"Title":"The Pragmatic Programmer (Hunt/Thomas, 1999)"},"Conditional_Elimination":{"Path":"./Conditional_Elimination.md","Slug":"Conditional_Elimination","ID":"Conditional_Elimination","Meta":{"tags":["logic","propositional-logic"]},"Title":"Conditional elimination"},"Natural_numbers":{"Path":"./Natural_numbers.md","Slug":"Natural_numbers","ID":"Natural_numbers","Meta":{"tags":["prealgebra"]},"Title":"Natural numbers"},"Any":{"Path":"./Any.md","Slug":"Any","ID":"Any","Meta":{"tags":["typescript"]},"Title":"Any"},"Whole_numbers":{"Path":"./Whole_numbers.md","Slug":"Whole_numbers","ID":"Whole_numbers","Meta":{"tags":["prealgebra"]},"Title":"The set of whole numbers"},"Set_DNS_settings":{"Path":"./Set_DNS_settings.md","Slug":"Set_DNS_settings","ID":"Set_DNS_settings","Meta":{"created":"Wednesday, June 12, 2024","id":"2w0e","tags":["Linux","networks","systemd"]},"Title":"Set DNS settings"},"Modelling_relationships_in_MongoDB":{"Path":"./Modelling_relationships_in_MongoDB.md","Slug":"Modelling_relationships_in_MongoDB","ID":"Modelling_relationships_in_MongoDB","Meta":{"tags":["databases","mongo-db","mongoose","node-js"]},"Title":"Modelling relationships between data"},"Negation_Introduction":{"Path":"./Negation_Introduction.md","Slug":"Negation_Introduction","ID":"Negation_Introduction","Meta":{"tags":["logic","propositional-logic"]},"Title":"Negation Introduction"},"Memory_leaks":{"Path":"./Memory_leaks.md","Slug":"Memory_leaks","ID":"Memory_leaks","Meta":{"tags":["memory"]},"Title":"Memory leaks"},"Aggregate_functions_in_SQL":{"Path":"./Aggregate_functions_in_SQL.md","Slug":"Aggregate_functions_in_SQL","ID":"Aggregate_functions_in_SQL","Meta":{"tags":["SQL","databases"]},"Title":"Aggregate functions in SQL"},"Interactive_staging":{"Path":"./Interactive_staging.md","Slug":"Interactive_staging","ID":"Interactive_staging","Meta":{"tags":["git"]},"Title":"Interactive staging"},"Type_guarding_and_narrowing_in_TS":{"Path":"./Type_guarding_and_narrowing_in_TS.md","Slug":"Type_guarding_and_narrowing_in_TS","ID":"Type_guarding_and_narrowing_in_TS","Meta":{"tags":["typescript"]},"Title":"Type narrowing and guarding"},"Bluetooth":{"Path":"./Bluetooth.md","Slug":"Bluetooth","ID":"Bluetooth","Meta":{"tags":["Linux","networks","procedural"]},"Title":"Bluetooth"},"Functions_in_Bash":{"Path":"./Functions_in_Bash.md","Slug":"Functions_in_Bash","ID":"Functions_in_Bash","Meta":{"tags":["shell"]},"Title":"Functions in Bash"},"Assembly":{"Path":"./Assembly.md","Slug":"Assembly","ID":"Assembly","Meta":{"created":"Tuesday, March 12, 2024","id":"2v5c","tags":["CPU"]},"Title":"Assembly"},"Python_execution":{"Path":"./Python_execution.md","Slug":"Python_execution","ID":"Python_execution","Meta":{"tags":["data-types","python"]},"Title":"Python execution"},"Capturing_user_input_in_Bash":{"Path":"./Capturing_user_input_in_Bash.md","Slug":"Capturing_user_input_in_Bash","ID":"Capturing_user_input_in_Bash","Meta":{"tags":["shell"]},"Title":"Capturing user input in Bash"},"None_in_Python":{"Path":"./None_in_Python.md","Slug":"None_in_Python","ID":"None_in_Python","Meta":{"tags":["data-types","python"]},"Title":"None in Python"},"Iterating_through_complex_data_structures_in_Python":{"Path":"./Iterating_through_complex_data_structures_in_Python.md","Slug":"Iterating_through_complex_data_structures_in_Python","ID":"Iterating_through_complex_data_structures_in_Python","Meta":{"tags":["python"]},"Title":"Iterating through complex data structures in Python"},"User_management_on_AWS":{"Path":"./User_management_on_AWS.md","Slug":"User_management_on_AWS","ID":"User_management_on_AWS","Meta":{"tags":["AWS"]},"Title":"User management and roles"},"Why_computers_use_binary":{"Path":"./Why_computers_use_binary.md","Slug":"Why_computers_use_binary","ID":"Why_computers_use_binary","Meta":{"tags":["binary","computer-architecture"]},"Title":"Why computers use binary"},"Intersection_types_in_TypeScript":{"Path":"./Intersection_types_in_TypeScript.md","Slug":"Intersection_types_in_TypeScript","ID":"Intersection_types_in_TypeScript","Meta":{"tags":["typescript"]},"Title":"Intersection types"},"Streams_in_NodeJS":{"Path":"./Streams_in_NodeJS.md","Slug":"Streams_in_NodeJS","ID":"Streams_in_NodeJS","Meta":{"tags":["node-js"]},"Title":"Handling streams with fs"},"Mapped_types_in_TS":{"Path":"./Mapped_types_in_TS.md","Slug":"Mapped_types_in_TS","ID":"Mapped_types_in_TS","Meta":{"tags":["typescript"]},"Title":"Mapped types in TypeScript"},"Strings_in_Bash":{"Path":"./Strings_in_Bash.md","Slug":"Strings_in_Bash","ID":"Strings_in_Bash","Meta":{"tags":["data-types","shell"]},"Title":"Strings in bash"},"Functions":{"Path":"./Functions.md","Slug":"Functions","ID":"Functions","Meta":{"tags":["react","typescript"]},"Title":"Functions"},"Update_an_SQL_table":{"Path":"./Update_an_SQL_table.md","Slug":"Update_an_SQL_table","ID":"Update_an_SQL_table","Meta":{"tags":["SQL","databases"]},"Title":"Updating an SQL table"},"Conditional_Introduction":{"Path":"./Conditional_Introduction.md","Slug":"Conditional_Introduction","ID":"Conditional_Introduction","Meta":{"tags":["logic","propositional-logic"]},"Title":"Conditional Introduction"},"Hexadecimal_number_system":{"Path":"./Hexadecimal_number_system.md","Slug":"Hexadecimal_number_system","ID":"Hexadecimal_number_system","Meta":{"tags":["computer-architecture","number-systems"]},"Title":"Hexadecimal number system"},"Additive_inverse_property":{"Path":"./Additive_inverse_property.md","Slug":"Additive_inverse_property","ID":"Additive_inverse_property","Meta":{"tags":["theorems"]},"Title":"Additive inverse property"},"Step_functions_and_state_machines":{"Path":"./Step_functions_and_state_machines.md","Slug":"Step_functions_and_state_machines","ID":"Step_functions_and_state_machines","Meta":{"tags":["AWS"]},"Title":"AWS Step functions and state machines"},"Breadboards":{"Path":"./Breadboards.md","Slug":"Breadboards","ID":"Breadboards","Meta":{"created":"Sunday, June 23, 2024","id":"jbf1","tags":["electronics"]},"Title":"Breadboards"},"Remote_tracking_branches":{"Path":"./Remote_tracking_branches.md","Slug":"Remote_tracking_branches","ID":"Remote_tracking_branches","Meta":{"tags":["git"]},"Title":"Remote tracking branches"},"Multiplicative_property_of_negative_one":{"Path":"./Multiplicative_property_of_negative_one.md","Slug":"Multiplicative_property_of_negative_one","ID":"Multiplicative_property_of_negative_one","Meta":{"tags":["prealgebra","theorems"]},"Title":"The Multiplicative Property of Negative One"},"Zero_property_of_multiplication":{"Path":"./Zero_property_of_multiplication.md","Slug":"Zero_property_of_multiplication","ID":"Zero_property_of_multiplication","Meta":{"tags":["prealgebra","theorems"]},"Title":"Zero property of multiplication"},"File_descriptors":{"Path":"./File_descriptors.md","Slug":"File_descriptors","ID":"File_descriptors","Meta":{"tags":["shell"]},"Title":"File descriptors"},"Accessing_secrets_from_a_Lambda":{"Path":"./Accessing_secrets_from_a_Lambda.md","Slug":"Accessing_secrets_from_a_Lambda","ID":"Accessing_secrets_from_a_Lambda","Meta":{"tags":["AWS","aws-lambda"]},"Title":"Accessing secrets from a Lambda"},"Switch_between_Python_vers":{"Path":"./Switch_between_Python_vers.md","Slug":"Switch_between_Python_vers","ID":"Switch_between_Python_vers","Meta":{"tags":["python"]},"Title":"Switch between Python versions locally"}}},"NeuronVersion":"1.9.35.3","Config":{"editUrl":null,"plugins":["neuronignore","links","tags","uptree","feed"],"siteBaseUrl":null,"author":null,"siteTitle":"My Zettelkasten","theme":"blue"},"Errors":{"Monitoring_processes_and_resources":{"tag":"ZettelIssue_MissingLinks","contents":["Monitoring_processes_and_resources",["Virtual_memory_and_the_MMU_in_Linux","Virtual_memory_and_the_MMU_in_Linux"]]},"Binary_colour_encoding":{"tag":"ZettelIssue_MissingLinks","contents":["Binary_colour_encoding",["Text_encoding"]]},"Formal_proofs_in_propositional_logic":{"tag":"ZettelIssue_MissingLinks","contents":["Formal_proofs_in_propositional_logic",["Syntax_of_sentential_logic"]]},"CPU_architecture":{"tag":"ZettelIssue_MissingLinks","contents":["CPU_architecture",["Memory"]]},"Chipset_and_controllers":{"tag":"ZettelIssue_MissingLinks","contents":["Chipset_and_controllers",["Memory"]]},"Bus":{"tag":"ZettelIssue_MissingLinks","contents":["Bus",["Memory"]]},"Latches":{"tag":"ZettelIssue_MissingLinks","contents":["Latches",["Memory"]]},"http_in_Node":{"tag":"ZettelIssue_MissingLinks","contents":["http_in_Node",["events"]]},"Environmental_and_shell_variables":{"tag":"ZettelIssue_MissingLinks","contents":["Environmental_and_shell_variables",["Shell-sessions-e6dd743dec1d4fe3b1ee672c8f9731f6","Shell-sessions-e6dd743dec1d4fe3b1ee672c8f9731f6"]]},"Format_specifiers_in_C":{"tag":"ZettelIssue_MissingLinks","contents":["Format_specifiers_in_C",["printing-values-in-c"]]},"Boolean_functions":{"tag":"ZettelIssue_MissingLinks","contents":["Boolean_functions",["Truth-tables"]]},"Redirect_to_dev_null":{"tag":"ZettelIssue_MissingLinks","contents":["Redirect_to_dev_null",["File_descriptors_and_redirection"]]},"What_are_disks":{"tag":"ZettelIssue_MissingLinks","contents":["What_are_disks",["Partitions"]]},"Boolean_function_synthesis":{"tag":"ZettelIssue_MissingLinks","contents":["Boolean_function_synthesis",["Digital_circuits"]]},"Logic_gates":{"tag":"ZettelIssue_MissingLinks","contents":["Logic_gates",["Truth-functional_connectives","Truth-tables"]]},"Integrated_circuits":{"tag":"ZettelIssue_MissingLinks","contents":["Integrated_circuits",["Digital_circuits"]]},"Filesystems":{"tag":"ZettelIssue_MissingLinks","contents":["Filesystems",["Basic_database_concepts"]]},"Creating_memory_with_NAND":{"tag":"ZettelIssue_MissingLinks","contents":["Creating_memory_with_NAND",["Digital_circuits"]]},"Application_structure":{"tag":"ZettelIssue_MissingLinks","contents":["Application_structure",["Routing"]]},"Classes_in_Python":{"tag":"ZettelIssue_MissingLinks","contents":["Classes_in_Python",["Memory"]]},"Managing_environments_in_NodeJS":{"tag":"ZettelIssue_MissingLinks","contents":["Managing_environments_in_NodeJS",["Process_object","node-config"]]},"Non_null_assertion_in_TypeScript":{"tag":"ZettelIssue_MissingLinks","contents":["Non_null_assertion_in_TypeScript",["Type_guarding_and_narrowing"]]},"The_History_of_Computing_Swade":{"tag":"ZettelIssue_MissingLinks","contents":["The_History_of_Computing_Swade",["Williams_Tube_RAM"]]},"Foreign_keys_in_SQL":{"tag":"ZettelIssue_MissingLinks","contents":["Foreign_keys_in_SQL",["Primary_key"]]},"Basic_properties_of_sets":{"tag":"ZettelIssue_MissingLinks","contents":["Basic_properties_of_sets",["symbols.html"]]},"Shell_sessions":{"tag":"ZettelIssue_MissingLinks","contents":["Shell_sessions",["Environmental-and-shell-variables-04d5ec7e8e2b486a93f002bf686e4bbb"]]},"Components_props_hooks_in_React":{"tag":"ZettelIssue_MissingLinks","contents":["Components_props_hooks_in_React",["Elements-992594b9cd2e483c85cddddffeb16f11"]]},"File_permissions_and_execution_in_Bash":{"tag":"ZettelIssue_MissingLinks","contents":["File_permissions_and_execution_in_Bash",["685254916b2642f189e6316b876e09c9"]]},"0_Introduction":{"tag":"ZettelIssue_MissingLinks","contents":["0_Introduction",["4_DELETE"]]},"Git_rebasing":{"tag":"ZettelIssue_MissingLinks","contents":["Git_rebasing",["Cherry_picking_a_branch"]]},"Truth_trees":{"tag":"ZettelIssue_MissingLinks","contents":["Truth_trees",["Consistency","Indeterminacy","Truth-tables"]]},"Validation_in_NodeJS":{"tag":"ZettelIssue_MissingLinks","contents":["Validation_in_NodeJS",["joi"]]},"Process_module_in_NodeJS":{"tag":"ZettelIssue_MissingLinks","contents":["Process_module_in_NodeJS",["events"]]},"Practical_walkthrough_Lambda_creation_within_AWS":{"tag":"ZettelIssue_MissingLinks","contents":["Practical_walkthrough_Lambda_creation_within_AWS",["AWS_API_Gateway"]]},"Logical_indeterminacy":{"tag":"ZettelIssue_MissingLinks","contents":["Logical_indeterminacy",["Consistency"]]},"Axioms_of_set_theory":{"tag":"ZettelIssue_MissingLinks","contents":["Axioms_of_set_theory",["beta"]]},"Motherboard":{"tag":"ZettelIssue_MissingLinks","contents":["Motherboard",["Memory"]]},"Role_of_unique_key_in_relational_databases":{"tag":"ZettelIssue_MissingLinks","contents":["Role_of_unique_key_in_relational_databases",["ACID_principle"]]},"Devices":{"tag":"ZettelIssue_MissingLinks","contents":["Devices",["Disks"]]},"DeMorgan's_Laws":{"tag":"ZettelIssue_MissingLinks","contents":["DeMorgan's_Laws",["Truth-functional_connectives"]]},"Whole_numbers":{"tag":"ZettelIssue_MissingLinks","contents":["Whole_numbers",["Symbols-and-formal-conventions-80aeaf1872f94a0d97a2e8d07e3855bd","Symbols-and-formal-conventions-80aeaf1872f94a0d97a2e8d07e3855bd"]]},"Modelling_relationships_in_MongoDB":{"tag":"ZettelIssue_MissingLinks","contents":["Modelling_relationships_in_MongoDB",["10_Joins"]]},"Functions_in_Bash":{"tag":"ZettelIssue_MissingLinks","contents":["Functions_in_Bash",["Passing_arguments_to_Bash_scripts"]]},"Streams_in_NodeJS":{"tag":"ZettelIssue_MissingLinks","contents":["Streams_in_NodeJS",["Memory"]]},"Step_functions_and_state_machines":{"tag":"ZettelIssue_MissingLinks","contents":["Step_functions_and_state_machines",["AWS_API_Gateway"]]}}} \ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/fs.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/fs.html deleted file mode 100644 index cf43993..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/fs.html +++ /dev/null @@ -1,78 +0,0 @@ -fs module - My Zettelkasten - - - - -

fs module

File System is an essential built-in module of Node that contains utility methods for working with files and directories.

Every method associated with fs has a blocking and asynchronous implementation. The former obviously blocks the event queue, the latter does not.

The synchronous methods are useful to have in some contexts but in general and with real-world applications, you should be using the async implementation so as to accord with the single-threaded event-driven architecture of Node.

Common I/0 methods

Read directory

Return a string array of all files in the current directory.

fs.readdir("./", function (err, files) {
-  if (err) {
-    console.error(err);
-  } else {
-    console.log(files);
-  }
-});

Read from file

fs.readFile("./lorem.md", "UTF-8", function (err, fileContents) {
-  console.log(fileContents);
-});

Write to file

let md = `A new file`;
-
-fs.writeFile("testFile.md", md.trim(), function () {
-  console.log("File was created");
-});

Appending to file

fs.appendFile("testFile.md", "new content");

Create directory

if (!fs.existsSync("directory_name")) {
-  fs.mkdir("directory_name", function (err) {
-    if (err) {
-      console.err(err);
-    }
-  });
-} else {
-  console.warn("Directory already exists");
-}

Rename and remove files

fs.rename("./filename.js", "./newname.js", function () {
-  console.log("file renamed");
-});
// Remove file
-fs.unlink("./file-to-delete", function (err) {
-  if (err) {
-    console.error(err);
-  }
-});

Rename and remove directories

// Best to use synchronous method here
-fs.rmSync("/dir", { recursive: true, force: true });

Streams

See Handling streams with fs

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/http_in_Node.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/http_in_Node.html deleted file mode 100644 index 16f5d74..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/http_in_Node.html +++ /dev/null @@ -1,76 +0,0 @@ -http module - My Zettelkasten - - - - -

http module

The HTTP Module allows us to create a web server that listens for HTTP requests on a given port. It is therefore perfect for creating backends for client-side JavaScript.

Creating a server

An HTTP server is another instance of an events). It therefore has all the same methods as the EventEmitter class: on, emit, addListener etc. This demonstrates again how much of Node’s core functionality is based on event emitters.

Creating a server

const http = require("http");
-
-const server = http.createServer(); // Create server as emitter
-
-// Register functions to run when listener is triggered
-server.on("connection", (socket) => {
-  console.log("new connection...");
-});
-
-server.listen(3000);
-console.log("Listening on port 3000");

This server is functionally equivalent to a generic event emitter:

// Raise an event
-const emitter = new EventEmitter("messageLogged");
-
-// Register a listener
-emitter.on("messagedLogged", function () {
-  console.log("The listener was called.");
-});

Whenever a request is made to this server, it raises an event. We can therefore target it with the on method and make it execute a function when requests are made.

If we were to start the server by running the file and we then used a browser to navigate to the port, we would see new connection logged every time we refresh the page.

Sockets and req, res

A socket is a generic protocol for client-server communication. Crucially it allows simultaneous communication both ways. The client can contact the server but the server can also contact the client. Our listener function above uses a socket as the callback function but in most cases this is quite low-level, not distinguishing responses from requests. It is more likely that you would initiate a request, resource architecture in place of a socket:

const server = http.createServer((req, res) => {
-  if (req.url === "/") {
-    res.write("hello");
-    res.end();
-  }
-});

Return JSON

Below is an example of using this architecture to return JSON to the client:

const server = http.createServer((req, res) => {
-  if (req.url === "/products") {
-    res.write(JSON.stringify(["shoes", "lipstick", "cups"]));
-    res.end();
-  }
-});

Express

In reality you would rarely use the http module directly to create a server. This is because it is quite low level and each response must be written in a linear fashion as with the two URLs in the previous example. Instead we use Express which is a framework for creating servers and routing that is an abstraction on top of the core HTTP module.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/impulse.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/impulse.html deleted file mode 100644 index ce8533d..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/impulse.html +++ /dev/null @@ -1,50 +0,0 @@ -Impulse - My Zettelkasten - - - - -

Impulse

Errors

Notes not belonging to any heterarchy:

The notebook has 462 notes and 294 links. It has 0 clusters in its folgezettel graph. Each cluster's folgezettel heterarchy is rendered as a forest.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/index.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/index.html deleted file mode 100644 index dec62cd..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/index.html +++ /dev/null @@ -1,50 +0,0 @@ -Eòlas - My Zettelkasten - - - - -

Eòlas

Hi, I’m Thomas. This is the frontend of Eòlas, my personal knowledge base. It is a Zettelkasten work in progess comprising notes from my self-directed study of software engineering and computer science.

Build ID: d0ed26d0-cdc8-4643-8c09-445408195f9b

Published: Sat 19 Oct 2024 13:00:06

Recent edits

All notes (463)

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/journald.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/journald.html deleted file mode 100644 index 4537e5a..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/journald.html +++ /dev/null @@ -1,52 +0,0 @@ -journald - My Zettelkasten - - - - -

journald

journald is a program that comes as default with systemd. It is a service for collecting and storing system-level log data. I keeps a track of all kernel processes. It is invaluable when tracing the source of problems and errors that may arise on the system level. It keeps a track of all kernal processes.

journalctl

We use journalctl to access the logs. The command by itself outputs the entire log which will be huge and hard to scroll through. We can refine the results with modifiers.

View logs for a specific process with pid

journalctl _PID=1234

View logs for a specific time period

This can be really helpful since you can bracket the most recent events which will be more memorable.

journalctl -S -1h

View logs for a specfic systemd unit

journalctl -u [unit_name] -e

View boot logs

journalctl -b

Identify specific boot

journalctl --list-boots
-

List only kernel entries to the journal

journalctl -k
-
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/jq.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/jq.html deleted file mode 100644 index 142c05f..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/jq.html +++ /dev/null @@ -1,61 +0,0 @@ -jq - My Zettelkasten - - - - -

jq

Remove property

Remove property from a JSON array of objects:

{
-  "member_inputs": [
-    {
-      "name": "Thomas",
-      "input_type": "select"
-    },
-    {
-      "name": "Martha",
-      "input_type": "text"
-    }
-  ]
-}
jq '.member_details |= map(del(.input_type))' memberDetails.json

Add ‘-i’ to modify the source file directly (in-place)

Multiple properties can be deleted simply by chaining, e.g.(del(.input_type, .another_property))

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/ps.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/ps.html deleted file mode 100644 index 702d45e..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/ps.html +++ /dev/null @@ -1,91 +0,0 @@ -Processes (ps) - My Zettelkasten - - - - -

Processes (ps)

ps allows us to control user processes from the shell.

The command in its most minimal application returns the following

  PID TTY       TIME     CMD
-  2437 pts/2    00:00:01 zsh
-  7112 pts/2    00:00:00 ps

With the -e modifier we can list more processes:

 PID TTY          TIME CMD
-      1 ?        00:00:05 systemd
-      2 ?        00:00:00 kthreadd
-      3 ?        00:00:00 rcu_gp
-      4 ?        00:00:00 rcu_par_gp
-      5 ?        00:00:00 netns
-      7 ?        00:00:00 kworker/0:0H-events_highpri
-      9 ?        00:00:00 mm_percpu_wq
-     11 ?        00:00:00 rcu_tasks_kthread
-     12 ?        00:00:00 rcu_tasks_rude_kthread
-     13 ?        00:00:00 rcu_tasks_trace_kthread
-     14 ?        00:00:08 ksoftirqd/0
-     15 ?        00:03:20 rcu_preempt
-     16 ?        00:00:00 rcub/0
-     17 ?        00:00:00 migration/0
-     18 ?        00:00:00 idle_inject/0
-     20 ?        00:00:00 cpuhp/0
-     21 ?        00:00:00 cpuhp/1
-     22 ?        00:00:00 idle_inject/1
-     23 ?        00:00:00 migration/1
-
pid
-
Process ID: every currently running process has a unique ID
-
tty
-
The terminal device where the process is running
-
Time
-
The amount of CPU time in minutes and seconds that the process has used so far. The total amount of time that the process has spent running instructions on the processor.
-
cmd
-
The command used to run the program. Note this can change during the running of the program.
-
-

Modifiers

-
ps x
-
Show all running processes
-
ps ax
-
Show all processes not just the ones you, the current user, own
-
ps u
-
Show detailed info on processes
-
ps w
-
Show full command names
-
-

Process termination

The general schema is: kill [pid]. This allows for process clean-up. If this doesn’t succeed you can force with KILL [pid] which will terminate the process immediately but is obviously more risky.

We can also start/stop processes with modifiers on kill:

  • kill -STOP pid
  • kill -CONT pid
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/python_advent_learnings.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/python_advent_learnings.html deleted file mode 100644 index 55e5d5e..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/python_advent_learnings.html +++ /dev/null @@ -1,69 +0,0 @@ -Python advent learnings - My Zettelkasten - - - - -

Python advent learnings

Construct paths without hard-coding absolute path

puzzle_input_path = os.path.join(os.path.dirname(__file__), "data/test_input.txt")
-

Read file by line and store in variable

puzzle_input_path = os.path.join(os.path.dirname(__file__), "data/test_input.txt")
-
-def getPuzzleInput(file_path):
-    with open(file_path, "r") as file:
-        return [line.strip() for line in file]
-
-
-puzzle_input = getPuzzleInput(puzzle_input_path)
-

Conditional tests for members of arrays

Check that all elements are greater than zero:

if all(element >= 0 for element in array):
-    print('All elements greater than 0')

Check if any element is less than 0:

if any(element < 0 for element in array):
-    print('There is an element that is less than 0')

Check for substring:

text = "latest test"
-if "test" in text:
-    return True

Control flow in loop

for counter_values in games:
-    colour = counter_values[1]
-    count = int(counter_values[0])
-    if colour in initial_values.keys() and count > initial_values[colour]:
-        break
-else:
-    valid_games_count += game_number

The use of the else clause here is a special feature of Python. The else clause after a for loop will normally only execute when the loop has finished iterating over the list, but not when the loop is terminated by a break statement.

The else clause is executed if the for loop completes normally. If the break statement is executed (i.e., if any count in counter_values is greater than the corresponding count in initial_values), the for loop is terminated and the else clause is skipped.

Here the combination of a for loop and the break statement creates if, else logic. If the break condition is not reached, then the else block runs for every iteration of the loop.

Multiple loop in list comprehension

games = [item.strip().split() for game in games for item in game.split(",")]
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/systemd.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/systemd.html deleted file mode 100644 index 3e8c8cc..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/systemd.html +++ /dev/null @@ -1,80 +0,0 @@ -systemd - My Zettelkasten - - - - -

systemd

Once the boot process has completed and the bootloader has located the kernel and injected it into memory the first user space program runs: init (for initialisation). init is a daemon process that continues running until shutdown and is responsible for starting all the processes that are prerequisites for user space. For example: network connections, disk access, user logins etc. init is the parent of all processes: PID1. Whilst it does a lot of its work in quick succession at boot time it is not limited to the this stage of the lifescycle but runs continuously in reponse to new user events.

On Linux systems systemd is used to implement init and therefore systemd will always be listed as PID1.

systemd is directly accessible from user space and provides a straightforward way to enable/disable, start/stop system level processes

systemd can track individual service daemons after they start, and group together multiple processes associated with a service, giving you more power and insight into exactly what is running on the system How Linux Works: Third Edition, Brian Ward 2021

How systemd works

Goal-directed units

systemd works on the basis of goals. Each goal is system task defined as a unit. A unit contains instructions and a specification of dependencies to other units.

When activating a unit, systemd first activates the dependencies and then moves onto the details of the unit itself. init as implemented by systemd does not follow a rigid sequence every time, initialising units in the same sequence and waiting for one to complete before starting another. Instead it activates units whenever they are ready. This, its parallelized nature, is one of the main advantages over previous programs that managed the init sequence on Linux (such as for example System V);

Unit types

Units are organised into unit types. The main types that run at boot time are as follows:

  • service units (.service)
    • control service daemons
  • socket units (.socket)
    • handle incoming network connection request locations
  • device units (.device)
    • disks and other devices
  • mount units (.mount)
    • handle the attachment of filesystems to the system
  • target units
    • control other units by organising them into groups

For example, at boot, a target unit called default.target groups together a number of service and mount units as dependencies. These then run in a graph-like dependency structure where a unit that comes late in the boot process can depend on several previous units making earlier branches of a dependency tree join back together.

systemd configuration files

Units are managed via systemd configuration files.

Configuration file locations

System level systemd config files are located in the system unit directory at /usr/lib/systemd/system. You shouldn’t change or manipulate these files or attempt to add new config files here since they will be overwritten by the system.

systemd global unit files

Local definitions that relate to the specific user and where the user herself can define units are located in the system configuration directory: /etc/systemd/system.

systemd local unit files, specific to the currently logged-in user

Example files

Below is the systemd service file for the creation of UUIDs:

[Unit]
-Description=Daemon for generating UUIDs
-Documentation=man:uuidd(8)
-Requires=uuidd.socket
-
-[Service]
-ExecStart=/usr/sbin/uuidd --socket-activation
-Restart=no
-User=uuidd
-Group=uuidd
-ProtectSystem=strict
-ProtectHome=yes
-PrivateDevices=yes
-PrivateUsers=yes
-ProtectKernelTunables=yes
-ProtectKernelModules=yes
-ProtectControlGroups=yes
-MemoryDenyWriteExecute=yes
-ReadWritePaths=/var/lib/libuuid/
-SystemCallFilter=@default @file-system @basic-io @system-service @signal @io-event @network-io
-
-[Install]
-Also=uuidd.socket
  • The Unit section provides metadata about the unit including which systemd dependencies it has
  • Service constitutes the main specification for the unit
  • Install is the call to set the dependencies running before the Service functions are accessible.

systemd operations: systemctl

The systemctl command is the chief way of interacting with systemd. You use it to activate and deactivate services, list their status, reload the configuration and so.

View the dependency graph

systemctl status by itself will print a long list of units grouped by their dependency relations. It will also provide some metadata about the current systemd boot context.

Viewing active units

Below I have listed the running units pertaining to bluetooth:

$ systemctl list-units | grep bluetooth
- sys-devices-pci0000:00-0000:00:14.0-usb3-3\x2d10-3\x2d10:1.0-bluetooth-hci0-hci0:3585.device                                   loaded active plugged   /sys/devices/pci0000:00/0000:00:14.0/usb3/3-10/3-10:1.0/bluetooth/hci0/hci0:3585
-  sys-devices-pci0000:00-0000:00:14.0-usb3-3\x2d10-3\x2d10:1.0-bluetooth-hci0.device                                             loaded active plugged   /sys/devices/pci0000:00/0000:00:14.0/usb3/3-10/3-10:1.0/bluetooth/hci0
-  sys-subsystem-bluetooth-devices-hci0.device                                                                                    loaded active plugged   /sys/subsystem/bluetooth/devices/hci0
-  sys-subsystem-bluetooth-devices-hci0:3585.device                                                                               loaded active plugged   /sys/subsystem/bluetooth/devices/hci0:3585
-  bluetooth.service                                                                                                              loaded active running   Bluetooth service
-  bluetooth.target                                                                                                               loaded active active    Bluetooth Support

List jobs

Requests to activate, reactivate and restart units are called jobs in systemd. They can be thought of as unit state changes. Current jobs can be listed with systemctl list-jobs.

This will most likely return No jobs running if the computer has been running for a while. Most jobs execute at boot.

Enable/disable, start/stop units

If a unit has dependencies it is necessary to enable it before starting it. This installs the dependencies.

systemctl enable mongodb.service
-Created symlink /etc/systemd/system/multi-user.target.wants/mongodb.service → /usr/lib/systemd/system/mongodb.service.

Then we can start:

systemctl start mongodb.service

To stop the service:

systemctl stop mongodb.service

After this we should disable it, in order to remove any symbolic links it has created on the system as part of the install process:

systemctl disable mongodb.service
-Removed "/etc/systemd/system/multi-user.target.wants/mongodb.service".

Why use systemd over cron ?

https://mark.stosberg.com/2016-08-26-rsnapshot-and-systemd/

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/systemd_status.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/systemd_status.html deleted file mode 100644 index a760e31..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/systemd_status.html +++ /dev/null @@ -1,72 +0,0 @@ -Get status of a specific unit - My Zettelkasten - - - - -

Get status of a specific unit

Here I have requested the status of the currently running mongodb unit:

$ systemctl status mongod
-mongodb.service - MongoDB Database Server
-     Loaded: loaded (/usr/lib/systemd/system/mongodb.service; enabled; preset: disabled)
-     Active: active (running) since Wed 2022-08-17 07:25:27 BST; 24h ago
-       Docs: https://docs.mongodb.org/manual
-   Main PID: 931 (mongod)
-     Memory: 304.1M
-        CPU: 2min 18.630s
-     CGroup: /system.slice/mongodb.service
-             └─931 /usr/bin/mongod --config /etc/mongodb.conf
-Aug 17 07:25:27 archbish systemd[1]: Started MongoDB Database Server.****

In addition to the core info it tells us the unit type. In this case it is a service.

We can also view the journal entry for the given unit. This provides you with its diagnostic log messages:

journalctl --unit=mongodb.service
-- Boot b9565dfe8aca4d069143209b3aa84d8e --
-Aug 05 18:31:30 archbish systemd[1]: Started MongoDB Database Server.
-Aug 06 14:27:33 archbish systemd[1]: mongodb.service: Deactivated successfully.
-Aug 06 14:27:33 archbish systemd[1]: mongodb.service: Consumed 3min 17.598s CPU time.
--- Boot 01922f84c3bd4b3a8f11824cf05f7320 --
-Aug 07 11:58:09 archbish systemd[1]: Started MongoDB Database Server.
-Aug 08 14:43:01 archbish systemd[1]: mongodb.service: Deactivated successfully.
-Aug 08 14:43:01 archbish systemd[1]: mongodb.service: Consumed 5min 28.760s CPU time.
--- Boot e52b735e115c43bdad8c00462aaff395 --
-Aug 10 13:13:22 archbish systemd[1]: Started MongoDB Database Server.
-Aug 11 07:46:40 archbish systemd[1]: mongodb.service: Deactivated successfully.
-Aug 11 07:46:40 archbish systemd[1]: mongodb.service: Consumed 2min 16.629s CPU time.

Each entry is organised around specific boots.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/v8.html b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/v8.html deleted file mode 100644 index 633826a..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/.neuron/output/v8.html +++ /dev/null @@ -1,50 +0,0 @@ -v8 - My Zettelkasten - - - - -

v8

The v8 module is useful for providing information about the resource-usage of your Node.js apps, such as memory usage and capacity.

\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/1726814727_LUWV.md b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/1726814727_LUWV.md deleted file mode 100644 index 88527f3..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/1726814727_LUWV.md +++ /dev/null @@ -1 +0,0 @@ -# Turing Mach diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/1.4-Input-Process-Output.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/1.4-Input-Process-Output.png deleted file mode 100644 index 9f804e1..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/1.4-Input-Process-Output.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/3-bit-adder-diagram.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/3-bit-adder-diagram.png deleted file mode 100644 index 7d993e7..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/3-bit-adder-diagram.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/540px-PDP-8_(1).jpg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/540px-PDP-8_(1).jpg deleted file mode 100644 index 1f67d13..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/540px-PDP-8_(1).jpg and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/DMUX.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/DMUX.png deleted file mode 100644 index 02f118d..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/DMUX.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/Domain _ Billing.pdf b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/Domain _ Billing.pdf deleted file mode 100644 index 7c47488..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/Domain _ Billing.pdf and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/EDSAC.jpg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/EDSAC.jpg deleted file mode 100644 index 48fad3d..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/EDSAC.jpg and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/FL-Databases-1.5_terminology.gif b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/FL-Databases-1.5_terminology.gif deleted file mode 100644 index 1040c3d..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/FL-Databases-1.5_terminology.gif and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/Harvard_Mark_1.jpg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/Harvard_Mark_1.jpg deleted file mode 100644 index 4ac0f1b..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/Harvard_Mark_1.jpg and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/LMC_5.gif b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/LMC_5.gif deleted file mode 100644 index 3399182..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/LMC_5.gif and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/MANIAC_computer.jpg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/MANIAC_computer.jpg deleted file mode 100644 index 5b92088..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/MANIAC_computer.jpg and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/MUX.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/MUX.png deleted file mode 100644 index ca8b128..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/MUX.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/Memory-Hierarchy.jpg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/Memory-Hierarchy.jpg deleted file mode 100644 index 4c9bba8..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/Memory-Hierarchy.jpg and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/ORelim1.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/ORelim1.png deleted file mode 100644 index 75731b0..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/ORelim1.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/ORelim2.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/ORelim2.png deleted file mode 100644 index 3bb7113..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/ORelim2.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/OS-api.svg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/OS-api.svg deleted file mode 100644 index 1bb6d85..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/OS-api.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - -
OS UI
Shell
OS API
OS internals
User
Application
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/Pasted_image_20220319135558.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/Pasted_image_20220319135558.png deleted file mode 100644 index 6298a65..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/Pasted_image_20220319135558.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/Pasted_image_20220319135805.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/Pasted_image_20220319135805.png deleted file mode 100644 index 37109dd..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/Pasted_image_20220319135805.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/Pasted_image_20220319135823.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/Pasted_image_20220319135823.png deleted file mode 100644 index 2b5fd00..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/Pasted_image_20220319135823.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/Pasted_image_20220411082627.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/Pasted_image_20220411082627.png deleted file mode 100644 index 82fd434..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/Pasted_image_20220411082627.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/REST_request-load.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/REST_request-load.png deleted file mode 100644 index 74792c2..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/REST_request-load.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/SAGE_command_post.jpg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/SAGE_command_post.jpg deleted file mode 100644 index 67f2cd0..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/SAGE_command_post.jpg and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/Screenshot_2020-08-09_at_21.34.48.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/Screenshot_2020-08-09_at_21.34.48.png deleted file mode 100644 index bbbb066..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/Screenshot_2020-08-09_at_21.34.48.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/Screenshot_2021-05-11_at_18.51.02.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/Screenshot_2021-05-11_at_18.51.02.png deleted file mode 100644 index 15ee66a..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/Screenshot_2021-05-11_at_18.51.02.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/Screenshot_2021-05-11_at_18.55.23.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/Screenshot_2021-05-11_at_18.55.23.png deleted file mode 100644 index 1da93a9..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/Screenshot_2021-05-11_at_18.55.23.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/TCP_IP.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/TCP_IP.png deleted file mode 100644 index 9d9d46b..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/TCP_IP.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/Turing_machines_01.gif b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/Turing_machines_01.gif deleted file mode 100644 index 974e3b3..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/Turing_machines_01.gif and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/Zuse-Z3.jpeg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/Zuse-Z3.jpeg deleted file mode 100644 index 389fa52..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/Zuse-Z3.jpeg and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/abc-computer.jpg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/abc-computer.jpg deleted file mode 100644 index 8d67dfe..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/abc-computer.jpg and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/access-key-aws.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/access-key-aws.png deleted file mode 100644 index d6ce20f..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/access-key-aws.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/all-layers-of-IP.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/all-layers-of-IP.png deleted file mode 100644 index 6d56840..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/all-layers-of-IP.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/altair-8800.jpg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/altair-8800.jpg deleted file mode 100644 index 3015ad2..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/altair-8800.jpg and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/analog-digital.svg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/analog-digital.svg deleted file mode 100644 index 35f441a..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/analog-digital.svg +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - 12 - 82 - 78 - 63 - 39 - 70 - 44 - 9 - -36 - -69 - -80 - -59 - -14 - 42 - Analog - Digital - - \ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/and-gate-new-2.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/and-gate-new-2.png deleted file mode 100644 index 58eab1d..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/and-gate-new-2.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/and-transistor.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/and-transistor.png deleted file mode 100644 index a18d128..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/and-transistor.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/api-gateway-trigger.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/api-gateway-trigger.png deleted file mode 100644 index 7ab0e1a..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/api-gateway-trigger.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/apollo-explorer.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/apollo-explorer.png deleted file mode 100644 index 4725eeb..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/apollo-explorer.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/apple1.jpg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/apple1.jpg deleted file mode 100644 index f9d9c2a..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/apple1.jpg and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/apple2.jpg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/apple2.jpg deleted file mode 100644 index 9de3fee..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/apple2.jpg and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/application-layer-data.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/application-layer-data.png deleted file mode 100644 index 9f1c6b2..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/application-layer-data.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/arithmometer.jpg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/arithmometer.jpg deleted file mode 100644 index 4875853..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/arithmometer.jpg and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/async.svg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/async.svg deleted file mode 100644 index fd85032..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/async.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - -
asynchronous
asynchronous
Text is not SVG - cannot display
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/atom-diagram.svg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/atom-diagram.svg deleted file mode 100644 index bde130b..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/atom-diagram.svg +++ /dev/null @@ -1 +0,0 @@ -Zeichenfläche 1 \ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/awk-outline.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/awk-outline.png deleted file mode 100644 index 9ff7848..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/awk-outline.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/basic-circuit.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/basic-circuit.png deleted file mode 100644 index f72f364..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/basic-circuit.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/bi-intro.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/bi-intro.png deleted file mode 100644 index 23a0572..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/bi-intro.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/biconditional-elim.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/biconditional-elim.png deleted file mode 100644 index c34918b..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/biconditional-elim.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/bjt-terminals.jpg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/bjt-terminals.jpg deleted file mode 100644 index 8b2720e..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/bjt-terminals.jpg and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/breadboard-DIP.jpg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/breadboard-DIP.jpg deleted file mode 100644 index 4e54dec..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/breadboard-DIP.jpg and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/breadboard-diagram.jpg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/breadboard-diagram.jpg deleted file mode 100644 index fba3eb0..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/breadboard-diagram.jpg and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/breakdown.svg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/breakdown.svg deleted file mode 100644 index 3258648..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/breakdown.svg +++ /dev/null @@ -1,39 +0,0 @@ - - - Artboard - - - - - - - - - - - - - - O(1) - - - - - - O(n) - - - - - - O(1) - - - - - - O(1) - - - - \ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/cell-comparison.svg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/cell-comparison.svg deleted file mode 100644 index 65a4a4f..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/cell-comparison.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - -
Current
Current
Sum of all cells
Sum of all cells
Series-Parallel
Series-Parallel
Series
Series
Parallel
Parallel
Same for all cells
Same for all cells
Sum of all cells
Sum of all cells
Voltage
Voltage
Sum of all cells
Sum of all cells
Same for all cells
Same for all cells
Sum of all cells
Sum of all cells
Text is not SVG - cannot display
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/change-dns-server.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/change-dns-server.png deleted file mode 100644 index 05039ce..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/change-dns-server.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/charge-cylinder.svg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/charge-cylinder.svg deleted file mode 100644 index 6325077..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/charge-cylinder.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/cherry-pick.svg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/cherry-pick.svg deleted file mode 100644 index f351da4..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/cherry-pick.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - -
main
main
feature
featu...
cherry-pick
cherr...
xyz
xyz
pqr
pqr
Text is not SVG - cannot display
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/circ-batt-final.svg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/circ-batt-final.svg deleted file mode 100644 index 1d2a2ae..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/circ-batt-final.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - -
1.5 V
1.5 V
Text is not SVG - cannot display
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/clock_pulses.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/clock_pulses.png deleted file mode 100644 index 7e69aaa..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/clock_pulses.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/cloud-formation-stack.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/cloud-formation-stack.png deleted file mode 100644 index fc65b7a..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/cloud-formation-stack.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/cloudwatch-logs.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/cloudwatch-logs.png deleted file mode 100644 index e73c386..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/cloudwatch-logs.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/combined-merge-hist.svg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/combined-merge-hist.svg deleted file mode 100644 index 30e5259..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/combined-merge-hist.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/complex-number-calculator-bell-labs.jpg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/complex-number-calculator-bell-labs.jpg deleted file mode 100644 index d0d65b4..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/complex-number-calculator-bell-labs.jpg and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/complex-tree.svg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/complex-tree.svg deleted file mode 100644 index 9cbba30..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/complex-tree.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - -
C
C
7~~D
7~~D
5
5
~C
~C
SM
SM
1
1
2 ~vD
2 ~vD
4
4
~(C v A)
~(C v A)
SM
SM
2
2
A (B & ~C)
A ⊃ (B & ~C)
C ≡ ~A
C ≡ ~A
SM
SM
3
3
~C
~C
~A
~A
~~A
~~A
~A
~A
4
4
6
6
7
7
A
A
5
5
2 ~vD
2 ~vD
3≡D
3≡D
3≡D
3≡D
Viewer does not support full SVG 1.1
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/comptometer.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/comptometer.png deleted file mode 100644 index 071bccd..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/comptometer.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/cond-elim.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/cond-elim.png deleted file mode 100644 index 993a336..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/cond-elim.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/cond-intro.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/cond-intro.png deleted file mode 100644 index 5287392..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/cond-intro.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/conditional-decomposition-rule.svg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/conditional-decomposition-rule.svg deleted file mode 100644 index a400a50..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/conditional-decomposition-rule.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - -
~P
~P
Q
Q
 Q
P ⊃ Q
1
1
2
2
SM
SM
1⊃D
1⊃D
Viewer does not support full SVG 1.1
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/conjunc-elim.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/conjunc-elim.png deleted file mode 100644 index fd66290..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/conjunc-elim.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/conjunc-intro.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/conjunc-intro.png deleted file mode 100644 index 3a8d642..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/conjunc-intro.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/conjunction-decomposition-rule.svg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/conjunction-decomposition-rule.svg deleted file mode 100644 index 5abcbd2..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/conjunction-decomposition-rule.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - -
P & Q
P & Q
1
1
2
2
3
3
Q
Q
SM
SM
1&D
1&D
1&D
1&D
Viewer does not support full SVG 1.1
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/container-lifecycle.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/container-lifecycle.png deleted file mode 100644 index c3f98e0..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/container-lifecycle.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/container-versus-vm.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/container-versus-vm.png deleted file mode 100644 index b30fe6b..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/container-versus-vm.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/containers-in-userspace.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/containers-in-userspace.png deleted file mode 100644 index 04705fc..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/containers-in-userspace.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/correct_push_button.jpg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/correct_push_button.jpg deleted file mode 100644 index cbbc0c3..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/correct_push_button.jpg and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/derivation_from_contradiction.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/derivation_from_contradiction.png deleted file mode 100644 index 2c81072..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/derivation_from_contradiction.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/differential_analyser_bush.jpg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/differential_analyser_bush.jpg deleted file mode 100644 index b5837ab..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/differential_analyser_bush.jpg and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/diode-led.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/diode-led.png deleted file mode 100644 index 00c3334..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/diode-led.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/diode.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/diode.png deleted file mode 100644 index fddfca4..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/diode.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/dipole-again.svg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/dipole-again.svg deleted file mode 100644 index 13cac44..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/dipole-again.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - -
E
E
North
North
E
E
South
South
Spin
Spin
Spin
Spin
Text is not SVG - cannot display
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/disjunc-elim.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/disjunc-elim.png deleted file mode 100644 index 0127c59..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/disjunc-elim.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/disjunc-intro.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/disjunc-intro.png deleted file mode 100644 index 6047493..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/disjunc-intro.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/disjunction-decomposition-rule.svg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/disjunction-decomposition-rule.svg deleted file mode 100644 index 144b2e8..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/disjunction-decomposition-rule.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - -
P
P
Q
Q
P v Q
P v Q
1
1
2
2
SM
SM
1vD
1vD
Viewer does not support full SVG 1.1
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/dock-architecture.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/dock-architecture.png deleted file mode 100644 index 84e6b6c..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/dock-architecture.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/draw.io-Page-8.drawio.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/draw.io-Page-8.drawio.png deleted file mode 100644 index 8c111e9..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/draw.io-Page-8.drawio.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/draw.io-Page-9.drawio.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/draw.io-Page-9.drawio.png deleted file mode 100644 index 9614777..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/draw.io-Page-9.drawio.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/drawio-Page-7.drawio.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/drawio-Page-7.drawio.png deleted file mode 100644 index e86a851..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/drawio-Page-7.drawio.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/dsfdsfsdfwe.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/dsfdsfsdfwe.png deleted file mode 100644 index 207ba84..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/dsfdsfsdfwe.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/dynamodb.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/dynamodb.png deleted file mode 100644 index 723be2a..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/dynamodb.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/em-spectrum.jpg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/em-spectrum.jpg deleted file mode 100644 index 46a2191..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/em-spectrum.jpg and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/em-wave.gif b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/em-wave.gif deleted file mode 100644 index 8faba2c..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/em-wave.gif and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/eniac.jpg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/eniac.jpg deleted file mode 100644 index 377e087..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/eniac.jpg and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/equiv-fractions.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/equiv-fractions.png deleted file mode 100644 index ddd0dbd..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/equiv-fractions.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/full-adder-new.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/full-adder-new.png deleted file mode 100644 index 8eb9df0..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/full-adder-new.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/gateway-services.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/gateway-services.png deleted file mode 100644 index cd11117..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/gateway-services.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/gateway-trigger.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/gateway-trigger.png deleted file mode 100644 index d43fe05..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/gateway-trigger.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/git-bisect.svg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/git-bisect.svg deleted file mode 100644 index 200a9c4..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/git-bisect.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - -
good
good
bad
bad
bisect
bisect
good
good
bisect
bisect
bad
bad
'bisect' above becomes 'good' below
'bisect' above become...
first stage
first stage
second
 stage
second...
Text is not SVG - cannot display
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/git-interactive-mode-2.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/git-interactive-mode-2.png deleted file mode 100644 index 7e69265..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/git-interactive-mode-2.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/git-interactive-rebase.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/git-interactive-rebase.png deleted file mode 100644 index 99ce73c..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/git-interactive-rebase.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/git-manual-hunk.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/git-manual-hunk.png deleted file mode 100644 index c3a8dbd..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/git-manual-hunk.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/git-patch-mode.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/git-patch-mode.png deleted file mode 100644 index 2b448ee..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/git-patch-mode.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/graphQL_request_load.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/graphQL_request_load.png deleted file mode 100644 index df97e79..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/graphQL_request_load.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/graphql-architecture.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/graphql-architecture.png deleted file mode 100644 index b56b208..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/graphql-architecture.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/graphql-journey-two.svg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/graphql-journey-two.svg deleted file mode 100644 index 949cd30..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/graphql-journey-two.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - -
CLIENT
CLIENT
SERVER
SERVER
convert query to string 
and send to
server as POST or
GET request
convert query to string...
Parse string and 
convert to an Abstract Syntax Tree
Parse string and...
Using the AST, validate the query against the types and fields of the GraphQL schema
Using the AST, validate...
Yes
Yes
No
No
Error?
Error?
field
field
resolver
resolver
Convert to JSON object
matching shape of client query
Convert to JSON object...
Assign object to `data` key in HTTP response body
Assign object to `data` key in HTTP...
Text is not SVG - cannot display
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/graphql_multiple_resources.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/graphql_multiple_resources.png deleted file mode 100644 index 3b526da..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/graphql_multiple_resources.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/greyscale-encoding.svg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/greyscale-encoding.svg deleted file mode 100644 index 4a72d8e..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/greyscale-encoding.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - -
Binary
Binary
Hex
Hex
Decimal
Decimal
0b00000000
0b00000000
0x00
0x00
0
0
0b01010101
0b01010101
0x55
0x55
85
85
0b10101010
0b10101010
0xAA
0xAA
170
170
0b11111111
0b11111111
0xFF
0xFF
255
255
Text is not SVG - cannot display
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/ground-symbol.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/ground-symbol.png deleted file mode 100644 index 7c7be5d..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/ground-symbol.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/grub.jpg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/grub.jpg deleted file mode 100644 index 58cb270..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/grub.jpg and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/half-adder-gates-three.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/half-adder-gates-three.png deleted file mode 100644 index 0469bc3..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/half-adder-gates-three.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/half-adder-new.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/half-adder-new.png deleted file mode 100644 index 45dc092..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/half-adder-new.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/harddisk.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/harddisk.png deleted file mode 100644 index 5f5ee0d..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/harddisk.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/hardware-abstraction-hierarchy.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/hardware-abstraction-hierarchy.png deleted file mode 100644 index 7251df8..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/hardware-abstraction-hierarchy.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/hardware-sim-basic.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/hardware-sim-basic.png deleted file mode 100644 index 52a0049..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/hardware-sim-basic.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/hd-sim-test.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/hd-sim-test.png deleted file mode 100644 index f6775dd..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/hd-sim-test.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/hertz_wave_freq.gif b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/hertz_wave_freq.gif deleted file mode 100644 index 0fd7c0f..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/hertz_wave_freq.gif and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/hexadecimal-to-bytes.svg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/hexadecimal-to-bytes.svg deleted file mode 100644 index 99cfb98..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/hexadecimal-to-bytes.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - -
8 A 5 2 F F 0 0
8 A 5 2 F F 0...
1000
1000
1010
1010
0101
0101
0010
0010
1111
1111
1111
1111
0000
0000
0000
0000
1 byte (8-bits)
1 byte (8-bits)
2 bytes (16-bits)
2 bytes (16-bits)
4 bytes (32-bits)
4 bytes (32-bits)
8
8
7
7
6
6
5
5
4
4
3
3
2
2
1
1
Text is not SVG - cannot display
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/htop.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/htop.png deleted file mode 100644 index a97cd4b..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/htop.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/hydraulic_computer.jpg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/hydraulic_computer.jpg deleted file mode 100644 index b84ada9..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/hydraulic_computer.jpg and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/ibm-1401.jpg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/ibm-1401.jpg deleted file mode 100644 index 43696c7..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/ibm-1401.jpg and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/ibm-360-in-use.jpeg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/ibm-360-in-use.jpeg deleted file mode 100644 index fc5a9ea..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/ibm-360-in-use.jpeg and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/ibm-360.jpg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/ibm-360.jpg deleted file mode 100644 index a12fd29..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/ibm-360.jpg and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/ibm-650-console-panel.jpg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/ibm-650-console-panel.jpg deleted file mode 100644 index ad55f62..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/ibm-650-console-panel.jpg and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/ibm-650.jpg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/ibm-650.jpg deleted file mode 100644 index 6bf83c7..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/ibm-650.jpg and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/ibm-701-control-unit.jpeg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/ibm-701-control-unit.jpeg deleted file mode 100644 index 1ed8ed4..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/ibm-701-control-unit.jpeg and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/ibm-add.jpeg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/ibm-add.jpeg deleted file mode 100644 index ab85377..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/ibm-add.jpeg and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/ibm-pc.jpg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/ibm-pc.jpg deleted file mode 100644 index 5fdd501..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/ibm-pc.jpg and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/incorrect_push_button.jpg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/incorrect_push_button.jpg deleted file mode 100644 index 1b2a25a..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/incorrect_push_button.jpg and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/integrated-circuit.jpeg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/integrated-circuit.jpeg deleted file mode 100644 index 71b6598..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/integrated-circuit.jpeg and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/intel-4004.jpg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/intel-4004.jpg deleted file mode 100644 index 583251a..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/intel-4004.jpg and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/internet-layer-packet-revised.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/internet-layer-packet-revised.png deleted file mode 100644 index d15a94a..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/internet-layer-packet-revised.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/internet-layer-packet.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/internet-layer-packet.png deleted file mode 100644 index 9c1534e..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/internet-layer-packet.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/ip-address-anatomy.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/ip-address-anatomy.png deleted file mode 100644 index 3466c04..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/ip-address-anatomy.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/javascript-recursion.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/javascript-recursion.png deleted file mode 100644 index b232421..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/javascript-recursion.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/jk-flip-flops.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/jk-flip-flops.png deleted file mode 100644 index f83dcdc..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/jk-flip-flops.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/journald.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/journald.png deleted file mode 100644 index 2781425..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/journald.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/kernel-cpu-interaction.svg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/kernel-cpu-interaction.svg deleted file mode 100644 index 0706e8c..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/kernel-cpu-interaction.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - -
Locate kernel (OS)
Locate kernel (OS)

Disk
Disk
Load kernel 
Load kernel 
Boot
Boot
Memory
Memory
Kernel
Kernel
Relay instructions
Relay instructions
CPU
CPU
USER SPACE
USER SPACE
Toggle
control
Toggle...
Fetch,
decode,
execute
Fetch,...
Shutdown
Shutdown
Shell
Shell
GUI
GUI
Schematic of role and lifecycle of the kernel
relative to the processor
and user space 
Schematic of role and lifecycle of the kernel...
 same entity/ location
same entity/ loc...
interaction between different entities
interaction between different enti...
CPU and kernel presented as logically distinct althought kernel is a running CPU process
CPU and kernel presente...
Text is not SVG - cannot display
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/knowledge_graph.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/knowledge_graph.png deleted file mode 100644 index 69ce70d..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/knowledge_graph.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/lambda-cloudwatch.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/lambda-cloudwatch.png deleted file mode 100644 index 4bf29ff..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/lambda-cloudwatch.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/lambda-func-three.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/lambda-func-three.png deleted file mode 100644 index a6fb7ea..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/lambda-func-three.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/lambda-func-two.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/lambda-func-two.png deleted file mode 100644 index d57af7f..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/lambda-func-two.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/lambda-overview.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/lambda-overview.png deleted file mode 100644 index 8a522ca..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/lambda-overview.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/lambda_func_one.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/lambda_func_one.png deleted file mode 100644 index 11353a7..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/lambda_func_one.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/leibniz-stepped-drum.jpg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/leibniz-stepped-drum.jpg deleted file mode 100644 index 492f346..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/leibniz-stepped-drum.jpg and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/lin.svg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/lin.svg deleted file mode 100644 index f207dd0..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/lin.svg +++ /dev/null @@ -1 +0,0 @@ -01234567RUNTIMEn \ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/link-layer-frame-revised.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/link-layer-frame-revised.png deleted file mode 100644 index cc00971..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/link-layer-frame-revised.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/link-layer-frame.drawio.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/link-layer-frame.drawio.png deleted file mode 100644 index cdbbddb..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/link-layer-frame.drawio.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/link-layer-internet-diagram.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/link-layer-internet-diagram.png deleted file mode 100644 index f9f918a..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/link-layer-internet-diagram.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/local-sam-docker.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/local-sam-docker.png deleted file mode 100644 index 9f964fa..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/local-sam-docker.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/logical-equivalence-tree.svg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/logical-equivalence-tree.svg deleted file mode 100644 index bb78612..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/logical-equivalence-tree.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - -
P ⊃ Q
P ⊃ Q
5
5
~P v Q
~P v Q
SM
SM
1
1
1 ~D
1 ~≡D
4
4
2
2
(P Q)  (~P v Q)
(P ⊃ Q)  ≡ (~P v Q)
3
3
P
P
4
4
7
7
3~⊃D
3~⊃D
~(P ⊃ Q)
~(P ⊃ Q)
~(~P v ~Q)
~(~P v ~Q)
6
6
1 ~D
1 ~≡D
~Q
~Q
3~⊃D
3~⊃D
P
P
~Q
~Q
5
5
~~P
~~P
~Q
~Q
P
P
~P
~P
Q
Q
9
9
8
8
8
8
9
9
10
10
2~⊃D
2~⊃D
3vD
3vD
2~vD
2~vD
2~vD
2~vD
7~~vD
7~~vD
Viewer does not support full SVG 1.1
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/logical-falsity-tree.svg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/logical-falsity-tree.svg deleted file mode 100644 index 4e0c22c..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/logical-falsity-tree.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - -
~P
~P
~Q
~Q
SM
SM
1
1
2&D
2&D
4
4
P & Q
P & Q
1&D
1&D
2
2
(P & Q) & ~(P & Q)
(P & Q) & ~(P & Q)
~(P & Q)
~(P & Q)
1&D
1&D
3
3
P
P
4
4
3&~D
3&~D
2&D
2&D
5
5
Q
Q
5
5
Viewer does not support full SVG 1.1
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/lsof.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/lsof.png deleted file mode 100644 index 8a8b5d5..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/lsof.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/magnetic-core-closeup.jpg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/magnetic-core-closeup.jpg deleted file mode 100644 index 8ca2077..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/magnetic-core-closeup.jpg and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/magnetic-core-memory.jpg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/magnetic-core-memory.jpg deleted file mode 100644 index de9e18d..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/magnetic-core-memory.jpg and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/magnetic-drum-memory.jpg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/magnetic-drum-memory.jpg deleted file mode 100644 index dbc9517..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/magnetic-drum-memory.jpg and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/magnetic-tape-disk.jpeg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/magnetic-tape-disk.jpeg deleted file mode 100644 index 072cd0e..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/magnetic-tape-disk.jpeg and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/magnetic-tape-ibm.jpeg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/magnetic-tape-ibm.jpeg deleted file mode 100644 index 7051ac4..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/magnetic-tape-ibm.jpeg and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/magnetic_field.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/magnetic_field.png deleted file mode 100644 index e82e190..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/magnetic_field.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/manchester_baby.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/manchester_baby.png deleted file mode 100644 index 01efc9e..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/manchester_baby.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/memory-flow.svg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/memory-flow.svg deleted file mode 100644 index ab78d87..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/memory-flow.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - -
CPU
CPU
L1 
CACHE
L1...
L2 CACHE
L2 CACHE
ADDRESS BUS
ADDRESS BUS
DATA BUS
DATA BUS
DRAM
DRAM
Text is not SVG - cannot display
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/mongo-collection.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/mongo-collection.png deleted file mode 100644 index 227ae90..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/mongo-collection.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/mongo-compass.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/mongo-compass.png deleted file mode 100644 index 8ecbab2..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/mongo-compass.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/mongo-db-structure.svg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/mongo-db-structure.svg deleted file mode 100644 index 6b1e2fb..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/mongo-db-structure.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - -
Collection
Collection
Database
Database
Collection
Collection
Document
Document
Document
Document
Document
Document
Document
Document

Mongo database structure

Mongo database structure
Text is not SVG - cannot display
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/mongo-doc-added.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/mongo-doc-added.png deleted file mode 100644 index a45847f..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/mongo-doc-added.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/mongoose-hierarchy.svg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/mongoose-hierarchy.svg deleted file mode 100644 index 15091f1..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/mongoose-hierarchy.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - -
Schema
Schema
Model 
Model 
Object instance
Object instance
Schema
const personSchema = new
   mongoose.Schema({
name: String,
age: Number
   })
const personSchema = new...
Model
const Person = mongoose.model
("Person", personSchema)
const Person = mongoose.model...
Object


const thomas = new Person({
   name: 'Thomas Bishop',
   age: 34
})
const thomas = new Person({...

Mongoose data hierarchy

Mongoose data hierarchy
Text is not SVG - cannot display
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/motherboard-pi.jpg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/motherboard-pi.jpg deleted file mode 100644 index 07c8c91..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/motherboard-pi.jpg and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/mount-directory.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/mount-directory.png deleted file mode 100644 index c522d2d..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/mount-directory.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/multi_on_off.gif b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/multi_on_off.gif deleted file mode 100644 index f7c90ea..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/multi_on_off.gif and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/multiple_circuits.gif b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/multiple_circuits.gif deleted file mode 100644 index c298651..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/multiple_circuits.gif and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/nand-gate-new.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/nand-gate-new.png deleted file mode 100644 index ca27c16..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/nand-gate-new.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/nand-mem-demonstrated.gif b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/nand-mem-demonstrated.gif deleted file mode 100644 index c8af9a7..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/nand-mem-demonstrated.gif and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/nand-mem-first.gif b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/nand-mem-first.gif deleted file mode 100644 index 927aa81..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/nand-mem-first.gif and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/nand-mem-second.gif b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/nand-mem-second.gif deleted file mode 100644 index 035f4e6..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/nand-mem-second.gif and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/nand_latch_logic_circuit.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/nand_latch_logic_circuit.png deleted file mode 100644 index 631f722..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/nand_latch_logic_circuit.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/negate-elim.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/negate-elim.png deleted file mode 100644 index 043992c..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/negate-elim.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/negate-intro.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/negate-intro.png deleted file mode 100644 index 0c2e920..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/negate-intro.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/negated-biconditional-decomposition-rule.drawio.svg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/negated-biconditional-decomposition-rule.drawio.svg deleted file mode 100644 index 38228e9..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/negated-biconditional-decomposition-rule.drawio.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - -
P
P
Q
Q
~(P ≡ Q)
~(P ≡ Q)
1
1
2
2
SM
SM
~1≡D
~1≡D
~P
~P
~Q
~Q
3
3
~1≡D
~1≡D
Viewer does not support full SVG 1.1
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/negated-conditional-decomposition-rule.svg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/negated-conditional-decomposition-rule.svg deleted file mode 100644 index bc8e052..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/negated-conditional-decomposition-rule.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - -
~(P  Q)
~(P ⊃ Q)
1
1
2
2
3
3
~Q
~Q
SM
SM
1~D
1~⊃D
1~D
1~⊃D
Viewer does not support full SVG 1.1
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/negated-conjunction-decomposition-rule.svg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/negated-conjunction-decomposition-rule.svg deleted file mode 100644 index 0a7a24c..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/negated-conjunction-decomposition-rule.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - -
~P
~P
~Q
~Q
~(P & Q)
~(P & Q)
1
1
2
2
SM
SM
~&D
~&D
Viewer does not support full SVG 1.1
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/negated-disjunction-decomposition-rule.svg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/negated-disjunction-decomposition-rule.svg deleted file mode 100644 index 21b10e1..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/negated-disjunction-decomposition-rule.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - -
~(P v Q)
~(P v Q)
1
1
2
2
3
3
~P 
~P 
~Q
~Q
SM
SM
1&~vD
1&~vD
1~vD
1~vD
Viewer does not support full SVG 1.1
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/network-request-layers.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/network-request-layers.png deleted file mode 100644 index 245877e..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/network-request-layers.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/node-event-loop.svg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/node-event-loop.svg deleted file mode 100644 index a87e2d3..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/node-event-loop.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - -
index.js
index.js
call stack
call stack
Timers
Timers
I/O callbacks
I/O callbacks
Close events
Close events
I/O polling
I/O polling
setImmediate
callbacks
setImmediate...
Idle, preparation
Idle, preparation
PROCESS
PROCESS
THREAD
THREAD
TICK
TICK
Text is not SVG - cannot display
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/nor-gate-new.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/nor-gate-new.png deleted file mode 100644 index d97578f..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/nor-gate-new.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/normal-merge-again.svg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/normal-merge-again.svg deleted file mode 100644 index 273eeb4..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/normal-merge-again.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - -
A
A
B
B
Text is not SVG - cannot display
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/one-eighth-a.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/one-eighth-a.png deleted file mode 100644 index a39820d..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/one-eighth-a.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/opensearch-architecture.drawio.svg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/opensearch-architecture.drawio.svg deleted file mode 100644 index 7696016..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/opensearch-architecture.drawio.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - -
cluster
cluster
node
node
node
node
node
node
cluster
cluster
node
node
node
node
node
node
domain
domain
Text is not SVG - cannot display
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/or-gate-new.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/or-gate-new.png deleted file mode 100644 index 2d97429..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/or-gate-new.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/or-transistor.svg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/or-transistor.svg deleted file mode 100644 index b691723..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/or-transistor.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - -
V-A
V-A
V-B
V-B
V-out
V-out
V-cc
V-cc
Trans
Trans
Trans
Trans
Text is not SVG - cannot display
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/parallel-battery-diagram.svg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/parallel-battery-diagram.svg deleted file mode 100644 index e8df3d3..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/parallel-battery-diagram.svg +++ /dev/null @@ -1,689 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - 1.5 V - + - - - - - - - - 1.5 V - 1.5 V - - - - - - - - - - - - - - 1.5 V - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - + - + - - - - diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/parallel-transmission.jpg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/parallel-transmission.jpg deleted file mode 100644 index e7f69b1..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/parallel-transmission.jpg and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/pascaline.jpg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/pascaline.jpg deleted file mode 100644 index 455f4ab..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/pascaline.jpg and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/pilot-ace.jpg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/pilot-ace.jpg deleted file mode 100644 index 2bc975b..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/pilot-ace.jpg and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/postman-aws-output.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/postman-aws-output.png deleted file mode 100644 index 7ce61fb..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/postman-aws-output.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/postman-lambda.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/postman-lambda.png deleted file mode 100644 index 5afc07e..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/postman-lambda.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/programming_a_digital_electronic_computter.jpg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/programming_a_digital_electronic_computter.jpg deleted file mode 100644 index f25ec94..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/programming_a_digital_electronic_computter.jpg and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/proof.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/proof.png deleted file mode 100644 index bf3831f..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/proof.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/proofs-drawio-Page-5.drawio.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/proofs-drawio-Page-5.drawio.png deleted file mode 100644 index 8f59d18..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/proofs-drawio-Page-5.drawio.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/proofs-drawio-Page-5.drawio_2.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/proofs-drawio-Page-5.drawio_2.png deleted file mode 100644 index b83b8a9..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/proofs-drawio-Page-5.drawio_2.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/proofs-drawio-Page-6.drawio.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/proofs-drawio-Page-6.drawio.png deleted file mode 100644 index ba492af..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/proofs-drawio-Page-6.drawio.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/ps-tree.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/ps-tree.png deleted file mode 100644 index fb7d7f2..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/ps-tree.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/push-button-legs.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/push-button-legs.png deleted file mode 100644 index a4be0cf..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/push-button-legs.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/python-exception-hierarchy.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/python-exception-hierarchy.png deleted file mode 100644 index 085758a..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/python-exception-hierarchy.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/queue.svg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/queue.svg deleted file mode 100644 index d6720d7..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/queue.svg +++ /dev/null @@ -1,20 +0,0 @@ - - - Artboard - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/react-lifecycle.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/react-lifecycle.png deleted file mode 100644 index eee57bd..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/react-lifecycle.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/rebase-tip-chage.svg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/rebase-tip-chage.svg deleted file mode 100644 index 94769c3..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/rebase-tip-chage.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/red-encoding.svg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/red-encoding.svg deleted file mode 100644 index f9b5752..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/red-encoding.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - -
11111111
11111111
00000000
00000000
00000000
00000000
Red
Red
Blue
Blue
Green
Green
=
=
0xFF0000
0xFF0000
Text is not SVG - cannot display
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/reiteration.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/reiteration.png deleted file mode 100644 index 6aee327..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/reiteration.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/relay.gif b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/relay.gif deleted file mode 100644 index 907016f..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/relay.gif and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/s3-package-again.svg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/s3-package-again.svg deleted file mode 100644 index 61aa822..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/s3-package-again.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - -
Create sam.yml
Create sam.yml
Upload zipped artefacts to S3
Upload zipped artefa...
Create CloudFormation template with address of artefacts
Create CloudFormation template...
Text is not SVG - cannot display
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/sam-build.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/sam-build.png deleted file mode 100644 index 18fea88..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/sam-build.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/sam-directory.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/sam-directory.png deleted file mode 100644 index 182ee2b..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/sam-directory.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/sam-template-yaml.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/sam-template-yaml.png deleted file mode 100644 index c394ea5..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/sam-template-yaml.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/serial-transmission.jpg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/serial-transmission.jpg deleted file mode 100644 index efd2c19..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/serial-transmission.jpg and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/series-battcircuit.svg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/series-battcircuit.svg deleted file mode 100644 index de63e18..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/series-battcircuit.svg +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - - - +1.5V - - - - - +1.5V - - - - - +1.5V - - - - - - - +4.5V - - \ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/series-battery-diagram.svg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/series-battery-diagram.svg deleted file mode 100644 index 838766a..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/series-battery-diagram.svg +++ /dev/null @@ -1,245 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - 1.5 V - 4.5 V - - - - - 1.5 V - - - - - 1.5 V - - - - - - - diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/server-listening.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/server-listening.png deleted file mode 100644 index eb38b2d..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/server-listening.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/signed-to-unsigned.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/signed-to-unsigned.png deleted file mode 100644 index ac7ba0a..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/signed-to-unsigned.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/single-git-history-rebase.svg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/single-git-history-rebase.svg deleted file mode 100644 index eadbe25..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/single-git-history-rebase.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/sql-full-outer-join.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/sql-full-outer-join.png deleted file mode 100644 index 9f44f41..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/sql-full-outer-join.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/sql-inner-join.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/sql-inner-join.png deleted file mode 100644 index b71eb33..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/sql-inner-join.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/sql-left-outer-join.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/sql-left-outer-join.png deleted file mode 100644 index e27388b..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/sql-left-outer-join.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/sql-right-outer-join.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/sql-right-outer-join.png deleted file mode 100644 index 2115475..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/sql-right-outer-join.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/square.svg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/square.svg deleted file mode 100644 index b305e27..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/square.svg +++ /dev/null @@ -1 +0,0 @@ -0100200300400500600700051015202530RUNTIMEn \ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/sr_latch_diagram.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/sr_latch_diagram.png deleted file mode 100644 index 41c51f6..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/sr_latch_diagram.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/sr_latch_logic_circuit.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/sr_latch_logic_circuit.png deleted file mode 100644 index f3a2702..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/sr_latch_logic_circuit.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/stack1.svg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/stack1.svg deleted file mode 100644 index 897bf39..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/stack1.svg +++ /dev/null @@ -1,17 +0,0 @@ - - - Artboard - - - - - - - - - - - - - - \ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/stack2.svg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/stack2.svg deleted file mode 100644 index f2d1752..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/stack2.svg +++ /dev/null @@ -1,17 +0,0 @@ - - - Artboard - - - - - - - - - - - - - - \ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/standard-userspace.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/standard-userspace.png deleted file mode 100644 index 3d8ff3a..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/standard-userspace.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/state-machine-definition.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/state-machine-definition.png deleted file mode 100644 index 19c39bd..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/state-machine-definition.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/state-machine-execution.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/state-machine-execution.png deleted file mode 100644 index be95d42..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/state-machine-execution.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/step1.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/step1.png deleted file mode 100644 index e9dee56..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/step1.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/step2.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/step2.png deleted file mode 100644 index 674fc62..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/step2.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/step3.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/step3.png deleted file mode 100644 index 7331da7..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/step3.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/step4.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/step4.png deleted file mode 100644 index 12a57b9..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/step4.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/stibitz-teletype.jpg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/stibitz-teletype.jpg deleted file mode 100644 index c22e1e4..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/stibitz-teletype.jpg and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/switch-and-gate.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/switch-and-gate.png deleted file mode 100644 index aae726a..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/switch-and-gate.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/switch-or-gate.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/switch-or-gate.png deleted file mode 100644 index d621991..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/switch-or-gate.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/sync-thread.svg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/sync-thread.svg deleted file mode 100644 index f3a6eb0..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/sync-thread.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - -
synchronous, single thread of control
synchronous, single thread of control
synchronous, 2+ threads of control
synchronous, 2+ threads of control
Text is not SVG - cannot display
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/systemd-global-files.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/systemd-global-files.png deleted file mode 100644 index 700600b..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/systemd-global-files.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/systemd-local-files.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/systemd-local-files.png deleted file mode 100644 index b443998..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/systemd-local-files.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/t-flip-flops.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/t-flip-flops.png deleted file mode 100644 index 208deea..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/t-flip-flops.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/terminal_colours.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/terminal_colours.png deleted file mode 100644 index 801f439..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/terminal_colours.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/theoremproof.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/theoremproof.png deleted file mode 100644 index 6c4b549..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/theoremproof.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/transistor-off.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/transistor-off.png deleted file mode 100644 index 0d24182..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/transistor-off.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/transistor-on.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/transistor-on.png deleted file mode 100644 index 4cc1441..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/transistor-on.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/transport-layer-segment.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/transport-layer-segment.png deleted file mode 100644 index c2ecdcf..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/transport-layer-segment.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/trigger-info.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/trigger-info.png deleted file mode 100644 index b478497..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/trigger-info.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/univac-1.jpg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/univac-1.jpg deleted file mode 100644 index bc986c9..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/univac-1.jpg and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/univac-operator-console.jpeg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/univac-operator-console.jpeg deleted file mode 100644 index 6eec154..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/univac-operator-console.jpeg and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/unsigned-to-signed.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/unsigned-to-signed.png deleted file mode 100644 index 0168aed..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/unsigned-to-signed.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/valence-shell.svg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/valence-shell.svg deleted file mode 100644 index f086c05..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/valence-shell.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - -
K
K
L
L
M
M
N
N
O
O
P
P
Q
Q
2
2
12
12
18
18
32
32
18
18
8
8
2
2
Valence shell
Valence shell
Designation
Designation
Max electrons
Max electrons
Text is not SVG - cannot display
\ No newline at end of file diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/vertical-circuit.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/vertical-circuit.png deleted file mode 100644 index 940bbb5..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/vertical-circuit.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/virtual-memory-diagram.jpg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/virtual-memory-diagram.jpg deleted file mode 100644 index b65f527..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/virtual-memory-diagram.jpg and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/voltage-drop.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/voltage-drop.png deleted file mode 100644 index c7f1bad..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/voltage-drop.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/von_neumann_architecture.jpeg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/von_neumann_architecture.jpeg deleted file mode 100644 index 3d168a4..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/von_neumann_architecture.jpeg and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/whirlwind-magnetic-cores.JPG b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/whirlwind-magnetic-cores.JPG deleted file mode 100644 index 48692ba..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/whirlwind-magnetic-cores.JPG and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/williams-tube-dots.jpg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/williams-tube-dots.jpg deleted file mode 100644 index 51acac6..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/williams-tube-dots.jpg and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/williams-tube.jpg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/williams-tube.jpg deleted file mode 100644 index 6738480..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/williams-tube.jpg and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/xor-addition-four.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/xor-addition-four.png deleted file mode 100644 index ea5ae5b..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/xor-addition-four.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/xor-gate-new.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/xor-gate-new.png deleted file mode 100644 index 9961f48..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/xor-gate-new.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/xor-hdl.png b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/xor-hdl.png deleted file mode 100644 index 56dba50..0000000 Binary files a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/xor-hdl.png and /dev/null differ diff --git a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/yellow-encoding.svg b/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/yellow-encoding.svg deleted file mode 100644 index 3a12161..0000000 --- a/neuron/d0ed26d0-cdc8-4643-8c09-445408195f9b/static/yellow-encoding.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - -
11111111
11111111
11111111
11111111
00000000
00000000
Red
Red
Blue
Blue
Green
Green
=
=
0xFFFF00
0xFFFF00
Text is not SVG - cannot display
\ No newline at end of file diff --git a/zk/1726814727_LUWV.md b/zk/1726814727_LUWV.md deleted file mode 100644 index 88527f3..0000000 --- a/zk/1726814727_LUWV.md +++ /dev/null @@ -1 +0,0 @@ -# Turing Mach diff --git a/zk/1_GET.md b/zk/Creating_a_RESTful_API_GET.md similarity index 100% rename from zk/1_GET.md rename to zk/Creating_a_RESTful_API_GET.md diff --git a/zk/5__Integrating_the_Mongo_database.md b/zk/Creating_a_RESTful_API_Integrating_the_Database.md similarity index 100% rename from zk/5__Integrating_the_Mongo_database.md rename to zk/Creating_a_RESTful_API_Integrating_the_Database.md diff --git a/zk/0_Introduction.md b/zk/Creating_a_RESTful_API_Introduction.md similarity index 100% rename from zk/0_Introduction.md rename to zk/Creating_a_RESTful_API_Introduction.md diff --git a/zk/2_POST.md b/zk/Creating_a_RESTful_API_POST.md similarity index 100% rename from zk/2_POST.md rename to zk/Creating_a_RESTful_API_POST.md diff --git a/zk/3_PUT.md b/zk/Creating_a_RESTful_API_PUT.md similarity index 100% rename from zk/3_PUT.md rename to zk/Creating_a_RESTful_API_PUT.md