diff --git a/SUMMARY.md b/SUMMARY.md index c81780ac3..a498a9838 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -1,33 +1,21 @@ # Summary * [Algorithm Archive](README.md) -* [TODO](TODO.md) * [Introduction](chapters/introduction/introduction.md) -* [A Personal Note](chapters/introduction/my_introduction_to_hobby_programming.md) * [How To Contribute](chapters/introduction/how_to_contribute.md) -* [Principles of Code](chapters/principles_of_code/principles_of_code.md) - * [Choosing A Language](chapters/principles_of_code/choosing_a_language/choosing_a_language.md) - * [Compiled Languages](chapters/principles_of_code/choosing_a_language/compiled/compiled.md) - * [Makefiles](chapters/principles_of_code/choosing_a_language/compiled/makefiles.md) - * [FORTRAN](chapters/principles_of_code/choosing_a_language/compiled/FORTRAN.md) - * [Building Blocks](chapters/principles_of_code/building_blocks/building_blocks.md) - * [Variables and Types](chapters/principles_of_code/building_blocks/variables.md) - * [Conditions](chapters/principles_of_code/building_blocks/conditions.md) - * [Loops](chapters/principles_of_code/building_blocks/loops.md) - * [Functions](chapters/principles_of_code/building_blocks/functions.md) - * [Classes](chapters/principles_of_code/building_blocks/classes.md) - * [Stacks and Queues](chapters/principles_of_code/building_blocks/stacks.md) - * [Bit Logic](chapters/principles_of_code/building_blocks/bitlogic.md) - * [Version Control](chapters/principles_of_code/version_control.md) - * [Complexity Notation](chapters/principles_of_code/notation/notation.md) -* [Convolutions](chapters/algorithms/convolutions/convolutions.md) -* [Taylor Series](chapters/general/taylor_series_expansion/taylor_series_expansion.md) +* [Version Control](chapters/introduction/version_control.md) +* [Data Structures](chapters/data_structures/data_structures.md) + * [Stacks and Queues](chapters/data_structures/stacks_and_queues/stacks_and_queues.md) +* [Mathematical Background](chapters/general/mathematical_background/mathematical_background.md) + * [Complexity Notation](chapters/general/notation/notation.md) + * [Bit Logic](chapters/general/bitlogic/bitlogic.md) + * [Convolutions](chapters/algorithms/convolutions/convolutions.md) + * [Taylor Series](chapters/general/taylor_series_expansion/taylor_series_expansion.md) * [Sorting and Searching](chapters/general/sorting_and_searching/sorting_and_searching.md) * [Bubble Sort](chapters/algorithms/bubble_sort/bubble_sort.md) * [Bogo Sort](chapters/algorithms/bogo_sort/bogo_sort.md) * [Tree Traversal](chapters/algorithms/tree_traversal/tree_traversal.md) * [Euclidean Algorithm](chapters/algorithms/euclidean_algorithm/euclidean_algorithm.md) -* [Multiplication](chapters/general/multiplication/multiplication.md) * [Monte Carlo](chapters/algorithms/monte_carlo_integration/monte_carlo_integration.md) * [Matrix Methods](chapters/general/matrix_methods/matrix_methods.md) * [Gaussian Elimination](chapters/algorithms/gaussian_elimination/gaussian_elimination.md) @@ -36,16 +24,13 @@ * [Gift Wrapping](chapters/general/gift_wrapping/gift_wrapping.md) * [Jarvis March](chapters/algorithms/jarvis_march/jarvis_march.md) * [Graham Scan](chapters/algorithms/graham_scan/graham_scan.md) - * [Chan's Algorithm](chapters/algorithms/chans_algorithm/chans_algorithm.md) * [FFT](chapters/algorithms/cooley_tukey/cooley_tukey.md) * [Decision Problems](chapters/general/decision_problems/decision_problems.md) * [Stable Marriage Problem](chapters/algorithms/stable_marriage_problem/stable_marriage_problem.md) * [Differential Equation Solvers](chapters/general/differential_equations/differential_equations.md) * [Forward Euler Method](chapters/algorithms/forward_euler_method/forward_euler_method.md) - * [Backward Euler Methods](chapters/algorithms/backward_euler_method/backward_euler_method.md) * [Physics Solvers](chapters/general/physics_solvers/physics_solvers.md) * [Verlet Integration](chapters/algorithms/verlet_integration/verlet_integration.md) - * [Barnes-Hut](chapters/algorithms/barnes_hut_algorithm/barnes_hut_algorithm.md) * [Quantum Systems](chapters/general/quantum_systems/quantum_systems.md) * [Split-Operator Method](chapters/algorithms/split-operator_method/split-operator_method.md) * [Data Compression](chapters/general/data_compression/data_compression.md) diff --git a/TODO.md b/TODO.md deleted file mode 100644 index 9d19c7a50..000000000 --- a/TODO.md +++ /dev/null @@ -1,29 +0,0 @@ -# TO DO - -The Algorithm Archive is currently being written and is quite small at the moment. -This is a list of all the things we need to get done ASAP. -That said, because of my (real-world) work schedule and such, ASAP is not as fast as I'd like, but that's how it goes. -I apologize for taking so long with each chapter, but I figure making this list public is a good step towards being as open as possible. - -## For James (Leios) - -Write: - -* Algorithms already covered (Chan's, Monte Carlo) -* Language choices (Makefiles, Fortran, Julia...). Note that I kinda wanted to turn this into a series of sorts where I review each language with a series of standard tests. - -Revise: - -* Mathematical Background -- Transform into "mathematical methods." - -I'll try to keep this list updated as I write more sections - -## Points of Discussion - -Here are points of discussion that need to be had about the Algorithm Archive before it gets too big and becomes too difficult to revise everything - -* **Should community-submitted code be clean or efficient?** When it comes to writing code, I often feel readability is the most important factor to keep in mind; however, with the code submitted to this archive, there will be pseudocode available to guide new folks through the process of writing the algorithm for the first time. For this reason, it might be best for the community to submit the most efficient code they can write in their own languages, commenting in any tricks to improve performance. -* **Is the current method of writing optimal?** When I originally envisioned this project, I thought that I would do all the writing and the community would do (most of) the coding. That said, I am becoming more open to the idea of letting community members write for the Archive. The advantage to this is obvious: The book gets written faster. The disadvantage is also obvious: We lose focus and consistency throughout the book. -* **We need a Logo.** I have no idea how to go about this. Maybe a logo contest at 16384 subscribers on youtube? The project will be large enough at that point to warrant a good logo. I really want something simple, though, like a [Trefoil Knot](https://en.wikipedia.org/wiki/Trefoil_knot#/media/File:Trefoil_knot_left.svg) or something. It kinda looks like 3 A's if you look at it the right way, and we'll definitely cover knot algorithms at some point because they are fascinating! - -Anyway, let me know what you think. I love the community we have here and appreciate all the conversations we've had so far! diff --git a/chapters/algorithms/backward_euler_method/backward_euler_method.md b/chapters/algorithms/backward_euler_method/backward_euler_method.md index 50cd34a96..20ffbb0ae 100644 --- a/chapters/algorithms/backward_euler_method/backward_euler_method.md +++ b/chapters/algorithms/backward_euler_method/backward_euler_method.md @@ -1,4 +1,4 @@ -### Backward Euler Method +# Backward Euler Method Unlike the forward Euler Method above, the backward Euler Method is an *implicit method*, which means that it results in a system of equations to solve. Luckily, we know how to solve systems of equations (*hint*: [Thomas Algorithm](../thomas_algorithm/thomas_algorithm.md), [Gaussian Elimination](../gaussian_elimination/gaussian_elimination.md)) diff --git a/chapters/algorithms/forward_euler_method/forward_euler_method.md b/chapters/algorithms/forward_euler_method/forward_euler_method.md index e16515e18..c34a20ee2 100644 --- a/chapters/algorithms/forward_euler_method/forward_euler_method.md +++ b/chapters/algorithms/forward_euler_method/forward_euler_method.md @@ -1,7 +1,7 @@ # The Forward Euler Method The Euler methods are some of the simplest methods to solve ordinary differential equations numerically. -They introduce a new set of methods called the [Runge Kutta](../runge_kutta_methods/runge_kutta_methods.md) methods, which will be discussed in the near future! +They introduce a new set of methods called the Runge Kutta methods, which will be discussed in the near future! As a physicist, I tend to understand things through methods that I have learned before. In this case, it makes sense for me to see Euler methods as extensions of the [Taylor Series Expansion](../general/taylor_series_expansion/taylor_series_expansion.md). @@ -48,7 +48,7 @@ $$ $$ Now, solving this set of equations in this way is known as the *forward* Euler Method. -In fact, there is another method known as the [*backward* Euler Method](../backward_euler_method/backward_euler_method.md), which we will get to soon enough. +In fact, there is another method known as the *backward* Euler Method, which we will get to soon enough. For now, it is important to note that the error of these methods depend on the timestep chosen.

diff --git a/chapters/algorithms/verlet_integration/verlet_integration.md b/chapters/algorithms/verlet_integration/verlet_integration.md index 358c1c878..a2f041e8f 100644 --- a/chapters/algorithms/verlet_integration/verlet_integration.md +++ b/chapters/algorithms/verlet_integration/verlet_integration.md @@ -162,7 +162,7 @@ Unfortunately, this has not yet been implemented in LabVIEW, so here's Julia cod {% endmethod %} -Even though this method is more used than the simple Verlet method mentioned above, it unforunately has an error term of $$\mathcal{O} \Delta t^2$$, which is two orders of magnitude worse. That said, if you want to have a simulaton with many objects that depend on one another --- like a gravity simulation --- the Velocity Verlet algorithm is a handy choice; however, you may have to play further tricks to allow everything to scale appropriately. These types of simulatons are sometimes called *n-body* simulations and one such trick is the [Barnes-Hut](../barnes_hut_algorithm/barnes_hut_algorithm.md) algorithm, which cuts the complexity of n-body simulations from $$\sim \mathcal{O}(n^2)$$ to $$\sim \mathcal{O}(n\log(n))$$ +Even though this method is more used than the simple Verlet method mentioned above, it unforunately has an error term of $$\mathcal{O} \Delta t^2$$, which is two orders of magnitude worse. That said, if you want to have a simulaton with many objects that depend on one another --- like a gravity simulation --- the Velocity Verlet algorithm is a handy choice; however, you may have to play further tricks to allow everything to scale appropriately. These types of simulatons are sometimes called *n-body* simulations and one such trick is the Barnes-Hut algorithm, which cuts the complexity of n-body simulations from $$\sim \mathcal{O}(n^2)$$ to $$\sim \mathcal{O}(n\log(n))$$ ## Example Code diff --git a/chapters/data_structures/data_structures.md b/chapters/data_structures/data_structures.md new file mode 100644 index 000000000..2ec5efbe3 --- /dev/null +++ b/chapters/data_structures/data_structures.md @@ -0,0 +1,4 @@ +# Data Structures + +This is a book about algorithms. +The fundamental building blocks of algorithms are data structures, and thus as more algorithms are added to the Archive, more data structures will be added to this section. diff --git a/chapters/principles_of_code/building_blocks/stacks.md b/chapters/data_structures/stacks_and_queues/stacks_and_queues.md similarity index 100% rename from chapters/principles_of_code/building_blocks/stacks.md rename to chapters/data_structures/stacks_and_queues/stacks_and_queues.md diff --git a/chapters/principles_of_code/building_blocks/bitlogic.md b/chapters/general/bitlogic/bitlogic.md similarity index 99% rename from chapters/principles_of_code/building_blocks/bitlogic.md rename to chapters/general/bitlogic/bitlogic.md index 077356490..32898cd11 100644 --- a/chapters/principles_of_code/building_blocks/bitlogic.md +++ b/chapters/general/bitlogic/bitlogic.md @@ -1,10 +1,10 @@ -### Bit Logic +# Bit Logic We write code in a language that makes a little sense to us, but does not make sense at all to our computer without a compiler to transform the code we write into a language the computer can understand. In the end, whenever we write code, all of the data structures we write are transformed into binary strings of 1's and 0's to be interpreted by our computer. That said, it's not always obvious how this happens, so let's start the simple case of integer numbers. -#### Integers +## Integers For integer numbers, 0 is still 0 and 1 is still 1; however, for 2, we need to use 2 digits because binary only has 0's and 1's. When we get to 4, we'll need 3 digits and when we get to 8, we'll need 4. Ever time we cross a power of 2, we'll need to add a new digit. Here's a table of the first 10 integers in binary: | Integer Number | Binary Number | @@ -45,7 +45,7 @@ Another method is to "roll over" to negative numbers when the bit count gets too Ultimately, integer numbers are not that difficult to deal with in binary, so let's move onto something more complicated: *floating-point numbers!* -#### Floating-point Numbers +## Floating-point Numbers Floats are numbers with a decimal point. 9.125 is a float. 9.000 is a float. 9 is an integer. Here are a few floats and their integer representations: diff --git a/chapters/principles_of_code/building_blocks/res/and.jpg b/chapters/general/bitlogic/res/and.jpg similarity index 100% rename from chapters/principles_of_code/building_blocks/res/and.jpg rename to chapters/general/bitlogic/res/and.jpg diff --git a/chapters/principles_of_code/building_blocks/res/nand.jpg b/chapters/general/bitlogic/res/nand.jpg similarity index 100% rename from chapters/principles_of_code/building_blocks/res/nand.jpg rename to chapters/general/bitlogic/res/nand.jpg diff --git a/chapters/principles_of_code/building_blocks/res/nor.jpg b/chapters/general/bitlogic/res/nor.jpg similarity index 100% rename from chapters/principles_of_code/building_blocks/res/nor.jpg rename to chapters/general/bitlogic/res/nor.jpg diff --git a/chapters/principles_of_code/building_blocks/res/not.jpg b/chapters/general/bitlogic/res/not.jpg similarity index 100% rename from chapters/principles_of_code/building_blocks/res/not.jpg rename to chapters/general/bitlogic/res/not.jpg diff --git a/chapters/principles_of_code/building_blocks/res/or.jpg b/chapters/general/bitlogic/res/or.jpg similarity index 100% rename from chapters/principles_of_code/building_blocks/res/or.jpg rename to chapters/general/bitlogic/res/or.jpg diff --git a/chapters/principles_of_code/building_blocks/res/xor.jpg b/chapters/general/bitlogic/res/xor.jpg similarity index 100% rename from chapters/principles_of_code/building_blocks/res/xor.jpg rename to chapters/general/bitlogic/res/xor.jpg diff --git a/chapters/general/differential_equations/differential_equations.md b/chapters/general/differential_equations/differential_equations.md index eb43c33dd..dd5a919e3 100644 --- a/chapters/general/differential_equations/differential_equations.md +++ b/chapters/general/differential_equations/differential_equations.md @@ -1,4 +1,4 @@ -### Differential Equations +# Differential Equations Differential equations lie at the heart of many different systems in physics, economics, biology, chemistry, and many other areas of research and engineering. Here, we discuss many different methods to solve particular sets of differential equations. diff --git a/chapters/general/mathematical_background/mathematical_background.md b/chapters/general/mathematical_background/mathematical_background.md new file mode 100644 index 000000000..7cad9457b --- /dev/null +++ b/chapters/general/mathematical_background/mathematical_background.md @@ -0,0 +1,13 @@ +# Mathematical Background + +No matter who you ask, programming requires at least a little math. +That said, for most programmers, it doesn't require *too* much. +For the most part, depending on your specialty, you will probably not see too much calculus or differential equations. +Honestly, you could probably get away with what you learned in high school. + +However, this is a book about algorithms, and algorithms sometimes require a deeper understanding of mathematics. +This section attemps to provide the mathematical foundations that you will need to understand certain algorithms. +As we add new algorithms and need new mathematical tools, we will add them to this section. + +A notable exception to this rule will be in the case of classes of algorithms that require domain-specific knowledge, like quantum simulations or bioinformatics. +In those cases, we will place the mathematical methods in more relevant sections. diff --git a/chapters/principles_of_code/notation/notation.md b/chapters/general/notation/notation.md similarity index 99% rename from chapters/principles_of_code/notation/notation.md rename to chapters/general/notation/notation.md index 93ef37514..fcc58cbac 100644 --- a/chapters/principles_of_code/notation/notation.md +++ b/chapters/general/notation/notation.md @@ -1,4 +1,4 @@ -### Complexity Notation +# Complexity Notation Algorithms are designed to solve problems. Over time, new algorithms are created to solve problems that old algorithms have already solved. @@ -25,7 +25,7 @@ Of the three Big $$O$$ is used the most, and is used in conversation to mean tha Unfortunately, at this point, these notations might be a little vague. In fact, it was incredibly vague for me for a long time, and it wasn't until I saw the notations in action that it all started to make sense, so that's what this section is about: providing concrete examples to better understand computational complexity notation. -### Constant Time +## Constant Time Let's write some code that reads in an array of length `n` and runs with constant time: @@ -66,7 +66,7 @@ Just because this is common practice does not mean it's the *best* practice. I have run into several situation where knowing the constants has saved me hours of run-time, so keep in mind that all of these notations are somewhat vague and dependent on a number of auxiliary factors. Still, that doesn't mean the notation is completely useless. For now, let's keep moving forward with some more complicated (and useful) examples! -### Linear Time +## Linear Time Now we are moving into interesting territory! Let's consider the following function: @@ -127,7 +127,7 @@ That said, there have been several cases throughout the history of algorithms wh For this reason, if you can avoid writing nested `for` loops, you certainly should! However, there are several cases where this cannot be avoided, so don't spend too much time worrying about it unless runtime becomes an issue! -### Exponential and Logarithmic Time +## Exponential and Logarithmic Time These are two more cases that come up all the time and often require a common theme: *recursion*. Generally speaking, logarithmic algorithms are some of the fastest algorithms out there, while exponential algorithms are some of the slowest. Unfortunately, this means that recursion can be either the most useful tool in existence for realizing certain algorithms or the most harmful one, depending on your problem. @@ -165,7 +165,7 @@ If we split these new arrays, we have 4 arrays of 2, and if we split these by tw This is as far as we can go, and we ended up dividing the array 3 times to get to this point. $$3 = \log_2(8)$$, so this function runs with a logarithmic number of operations. -### Putting it all together +## Putting it all together We've outlined the most common complexity cases of different algorithms here, but at this point things might still be unclear. Which is better: $$O(n^2)$$ or $$O(log(n))$$? diff --git a/chapters/principles_of_code/notation/out.dat b/chapters/general/notation/out.dat similarity index 100% rename from chapters/principles_of_code/notation/out.dat rename to chapters/general/notation/out.dat diff --git a/chapters/principles_of_code/notation/res/cplot.png b/chapters/general/notation/res/cplot.png similarity index 100% rename from chapters/principles_of_code/notation/res/cplot.png rename to chapters/general/notation/res/cplot.png diff --git a/chapters/general/physics_solvers/physics_solvers.md b/chapters/general/physics_solvers/physics_solvers.md index 5c6777b22..457a237e8 100644 --- a/chapters/general/physics_solvers/physics_solvers.md +++ b/chapters/general/physics_solvers/physics_solvers.md @@ -1,4 +1,4 @@ -### Physics Solvers +# Physics Solvers There are certain algorithms that have been uniquely created to solve particular physical systems. For example, the kinematic equation can be solved with Verlet integration and also with more general differential equation solvers. diff --git a/chapters/introduction/how_to_contribute.md b/chapters/introduction/how_to_contribute.md index f1209e07b..8847ae01a 100644 --- a/chapters/introduction/how_to_contribute.md +++ b/chapters/introduction/how_to_contribute.md @@ -1,8 +1,8 @@ -## How to Contribute to the Algorithm Archive +# How to Contribute to the Algorithm Archive The *Algorithm Archive* is an effort to learn about and teach algorithms as a community. As such, it requires a certain level of trust between community members. -For the most part, the collaboration can be done via GitHub and gitbook, so it is important to understand the basics of [version control](../principles_of_code/version_control.md). +For the most part, the collaboration can be done via GitHub and gitbook, so it is important to understand the basics of [version control](version_control.md). Ideally, all code provided by the community will be submitted via pull requests and discussed accordingly; however, I understand that many individuals are new to collaborative projects, so I will allow submissions by other means (comments, tweets, etc...). As this project grows in size, it will be harder and harder to facilitate these submissions. In addition, by submitting in any way other than pull requests, I cannot guarantee I will be able to list you as a collaborator (though I will certainly do my best to update the `CONTRIBUTORS.md` file accordingly). diff --git a/chapters/principles_of_code/res/clone.png b/chapters/introduction/res/clone.png similarity index 100% rename from chapters/principles_of_code/res/clone.png rename to chapters/introduction/res/clone.png diff --git a/chapters/principles_of_code/res/fork.png b/chapters/introduction/res/fork.png similarity index 100% rename from chapters/principles_of_code/res/fork.png rename to chapters/introduction/res/fork.png diff --git a/chapters/principles_of_code/version_control.md b/chapters/introduction/version_control.md similarity index 99% rename from chapters/principles_of_code/version_control.md rename to chapters/introduction/version_control.md index 536d0958d..c7d839b9e 100644 --- a/chapters/principles_of_code/version_control.md +++ b/chapters/introduction/version_control.md @@ -1,4 +1,4 @@ -## Git and Version Control +# Git and Version Control I am a fan of open-source software. It allows users to see inside the code running on their system and mess around with it if they like. Unlike proprietary software, open source software allows any user to learn the entire codebase from the ground up, and that's an incredibly exciting prospect! diff --git a/chapters/principles_of_code/choosing_a_language/choosing_a_language.md b/chapters/languages/choosing_a_language.md similarity index 100% rename from chapters/principles_of_code/choosing_a_language/choosing_a_language.md rename to chapters/languages/choosing_a_language.md diff --git a/chapters/principles_of_code/choosing_a_language/compiled/FORTRAN.md b/chapters/languages/compiled/FORTRAN.md similarity index 100% rename from chapters/principles_of_code/choosing_a_language/compiled/FORTRAN.md rename to chapters/languages/compiled/FORTRAN.md diff --git a/chapters/principles_of_code/choosing_a_language/compiled/compiled.md b/chapters/languages/compiled/compiled.md similarity index 100% rename from chapters/principles_of_code/choosing_a_language/compiled/compiled.md rename to chapters/languages/compiled/compiled.md diff --git a/chapters/principles_of_code/choosing_a_language/compiled/makefiles.md b/chapters/languages/compiled/makefiles.md similarity index 100% rename from chapters/principles_of_code/choosing_a_language/compiled/makefiles.md rename to chapters/languages/compiled/makefiles.md diff --git a/chapters/principles_of_code/building_blocks/building_blocks.md b/chapters/principles_of_code/building_blocks/building_blocks.md deleted file mode 100644 index 12cf2b5ca..000000000 --- a/chapters/principles_of_code/building_blocks/building_blocks.md +++ /dev/null @@ -1,9 +0,0 @@ -## Building Blocks - -When it comes to programming, there are certain features that will be used again and again, so it's a good idea to mention how these features work and where they are used. -This section attempts to explain anything that might confuse beginner programmers; however, it is not meant as an exhaustive list of every tool available in the coding toolbox. -Instead, it's meant to provide an accessible understanding of the data structures used throughout this text and the pseudocode that will be used to express these structures. - -It's worth pointing out that algorithms and data stuctures almost always go hand-in-hand. -There are many different ways to climb a mountain, but depending on the mountain you need to climb, you might need different tools. -Similarly, many different algorithms do similar tasks; however, with the right data structures, some algorithms become much more efficient than others. diff --git a/chapters/principles_of_code/building_blocks/classes.md b/chapters/principles_of_code/building_blocks/classes.md deleted file mode 100644 index 371894b1a..000000000 --- a/chapters/principles_of_code/building_blocks/classes.md +++ /dev/null @@ -1,26 +0,0 @@ -### Classes and Structs - -A while ago, one of my friends asked me the purpose of classes in programming. -No matter what I did or how I tried to reason with him, I could not convince him that classes were useful and necessary programming constructs. -To put it simply, classes are data types that allow programmers to store multiple data types within them. -That said, depending on the language, classes might look slightly different. -For example, Julia forgoes classes altogether and simply allows programmers to define a type of types. -I am personally a fan of this approach and will be using it the bulk psuedocode for this text: - -```julia -type Human - Height::Float64 - Weight::Float64 - Popularity::Float64 -end -``` - -Now, here's where things get a little sticky. -The truth is that there is a philosophical difference between how languages implement classes (among other things), which basically boils down to whether languages allow functions to be held within data types or not. -*Functional* programming languages argue that functions should always act on data types. -*Object-Oriented* languages argue that certain data types (like Human, above), should be able to *do* things, so it makes sense to put functions within classes. -There is merit to both of these arguments, so it's best to go with whatever you feel comfortable with. - -In the case of object-oriented languages, classes have an additional layer of complexity associated with them that should definitely be discussed. -That said, I would like to forgo that discussion at this time and come back to it in the near future. -Please bug me if you think I might have forgotten! diff --git a/chapters/principles_of_code/building_blocks/conditions.md b/chapters/principles_of_code/building_blocks/conditions.md deleted file mode 100644 index 41a8ec979..000000000 --- a/chapters/principles_of_code/building_blocks/conditions.md +++ /dev/null @@ -1,102 +0,0 @@ -### Conditions - -Of all the programming building blocks, conditions might be the most intuitive and they basically flow from natural speech. -Let's say you are up late studying for an exam schedule for later in the month, but you are finding yourself lacking in motivation and distracted by the internet. -You hate wasting time, so you try to figure out how tired you are and think to yourself, *if I am tired, I will go to sleep. Otherwise, I should get back to work!* -In code, this looks like: - -```julia -if (me.tired() == true) - me.sleep() -else - me.work() -end -``` - -Here, we are assuming you are a type of `human` with the abilities to both `sleep()` and `work()`. -Note that the condition is checking to see if the statement provided is `true` or `false` before continuing. -In other words, it is condensing the statement `me.tired() == true` into a simple boolean value. -This is important to remember when dealing with loops later. -Conditions allow you to modify the flow of your program depending on other values produced and are a powerful and intuitive tool. - -It's worth noting here that all the mathematical conditions work in these statements: - -| Symbol | Meaning | -| --------------------------- | --------------------------------------- | -| a == b | a is equal to b | -| a > b | a is greater than b | -| a < b | a is less than b | -| a != b | a is not equal to b | -| a == b && b == c | a is equal to b **and** b is equal to c | -| a == b || b == c | a is equal to b **or** b is equal to c | - -Here, the `&&` operator means both conditions must be `true` for the statement as a whole to be considered `true`, while the `||` operator means that only one of the two statements must be `true` for the statement to be considered `true`. -Also note that the `!` operator can be used in front of boolean values to signify the value should be to opposite. -For example, if you are trying to indicate that you are not tired (even though you clearly are), you might say `!me.tired()`. -`me.tired()` will return `true`, but the `!` operator will flip the `true` to `false`. - -In addition to the `if` and `else` keywords, there is also the `else if`, which varies notationally depending on the language you are using. -Imagine that we wanted to add two additional functions to the `human` type: `care()`, which evaluates the amount you care about a particular topic and `procrastinate()`, which is the action of wasting time. -Imagine (again) that you are studying for an exam that is a month away, but this time, you are studying for a class you do not care about. -You might update your thought to be something like, *if I am tired, I will go to sleep. If I don't care about the class, I can continue procrastinating. Otherwise, I should get back to work!* -In code, this looks like: - -```julia -if (me.tired()) - me.sleep() -else if(!me.care()) - me.procrastinate() -else - me.work() -end -``` - -To be clear: if `me.care()` returns `true`, then the `!` will flip the statement in the `else if` to `false`, and thus you will not procrastinate. -If `me.care()` returns `false`, the `!` will flip the statement to `true` and you will begin procrastinating if you are not tired. -This might take a little thought, and I encourage you to meditate on it, if you so desire. - -Now on to something slightly more complicated: *switches*. -Imagine you have a lot of conditions to keep in mind, all of which depend on the same variable. -You couldgo through these conditions one-by-one with a chain of `if` and `else if` conditions, like so: - -```julia -if (val == 0) - scenario_0() -else if (val == 1) - scenario_1() -else if (val == 2) - scenario_2() -else if (val == 3) - scenario_3() -else - scenario_4() -end -``` -Here, we need to run different functions depending on the value of the variable `val`. -In these cases, it's worth bringing in a faster and sometimes more elegant solution: the `switch` statement. - -```julia -switch(val) - case 0: - scenario_0() - break - case 1: - scenario_1() - break - case 2: - scenario_2() - break - case 3: - scenario_3() - break - case 4: - scenario_4() - break -end -``` - - -To clarify: not all languages have a `switch` statement, and as mentioned, it's not precisely necessary. -That said, in languages that do have a `switch`, it's often preferred to a chain of `else if` statements; - -Though simple, conditions are essential to almost all modern code, so get used to seeing them everywhere! diff --git a/chapters/principles_of_code/building_blocks/functions.md b/chapters/principles_of_code/building_blocks/functions.md deleted file mode 100644 index 128441247..000000000 --- a/chapters/principles_of_code/building_blocks/functions.md +++ /dev/null @@ -1,82 +0,0 @@ -### Functions - -Functions make sense from a mathematical point of view. -$$f(x) = 2x+5$$ returns a value for $$f(x)$$ at any point $$x$$ that you want. -For example $$f(5) = 15$$, or $$f(10) = 25$$. -Often times, the function is graphed for *every point* indicating the precise nature of how the function and variable relate to one another, but that is another matter entirely. -For the most part, functions in programming work exactly the same way. -They are dependent on certain variables and return something at the end. -In code, the above function might look like: - -``` -function f(x) - return 2*x+5 -end -``` - -Syntactically, they are a little different, but the content is identical. -That said, it's not obvious how functions help when writing code at this point; however, this will become incredibly obvious once you see them in action. -Basically, functions allow programmers to create reusable operations that can be called at any point in the code. -In a sense, functions make understanding code much, much easier. - -### Recursion - -Simply put, recursion is the process of putting a function inside itself. -Now, I know what you are thinking, "Why does this deserve a special name?" -That is a very good question and one that tooke me a while to understand. -Let's take a simple example: - -```julia -function f(x) - x = x + 1 - f(x) -end -``` - -Every time `f(x)` is called, it calls `f(x)`, which then calls `f(x)` again and again and again... -Basically, we just replicated a `while` loop! -The problem here is that *we forgot a stop condition!* -This means that our function will run forever, constantly incrementing the value of x for all eternity! - -There are many possible solutions, one of which looks like this: - -```julia -function f(x, cutoff) - if (x < cutoff) - x = x + 1 - f(x) - end -end -``` - -In the end, no matter how you choose to use recursion, you need to think carefully about what you want the code to do. -For example, in the case shown here, recursion is definitely not the most straightforward way to increment the value of $$x$$ by $$1$$. -In some cases, though, recursion not only makes the code easier to use and understand, but it might also be the only way to solve a provided problem. -In addition, the proper use of recursion can speed up certain code tremendously. - -I guess the main point is this: *recursion is powerful, but with great power comes great resposibility!* - - - -$$ -\newcommand{\d}{\mathrm{d}} -\newcommand{\bff}{\boldsymbol{f}} -\newcommand{\bfg}{\boldsymbol{g}} -\newcommand{\bfp}{\boldsymbol{p}} -\newcommand{\bfq}{\boldsymbol{q}} -\newcommand{\bfx}{\boldsymbol{x}} -\newcommand{\bfu}{\boldsymbol{u}} -\newcommand{\bfv}{\boldsymbol{v}} -\newcommand{\bfA}{\boldsymbol{A}} -\newcommand{\bfB}{\boldsymbol{B}} -\newcommand{\bfC}{\boldsymbol{C}} -\newcommand{\bfM}{\boldsymbol{M}} -\newcommand{\bfJ}{\boldsymbol{J}} -\newcommand{\bfR}{\boldsymbol{R}} -\newcommand{\bfT}{\boldsymbol{T}} -\newcommand{\bfomega}{\boldsymbol{\omega}} -\newcommand{\bftau}{\boldsymbol{\tau}} -$$ - diff --git a/chapters/principles_of_code/building_blocks/loops.md b/chapters/principles_of_code/building_blocks/loops.md deleted file mode 100644 index 12062ff34..000000000 --- a/chapters/principles_of_code/building_blocks/loops.md +++ /dev/null @@ -1,59 +0,0 @@ -### Loops - -Loops are weird. I'm not going to lie, it took me a super long time to figure out how and when to use them appropriately. -Nowadays, I see them as essential elements to almost any program I write. -There two basic loop types: `for` and `while`, which are syntactically similar and reasonably intuitive. -Let's say you want to walk out of a room with a closed door. -In code, this might look something like: - -```julia -while(me.position < door.position) - me.take_step() -end - -me.open_door() -``` - -Like before, we assume that you are part of a type of `human`s with the functions `take_step()` and `open_door()`. -Here, the `while` loop simply keeps going until the condition is no longer met, and it's assumed that the `take_step()` function changes your `position` value. -When the condition returns `false`, we assume that you are either at the door or have run into it, so it's safe to assume you can use the `open_door()` function. - -The other possible loop type is the `for` loop, which is arguable more common and iterates through a container (such as `vectors` mentioned before). -Often times, the `for` loop will look something like this: - -```julia -for i = 1:10 - print(i) -end -``` - -In this case, we are creating a range of values between $$1$$ and $$10$$ and setting the value of $$i$$ every iteration of the loop. -In this case $$i$$ is an interable variable that steps through the range of `1:10`, and is the primary reason for using a `for` loop instead of a `while` loop for the same task. -To be clear, $$i$$ does not need to iterate through integers and could instead iterate through any number of types held in some other container. - -Ultimately, loops allow programmers to repeat the same operation multiple times and are the heart most programs and simulations I have seen. - - - -$$ -\newcommand{\d}{\mathrm{d}} -\newcommand{\bff}{\boldsymbol{f}} -\newcommand{\bfg}{\boldsymbol{g}} -\newcommand{\bfp}{\boldsymbol{p}} -\newcommand{\bfq}{\boldsymbol{q}} -\newcommand{\bfx}{\boldsymbol{x}} -\newcommand{\bfu}{\boldsymbol{u}} -\newcommand{\bfv}{\boldsymbol{v}} -\newcommand{\bfA}{\boldsymbol{A}} -\newcommand{\bfB}{\boldsymbol{B}} -\newcommand{\bfC}{\boldsymbol{C}} -\newcommand{\bfM}{\boldsymbol{M}} -\newcommand{\bfJ}{\boldsymbol{J}} -\newcommand{\bfR}{\boldsymbol{R}} -\newcommand{\bfT}{\boldsymbol{T}} -\newcommand{\bfomega}{\boldsymbol{\omega}} -\newcommand{\bftau}{\boldsymbol{\tau}} -$$ - diff --git a/chapters/principles_of_code/building_blocks/variables.md b/chapters/principles_of_code/building_blocks/variables.md deleted file mode 100644 index a27ea350c..000000000 --- a/chapters/principles_of_code/building_blocks/variables.md +++ /dev/null @@ -1,113 +0,0 @@ -### Variable and Types - -For many people, declaring variables and types is a straightforward process. -The idea is simple: variables hold values. -We set these values with the `=` sign. -For example, if we say - -``` -x = 5 -``` -Then we have set the value of the variable $$x$$ to be $$5$$. -But here's a question that your computer has to answer: what is $$5$$? - -To us, the answer's trivial, it's a number! -This is true, but there are different kinds of numbers. -There are integers that include all counting numbers from negative to positive infinity: $$-\infty, \cdots, -1, 0, 1, \cdots, \infty$$. -Then there are floating-point numbers which include everything in-between every counting number; however, that is not the end of the story. -Floating-point numbers also have certain levels of precision, the numbers of $$0$$'s after the decimal point. -For example, $$1.01$$ is more precise than $$1.0$$. -Each of these levels of precision will require a different level of storage space on the computer, so it make sense to differentiate them based on the amount of storage they require. -In the end, all of these variables will be stored as some number, $$n$$, binary bits, which are constrained to be either $$0$$ or $$1$$ and as we increase the number of bits, we can hold $$2^n$$ possible values. - -This means that we have multiple different floating-point and integer types: `float16`, `int16`, `float32`, `int32`, `float64`, `int64`, and so on. -Here, the number ($$16, 32, 64,\cdots$$) at the end of the declared variable corresponds to the number of bits used to represent that number. -For the most part, *double precision* or `float64` is good enough for almost all computation; however, sometimes higher precision is necessary and other times lower precision will speed up computation tremendously. - -Most languages allow you to explicitly state the type of every variable, but some languages may treat these variables differently than expected, depending on the type provided. -For example: - -``` -float x = 5 -int y = 5 - -print(1/x) -print(1/y) -``` - ----- -**OUTPUT** -``` -0.2 -0 -``` - -Here, the same mathematical expression provided two radically different results! -Now, you might be thinking that the first output is *more correct*, but this is not exactly true. -The second expression was simply a case of *integer division* and is useful in many cases. -Unfortunately, it is also a notorious source of errors, which is why it's always a good idea to check the types of all variables in a program just to be sure you are doing the appropriate computation. -To be explicit: - -``` -1/5 != 1.0/5.0 -``` - -It's important to keep in mind what you are trying to say and what your computer hears you saying. - -Now, variables do not need to be explicitly numbers. -They can be strings (`"hello world!"`), or any data structure you could want. -These data structures will interact with each other differently and these interactions are sometimes language-dependent, so be careful when working with them! -In addition, some of these data structures have functions unique to them that me may call upon as programmers. - -For example, `vectors` are data containers that hold other data structures. -In almost every language, there is a function that can be used to get the size of a `vector` in order to tell how many elements it holds. -In addition, the vector also has methods to `push` elements into it. - -In C++, for example, vectors often look like this: - -```cpp -#include - -... -// Creating a vector of integers -std::vector vector_of_ints; - -//Adding elements to our vector_of_ints -vector_of_ints.push_back(1); -vector_of_ints.push_back(2); -vector_of_ints.push_back(3); - -// Finding size of our vector_of_ints -vector_of_ints.size(); - -... -``` - -Here, the `size()` function should return 3, because we have put in 3 elements. -We will talk more about vectors in a bit, but for now, know that certain functions are available to be used on certain types, and in most object-oriented languages, these functions are called with a simple `.`. -Almost all laguages also allow users to define their own types in the form of `classes`, which will also be touched on later in this section. - - - -$$ -\newcommand{\d}{\mathrm{d}} -\newcommand{\bff}{\boldsymbol{f}} -\newcommand{\bfg}{\boldsymbol{g}} -\newcommand{\bfp}{\boldsymbol{p}} -\newcommand{\bfq}{\boldsymbol{q}} -\newcommand{\bfx}{\boldsymbol{x}} -\newcommand{\bfu}{\boldsymbol{u}} -\newcommand{\bfv}{\boldsymbol{v}} -\newcommand{\bfA}{\boldsymbol{A}} -\newcommand{\bfB}{\boldsymbol{B}} -\newcommand{\bfC}{\boldsymbol{C}} -\newcommand{\bfM}{\boldsymbol{M}} -\newcommand{\bfJ}{\boldsymbol{J}} -\newcommand{\bfR}{\boldsymbol{R}} -\newcommand{\bfT}{\boldsymbol{T}} -\newcommand{\bfomega}{\boldsymbol{\omega}} -\newcommand{\bftau}{\boldsymbol{\tau}} -$$ - diff --git a/chapters/principles_of_code/code_quality.md b/chapters/principles_of_code/code_quality.md deleted file mode 100644 index c4ed35ac2..000000000 --- a/chapters/principles_of_code/code_quality.md +++ /dev/null @@ -1,19 +0,0 @@ -## Code Quality - -I am a computational physicist. Industry programmers give researchers a hard time for their programming capabilities, not because they cannot code, but because (for the most part) research code looks bad. -Programming, like any other form of creative expression, is limited by the artist's ability to creatively express themselves. -For many computational researchers, the code is not their art. Science is. -Programming is simply the brush they use to stroke the canvas of reality. -Many times, they become so consumed with their painting that they ignore their tools. Now, truth be told, I have seen some pretty repulsive industry code, too, so this complaint is not exclusively biased towards researchers. - -No matter what the intended goal might be, it is important to be able to read and understand the code you are writing. I know putting a comment block at the start of programs might seem like a chore, but it's not so bad, and letting everyone know up-front what the code is intended to do is incredibly useful to readers. Remember that in a few months, you will be a reader too. Take the time to properly care for your code, to clean your brush after using it. It'll pay off in the long run, I promise. - -### Comments / style - -Comments. Every language has a different way to introduce them. Some use the noble #, others the //, still others the ! or $ or C. Regardless of your language of choice, every single language offers you the ability to tell readers what you are intending to do with your code. This is a necessary component to programming. In fact, I would argue that it is one of the most useful part of any code. Sure, the code has to work. It's gotta compile and do something useful, but I cannot tell you how many times I have had to fix broken code that no one had looked at for years. Sometimes this is a long and laborious process, taking every ounce of my mental abilities, and other times it only takes a few minutes. What's the difference? Comments and documentation. - -I remember the first time I learned to program, I found commenting tedious. I remember thinking, "Hah. This is completely useless. Any programmer worth their salt will be able to figure out what I am trying to do in no time!" Turns out, I wasn't worth my salt because after trying to figure out my code a month later, I couldn't figure out what on Earth I was trying to do. Here's the truth: when it comes to programming, you are often your own audience. Trust me, I know it seems like a good idea to keep the code short -- to go for witty one-liners that make you feel brilliant, but these make your code impossible to read. - -When researching, we keep lab notebooks. It's common practice for obvious reasons. If I forget what I was doing the other day or need to look up parameters, I check the lab notebook. If other researchers question the results of my simulations, I check my lab notebook. If I don't know what to do because I have tried everything I can possibly think of, I check my lab notebook. It's a place for inspiration, for validation, and for guidance. When programming, your code should tell the story of your program. It should reveal the hidden secrets that make your code tick. If anyone finds a bug in the code downstream, they should be able to figure out exactly what went wrong and fix it themselves. - -I guess my point is that commenting your code and keeping proper documentation is about more than just cleaning up after yourself. It is a fundamental part to the art of programming. It's like polishing your guitar on a sunny day. It's revising your poems after a long evening of writing. It's levelling your monk before the next raid. It's essential. Do not neglect it! diff --git a/chapters/principles_of_code/principles_of_code.md b/chapters/principles_of_code/principles_of_code.md deleted file mode 100644 index 7e7a58ec3..000000000 --- a/chapters/principles_of_code/principles_of_code.md +++ /dev/null @@ -1,30 +0,0 @@ -# The Principles of Code - -At least to me, programming is a form of creative expression. Sure, programming is difficult. It's difficult in the same way that art, music, or writing is difficult: you know exactly what you want to create, but it takes time to learn how to create it. As I mentioned previously, for a significant portion of my life, I wanted to be an author, so I spent hours and hours every day writing fantasy novels. The more I wrote, the better I got at writing, but when I went back to read the initial chapters of my books, I was frankly revolted at how poor my writing was. By the time I finished revising those chapters and writing more on the side, I felt that the second half of the story was in need of revision too. In the end, I wrote and re-wrote and re-wrote again until I was sick of the story altogether, so I wrote something else. Same characters, different story. It was a vicious cycle that ultimately lead to failure on my part to publish anything. - -Here's that cycle again in code: - -```julia -type Human - ability::Int64 - standard::Int64 -end - -function create_something(me::Human) - while (me.ability < me.standard) - me.ability += 1 - me.standard += 1 - println("I am not good enough. Continuing...") - end -end - -create_something(Human(0,1)) -``` - -I am sure this has a name, but I like to call it the *perfectionist's loop*. It's obviously endless and the only way out is by forcing the code to terminate early with `ctrl+c`. Any artist knows this problem. At first, the act of creation is fun, but after a few iterations, it becomes frustrating. Soon, you are curled into a ball in the corner of a room with a paintbrush in your hand and a myriad of colors splattered all over you and the immediate area. In front of you lay the remains of your art, toppled to the ground. It happens. It will probably happen when you learn programming. When it happens, there is only one thing to do: *keep iterating through the loop!* - -The moment you press `ctrl+c` is the moment you stop improving. Don't stop improving. Don't lower your standards. If you ever need motivation to continue, look at who you were a few months ago. You should be "better" than that person. If not, figure out what's holding you back and keep iterating through the loop! - -The problem is that when it comes to programming, there are a bunch of technical problems that crop up and prevent us from improving. This chapter is specifically written to help you make decisions and improve your ability to program. We'll start with choosing a language -- a question that kept me from even starting programming to begin with. Then we'll move on to programming building blocks and important data structures to remember. The idea is that we'll link to the building block sections when necessary throughout the book. This section will probably be the section that changes the most frequently as the archive evolves. after all, the more algorithms we cover, the more building blocks will be necessary to write them. - -As always, let me know if there's anything that is unclear or you think needs to be fixed! Thanks for reading and good luck! diff --git a/redirects.json b/redirects.json index 49f38ff86..659bd705a 100644 --- a/redirects.json +++ b/redirects.json @@ -1,12 +1,24 @@ { "redirects": [ { - "from": "chapters/introduction.html", - "to": "chapters/introduction/introduction.html" + "from": "chapters/principles_of_code/building_blocks/stacks.html", + "to": "chapters/data_structures/stacks_and_queues/stacks_and_queues.html" + }, + { + "from": "chapters/principles_of_code/building_blocks/bitlogic.html", + "to": "chapters/general/bitlogic.html" + }, + { + "from": "chapters/principles_of_code/notation/notation.html", + "to": "chapters/general/notation.html" + }, + { + "from": "chapters/principles_of_code/version_control.html", + "to": "chapters/introduction/version_control.html" }, { - "from": "chapters/getting_started.html", - "to": "chapters/introduction/my_introduction_to_hobby_programming.html" + "from": "chapters/introduction.html", + "to": "chapters/introduction/introduction.html" }, { "from": "chapters/how_to_contribute.html", @@ -40,10 +52,6 @@ "from": "chapters/euclidean_algorithm/euclidean.html", "to": "chapters/algorithms/euclidean_algorithm/euclidean_algorithm.html" }, - { - "from": "chapters/multiplication/multiplication.html", - "to": "chapters/general/multiplication/multiplication.html" - }, { "from": "chapters/monte_carlo/monte_carlo.html", "to": "chapters/algorithms/monte_carlo_integration/monte_carlo_integration.html" @@ -112,10 +120,6 @@ "from": "chapters/physics_solvers/verlet/verlet.html", "to": "chapters/algorithms/verlet_integration/verlet_integration.html" }, - { - "from": "chapters/physics_solvers/barnes_hut.html", - "to": "chapters/algorithms/barnes_hut_algorithm/barnes_hut_algorithm.html" - }, { "from": "chapters/physics_solvers/quantum/quantum.html", "to": "chapters/general/quantum_systems/quantum_systems.html"