diff options
-rw-r--r-- | README.markdown | 1 | ||||
-rw-r--r-- | c.html.markdown | 132 | ||||
-rw-r--r-- | clojure.html.markdown | 10 | ||||
-rw-r--r-- | dart.html.markdown | 507 | ||||
-rw-r--r-- | file.erb | 1 | ||||
-rw-r--r-- | fsharp.html.markdown | 633 | ||||
-rw-r--r-- | haskell.html.markdown | 348 | ||||
-rw-r--r-- | java.html.markdown | 349 | ||||
-rw-r--r-- | lua.html.markdown | 1 | ||||
-rw-r--r-- | pets.csv | 4 | ||||
-rw-r--r-- | php.html.markdown | 640 | ||||
-rw-r--r-- | python.html.markdown | 94 | ||||
-rw-r--r-- | r.html.markdown | 328 |
13 files changed, 2669 insertions, 379 deletions
diff --git a/README.markdown b/README.markdown index 3223a2bd..77e09abd 100644 --- a/README.markdown +++ b/README.markdown @@ -17,7 +17,6 @@ properly! The most requested languages are: * Scala -* Python * Javascript ... but there are many more requests to do "every language", so don't let that stop you. diff --git a/c.html.markdown b/c.html.markdown index 15bfa05e..69bf099e 100644 --- a/c.html.markdown +++ b/c.html.markdown @@ -2,6 +2,7 @@ language: c author: Adam Bard author_url: http://adambard.com/ +filename: learnc.c --- Ah, C. Still the language of modern high-performance computing. @@ -12,6 +13,7 @@ memory management and C will take you as far as you need to go. ```c // Single-line comments start with // + /* Multi-line comments look like this. */ @@ -19,6 +21,7 @@ Multi-line comments look like this. // Import headers with #include #include <stdlib.h> #include <stdio.h> +#include <string.h> // Declare function signatures in advance in a .h file, or at the top of // your .c file. @@ -27,7 +30,7 @@ void function_2(); // Your program's entry point is a function called // main with an integer return type. -int main(){ +int main() { // print output using printf, for "print formatted" // %d is an integer, \n is a newline @@ -38,36 +41,49 @@ printf("%d\n", 0); // => Prints 0 // Types /////////////////////////////////////// -// Variables must always be declared with a type. +// You have to declare variables before using them. A variable declaration +// requires you to specify its type; a variable's type determines its size +// in bytes. -// 32-bit integer +// ints are usually 4 bytes int x_int = 0; -// 16-bit integer +// shorts are usually 2 bytes short x_short = 0; -// 8-bit integer, aka 1 byte +// chars are guaranteed to be 1 byte char x_char = 0; char y_char = 'y'; // Char literals are quoted with '' -long x_long = 0; // Still 32 bytes for historical reasons -long long x_long_long = 0; // Guaranteed to be at least 64 bytes +// longs are often 4 to 8 bytes; long longs are guaranteed to be at least +// 64 bits +long x_long = 0; +long long x_long_long = 0; -// 32-bit floating-point decimal +// floats are usually 32-bit floating point numbers float x_float = 0.0; -// 64-bit floating-point decimal +// doubles are usually 64-bit floating-point numbers double x_double = 0.0; -// Integer types may be unsigned +// Integral types may be unsigned. This means they can't be negative, but +// the maximum value of an unsigned variable is greater than the maximum +// value of the same size. unsigned char ux_char; unsigned short ux_short; unsigned int ux_int; unsigned long long ux_long_long; +// Other than char, which is always 1 byte, these types vary in size depending +// on your machine. sizeof(T) gives you the size of a variable with type T in +// bytes so you can express the size of these types in a portable way. +// For example, +printf("%lu\n", sizeof(int)); // => 4 (on machines with 4-byte words) + // Arrays must be initialized with a concrete size. char my_char_array[20]; // This array occupies 1 * 20 = 20 bytes int my_int_array[20]; // This array occupies 4 * 20 = 80 bytes + // (assuming 4-byte words) // You can initialize an array to 0 thusly: @@ -81,16 +97,20 @@ my_array[0]; // => 0 my_array[1] = 2; printf("%d\n", my_array[1]); // => 2 -// Strings are just lists of chars terminated by a null (0x00) byte. +// Strings are just arrays of chars terminated by a NUL (0x00) byte, +// represented in strings as the special character '\0'. +// (We don't have to include the NUL byte in string literals; the compiler +// inserts it at the end of the array for us.) char a_string[20] = "This is a string"; +printf("%s\n", a_string); // %s formats a string /* You may have noticed that a_string is only 16 chars long. -Char #17 is a null byte, 0x00 aka \0. +Char #17 is the NUL byte. Chars #18, 19 and 20 have undefined values. */ -printf("%d\n", a_string[16]); +printf("%d\n", a_string[16]); // => 0 /////////////////////////////////////// // Operators @@ -112,7 +132,8 @@ f1 / f2; // => 0.5, plus or minus epsilon // Comparison operators are probably familiar, but // there is no boolean type in c. We use ints instead. -// 0 is false, anything else is true +// 0 is false, anything else is true. (The comparison +// operators always return 0 or 1.) 3 == 2; // => 0 (false) 3 != 2; // => 1 (true) 3 > 2; // => 1 @@ -140,33 +161,33 @@ f1 / f2; // => 0.5, plus or minus epsilon // Control Structures /////////////////////////////////////// -if(0){ +if (0) { printf("I am never run\n"); -}else if(0){ +} else if (0) { printf("I am also never run\n"); -}else{ +} else { printf("I print\n"); } // While loops exist int ii = 0; -while(ii < 10){ +while (ii < 10) { printf("%d, ", ii++); // ii++ increments ii in-place, after using its value. } // => prints "0, 1, 2, 3, 4, 5, 6, 7, 8, 9, " printf("\n"); int kk = 0; -do{ +do { printf("%d, ", kk); -}while(++kk < 10); // ++kk increments kk in-place, before using its value +} while (++kk < 10); // ++kk increments kk in-place, before using its value // => prints "0, 1, 2, 3, 4, 5, 6, 7, 8, 9, " printf("\n"); // For loops too int jj; -for(jj=0; jj < 10; jj++){ +for (jj=0; jj < 10; jj++) { printf("%d, ", jj); } // => prints "0, 1, 2, 3, 4, 5, 6, 7, 8, 9, " @@ -176,8 +197,8 @@ printf("\n"); // Typecasting /////////////////////////////////////// -// Everything in C is stored somewhere in memory. You can change -// the type of a variable to choose how to read its data +// Every value in C has a type, but you can cast one value into another type +// if you want. int x_hex = 0x01; // You can assign vars with hex literals @@ -188,32 +209,53 @@ printf("%d\n", (char) x_hex); // => Prints 1 // Types will overflow without warning printf("%d\n", (char) 257); // => 1 (Max char = 255) -printf("%d\n", (short) 65537); // => 1 (Max short = 65535) + +// Integral types can be cast to floating-point types, and vice-versa. +printf("%f\n", (float)100); // %f formats a float +printf("%lf\n", (double)100); // %lf formats a double +printf("%d\n", (char)100.0); /////////////////////////////////////// // Pointers /////////////////////////////////////// -// You can retrieve the memory address of your variables, -// then mess with them. +// A pointer is a variable declared to store a memory address. Its declaration will +// also tell you the type of data it points to. You can retrieve the memory address +// of your variables, then mess with them. int x = 0; printf("%p\n", &x); // Use & to retrieve the address of a variable // (%p formats a pointer) // => Prints some address in memory; +// Pointer types end with * in their declaration +int* px; // px is a pointer to an int +px = &x; // Stores the address of x in px +printf("%p\n", px); // => Prints some address in memory + +// To retreive the value at the address a pointer is pointing to, +// put * in front to de-reference it. +printf("%d\n", *px); // => Prints 0, the value of x, which is what px is pointing to the address of + +// You can also change the value the pointer is pointing to. +// We'll have to wrap the de-reference in parenthesis because +// ++ has a higher precedence than *. +(*px)++; // Increment the value px is pointing to by 1 +printf("%d\n", *px); // => Prints 1 +printf("%d\n", x); // => Prints 1 + int x_array[20]; // Arrays are a good way to allocate a contiguous block of memory int xx; -for(xx=0; xx<20; xx++){ +for (xx=0; xx<20; xx++) { x_array[xx] = 20 - xx; } // Initialize x_array to 20, 19, 18,... 2, 1 -// Pointer types end with * +// Declare a pointer of type int and initialize it to point to x_array int* x_ptr = x_array; -// This works because arrays are pointers to their first element. +// x_ptr now points to the first element in the array (the integer 20). +// This works because arrays are actually just pointers to their first element. -// Put a * in front to de-reference a pointer and retrieve the value, -// of the same type as the pointer, that the pointer is pointing at. +// Arrays are pointers to their first element printf("%d\n", *(x_ptr)); // => Prints 20 printf("%d\n", x_array[0]); // => Prints 20 @@ -221,33 +263,27 @@ printf("%d\n", x_array[0]); // => Prints 20 printf("%d\n", *(x_ptr + 1)); // => Prints 19 printf("%d\n", x_array[1]); // => Prints 19 -// Array indexes are such a thin wrapper around pointer -// arithmetic that the following works: -printf("%d\n", 0[x_array]); // => Prints 20; -printf("%d\n", 2[x_array]); // => Prints 18; - -// The above is equivalent to: -printf("%d\n", *(0 + x_ptr)); -printf("%d\n", *(2 + x_ptr)); - -// You can give a pointer a block of memory to use with malloc +// You can also dynamically allocate contiguous blocks of memory with the +// standard library function malloc, which takes one integer argument +// representing the number of bytes to allocate from the heap. int* my_ptr = (int*) malloc(sizeof(int) * 20); -for(xx=0; xx<20; xx++){ - *(my_ptr + xx) = 20 - xx; +for (xx=0; xx<20; xx++) { + *(my_ptr + xx) = 20 - xx; // my_ptr[xx] = 20-xx would also work here } // Initialize memory to 20, 19, 18, 17... 2, 1 (as ints) // Dereferencing memory that you haven't allocated gives // unpredictable results printf("%d\n", *(my_ptr + 21)); // => Prints who-knows-what? -// When you're done with a malloc'd block, you need to free it +// When you're done with a malloc'd block of memory, you need to free it, +// or else no one else can use it until your program terminates free(my_ptr); // Strings can be char arrays, but are usually represented as char // pointers: char* my_str = "This is my very own string"; -printf("%d\n", *my_str); // 84 (The ascii value of 'T') +printf("%c\n", *my_str); // => 'T' function_1(); } // end main function @@ -260,12 +296,12 @@ function_1(); // <return type> <function name>(<args>) int add_two_ints(int x1, int x2){ - return x1 + x2; // Use return a return a value + return x1 + x2; // Use return to return a value } /* -Pointers are passed-by-reference (duh), so functions -can mutate their values. +Functions are pass-by-value, but you can make your own references +with pointers so functions can mutate their values. Example: in-place string reversal */ diff --git a/clojure.html.markdown b/clojure.html.markdown index 5086d2c2..12611fd3 100644 --- a/clojure.html.markdown +++ b/clojure.html.markdown @@ -2,6 +2,7 @@ language: clojure author: Adam Bard author_url: http://adambard.com/ +filename: test.clj --- Clojure is a variant of LISP developed for the Java Virtual Machine. It has @@ -12,6 +13,9 @@ state as it comes up. This combination allows it to handle concurrent processing very simply, and often automatically. +(You need a version of Clojure 1.2 or newer) + + ```clojure ; Comments start with semicolons. @@ -56,10 +60,12 @@ and often automatically. (class false) ; Booleans are java.lang.Boolean (class nil); The "null" value is called nil -; If you want to create a literal list of data, use ' to make a "symbol" +; If you want to create a literal list of data, use ' to stop it from +; being evaluated '(+ 1 2) ; => (+ 1 2) +; (shorthand for (quote (+ 1 2)) -; You can eval symbols. +; You can eval a quoted list (eval '(+ 1 2)) ; => 3 ; Collections & Sequences diff --git a/dart.html.markdown b/dart.html.markdown new file mode 100644 index 00000000..27365746 --- /dev/null +++ b/dart.html.markdown @@ -0,0 +1,507 @@ +--- +language: dart +author: Joao Pedrosa +author_url: https://github.com/jpedrosa/ +filename: learndart.dart +--- + +Dart is a newcomer into the realm of programming languages. +It borrows a lot from other mainstream languages, having as a goal not to deviate too much from +its JavaScript sibling. Like JavaScript, Dart aims for great browser integration. + +Dart's most controversial feature must be its Optional Typing. + +```javascript +import "dart:collection"; +import "dart:math" as DM; + +// Welcome to Learn Dart in 15 minutes. http://www.dartlang.org/ +// This is an executable tutorial. You can run it with Dart or on +// the Try Dart! site if you copy/paste it there. http://try.dartlang.org/ + +// Function declaration and method declaration look the same. Function +// declarations can be nested. The declaration takes the form of +// name() {} or name() => singleLineExpression; +// The fat arrow function declaration has an implicit return for the result of +// the expression. +example1() { + example1nested1() { + example1nested2() => print("Example1 nested 1 nested 2"); + example1nested2(); + } + example1nested1(); +} + +// Anonymous functions don't include a name. +example2() { + example2nested1(fn) { + fn(); + } + example2nested1(() => print("Example2 nested 1")); +} + +// When a function parameter is declared, the declaration can include the +// number of parameters the function takes by specifying the names of the +// parameters it takes. +example3() { + example3nested1(fn(informSomething)) { + fn("Example3 nested 1"); + } + example3planB(fn) { // Or don't declare number of parameters. + fn("Example3 plan B"); + } + example3nested1((s) => print(s)); + example3planB((s) => print(s)); +} + +// Functions have closure access to outer variables. +var example4Something = "Example4 nested 1"; +example4() { + example4nested1(fn(informSomething)) { + fn(example4Something); + } + example4nested1((s) => print(s)); +} + +// Class declaration with a sayIt method, which also has closure access +// to the outer variable as though it were a function as seen before. +var example5method = "Example5 sayIt"; +class Example5Class { + sayIt() { + print(example5method); + } +} +example5() { + // Create an anonymous instance of the Example5Class and call the sayIt + // method on it. + new Example5Class().sayIt(); +} + +// Class declaration takes the form of class name { [classBody] }. +// Where classBody can include instance methods and variables, but also +// class methods and variables. +class Example6Class { + var example6InstanceVariable = "Example6 instance variable"; + sayIt() { + print(example6InstanceVariable); + } +} +example6() { + new Example6Class().sayIt(); +} + +// Class methods and variables are declared with "static" terms. +class Example7Class { + static var example7ClassVariable = "Example7 class variable"; + static sayItFromClass() { + print(example7ClassVariable); + } + sayItFromInstance() { + print(example7ClassVariable); + } +} +example7() { + Example7Class.sayItFromClass(); + new Example7Class().sayItFromInstance(); +} + +// Literals are great, but there's a restriction for what literals can be +// outside of function/method bodies. Literals on the outer scope of class +// or outside of class have to be constant. Strings and numbers are constant +// by default. But arrays and maps are not. They can be made constant by +// declaring them "const". +var example8A = const ["Example8 const array"], + example8M = const {"someKey": "Example8 const map"}; +example8() { + print(example8A[0]); + print(example8M["someKey"]); +} + +// Loops in Dart take the form of standard for () {} or while () {} loops, +// slightly more modern for (.. in ..) {}, or functional callbacks with many +// supported features, starting with forEach. +var example9A = const ["a", "b"]; +example9() { + for (var i = 0; i < example9A.length; i++) { + print("Example9 for loop '${example9A[i]}'"); + } + var i = 0; + while (i < example9A.length) { + print("Example9 while loop '${example9A[i]}'"); + i++; + } + for (var e in example9A) { + print("Example9 for-in loop '${e}'"); + } + example9A.forEach((e) => print("Example9 forEach loop '${e}'")); +} + +// To loop over the characters of a string or to extract a substring. +var example10S = "ab"; +example10() { + for (var i = 0; i < example10S.length; i++) { + print("Example10 String character loop '${example10S[i]}'"); + } + for (var i = 0; i < example10S.length; i++) { + print("Example10 substring loop '${example10S.substring(i, i + 1)}'"); + } +} + +// Int and double are the two supported number formats. +example11() { + var i = 1 + 320, d = 3.2 + 0.01; + print("Example11 int ${i}"); + print("Example11 double ${d}"); +} + +// DateTime provides date/time arithmetic. +example12() { + var now = new DateTime.now(); + print("Example12 now '${now}'"); + now = now.add(new Duration(days: 1)); + print("Example12 tomorrow '${now}'"); +} + +// Regular expressions are supported. +example13() { + var s1 = "some string", s2 = "some", re = new RegExp("^s.+?g\$"); + match(s) { + if (re.hasMatch(s)) { + print("Example13 regexp matches '${s}'"); + } else { + print("Example13 regexp doesn't match '${s}'"); + } + } + match(s1); + match(s2); +} + +// Boolean expressions need to resolve to either true or false, as no +// implicit conversions are supported. +example14() { + var v = true; + if (v) { + print("Example14 value is true"); + } + v = null; + try { + if (v) { + // Never runs + } else { + // Never runs + } + } catch (e) { + print("Example14 null value causes an exception: '${e}'"); + } +} + +// try/catch/finally and throw are used for exception handling. +// throw takes any object as parameter; +example15() { + try { + try { + throw "Some unexpected error."; + } catch (e) { + print("Example15 an exception: '${e}'"); + throw e; // Re-throw + } + } catch (e) { + print("Example15 catch exception being re-thrown: '${e}'"); + } finally { + print("Example15 Still run finally"); + } +} + +// To be efficient when creating a long string dynamically, use +// StringBuffer. Or you could join a string array. +example16() { + var sb = new StringBuffer(), a = ["a", "b", "c", "d"], e; + for (e in a) { sb.write(e); } + print("Example16 dynamic string created with " + "StringBuffer '${sb.toString()}'"); + print("Example16 join string array '${a.join()}'"); +} + +// Strings can be concatenated by just having string literals next to +// one another with no further operator needed. +example17() { + print("Example17 " + "concatenate " + "strings " + "just like that"); +} + +// Strings have single-quote or double-quote for delimiters with no +// actual difference between the two. The given flexibility can be good +// to avoid the need to escape content that matches the delimiter being +// used. For example, double-quotes of HTML attributes if the string +// contains HTML content. +example18() { + print('Example18 <a href="etc">' + "Don't can't I'm Etc" + '</a>'); +} + +// Strings with triple single-quotes or triple double-quotes span +// multiple lines and include line delimiters. +example19() { + print('''Example19 <a href="etc"> +Example19 Don't can't I'm Etc +Example19 </a>'''); +} + +// Strings have the nice interpolation feature with the $ character. +// With $ { [expression] }, the return of the expression is interpolated. +// $ followed by a variable name interpolates the content of that variable. +// $ can be escaped like so \$ to just add it to the string instead. +example20() { + var s1 = "'\${s}'", s2 = "'\$s'"; + print("Example20 \$ interpolation ${s1} or $s2 works."); +} + +// Optional types allow for the annotation of APIs and come to the aid of +// IDEs so the IDEs can better refactor, auto-complete and check for +// errors. So far we haven't declared any types and the programs have +// worked just fine. In fact, types are disregarded during runtime. +// Types can even be wrong and the program will still be given the +// benefit of the doubt and be run as though the types didn't matter. +// There's a runtime parameter that checks for type errors which is +// the checked mode, which is said to be useful during development time, +// but which is also slower because of the extra checking and is thus +// avoided during deployment runtime. +class Example21 { + List<String> _names; + Example21() { + _names = ["a", "b"]; + } + List<String> get names => _names; + set names(List<String> list) { + _names = list; + } + int get length => _names.length; + void add(String name) { + _names.add(name); + } +} +void example21() { + Example21 o = new Example21(); + o.add("c"); + print("Example21 names '${o.names}' and length '${o.length}'"); + o.names = ["d", "e"]; + print("Example21 names '${o.names}' and length '${o.length}'"); +} + +// Class inheritance takes the form of class name extends AnotherClassName {}. +class Example22A { + var _name = "Some Name!"; + get name => _name; +} +class Example22B extends Example22A {} +example22() { + var o = new Example22B(); + print("Example22 class inheritance '${o.name}'"); +} + +// Class mixin is also available, and takes the form of +// class name extends SomeClass with AnotherClassName {}. +// It's necessary to extend some class to be able to mixin another one. +// The template class of mixin cannot at the moment have a constructor. +// Mixin is mostly used to share methods with distant classes, so the +// single inheritance doesn't get in the way of reusable code. +// Mixins follow the "with" statement during the class declaration. +class Example23A {} +class Example23Utils { + addTwo(n1, n2) { + return n1 + n2; + } +} +class Example23B extends Example23A with Example23Utils { + addThree(n1, n2, n3) { + return addTwo(n1, n2) + n3; + } +} +example23() { + var o = new Example23B(), r1 = o.addThree(1, 2, 3), + r2 = o.addTwo(1, 2); + print("Example23 addThree(1, 2, 3) results in '${r1}'"); + print("Example23 addTwo(1, 2) results in '${r2}'"); +} + +// The Class constructor method uses the same name of the class and +// takes the form of SomeClass() : super() {}, where the ": super()" +// part is optional and it's used to delegate constant parameters to the +// super-parent's constructor. +class Example24A { + var _value; + Example24A({value: "someValue"}) { + _value = value; + } + get value => _value; +} +class Example24B extends Example24A { + Example24B({value: "someOtherValue"}) : super(value: value); +} +example24() { + var o1 = new Example24B(), + o2 = new Example24B(value: "evenMore"); + print("Example24 calling super during constructor '${o1.value}'"); + print("Example24 calling super during constructor '${o2.value}'"); +} + +// There's a shortcut to set constructor parameters in case of simpler classes. +// Just use the this.parameterName prefix and it will set the parameter on +// an instance variable of same name. +class Example25 { + var value, anotherValue; + Example25({this.value, this.anotherValue}); +} +example25() { + var o = new Example25(value: "a", anotherValue: "b"); + print("Example25 shortcut for constructor '${o.value}' and " + "'${o.anotherValue}'"); +} + +// Named parameters are available when declared between {}. +// Parameter order can be optional when declared between {}. +// Parameters can be made optional when declared between []. +example26() { + var _name, _surname, _email; + setConfig1({name, surname}) { + _name = name; + _surname = surname; + } + setConfig2(name, [surname, email]) { + _name = name; + _surname = surname; + _email = email; + } + setConfig1(surname: "Doe", name: "John"); + print("Example26 name '${_name}', surname '${_surname}', " + "email '${_email}'"); + setConfig2("Mary", "Jane"); + print("Example26 name '${_name}', surname '${_surname}', " + "email '${_email}'"); +} + +// Variables declared with final can only be set once. +// In case of classes, final instance variables can be set via constant +// constructor parameter. +class Example27 { + final color1, color2; + // A little flexibility to set final instance variables with syntax + // that follows the : + Example27({this.color1, color2}) : color2 = color2; +} +example27() { + final color = "orange", o = new Example27(color1: "lilac", color2: "white"); + print("Example27 color is '${color}'"); + print("Example27 color is '${o.color1}' and '${o.color2}'"); +} + +// To import a library, use import "libraryPath" or if it's a core library, +// import "dart:libraryName". There's also the "pub" package management with +// its own convention of import "package:packageName". +// See import "dart:collection"; at the top. Imports must come before +// other code declarations. IterableBase comes from dart:collection. +class Example28 extends IterableBase { + var names; + Example28() { + names = ["a", "b"]; + } + get iterator => names.iterator; +} +example28() { + var o = new Example28(); + o.forEach((name) => print("Example28 '${name}'")); +} + +// For control flow we have: +// * standard switch with must break statements +// * if-else if-else and ternary ..?..:.. operator +// * closures and anonymous functions +// * break, continue and return statements +example29() { + var v = true ? 30 : 60; + switch (v) { + case 30: + print("Example29 switch statement"); + break; + } + if (v < 30) { + } else if (v > 30) { + } else { + print("Example29 if-else statement"); + } + callItForMe(fn()) { + return fn(); + } + rand() { + v = new DM.Random().nextInt(50); + return v; + } + while (true) { + print("Example29 callItForMe(rand) '${callItForMe(rand)}'"); + if (v != 30) { + break; + } else { + continue; + } + // Never gets here. + } +} + +// Parse int, convert double to int, or just keep int when dividing numbers +// by using the ~/ operation. Let's play a guess game too. +example30() { + var gn, tooHigh = false, + n, n2 = (2.0).toInt(), top = int.parse("123") ~/ n2, bottom = 0; + top = top ~/ 6; + gn = new DM.Random().nextInt(top + 1); // +1 because nextInt top is exclusive + print("Example30 Guess a number between 0 and ${top}"); + guessNumber(i) { + if (n == gn) { + print("Example30 Guessed right! The number is ${gn}"); + } else { + tooHigh = n > gn; + print("Example30 Number ${n} is too " + "${tooHigh ? 'high' : 'low'}. Try again"); + } + return n == gn; + } + n = (top - bottom) ~/ 2; + while (!guessNumber(n)) { + if (tooHigh) { + top = n - 1; + } else { + bottom = n + 1; + } + n = bottom + ((top - bottom) ~/ 2); + } +} + +// Programs have only one entry point in the main function. +// Nothing is expected to be executed on the outer scope before a program +// starts running with what's in its main function. +// This helps with faster loading and even lazily loading of just what +// the program needs to startup with. +main() { + print("Learn Dart in 15 minutes!"); + [example1, example2, example3, example4, example5, example6, example7, + example8, example9, example10, example11, example12, example13, example14, + example15, example16, example17, example18, example19, example20, + example21, example22, example23, example24, example25, example26, + example27, example28, example29, example30 + ].forEach((ef) => ef()); +} + +``` + +## Further Reading + +Dart has a comprehenshive web-site. It covers API reference, tutorials, articles and more, including a +useful Try Dart online. +http://www.dartlang.org/ +http://try.dartlang.org/ + + + diff --git a/file.erb b/file.erb new file mode 100644 index 00000000..5f162aa5 --- /dev/null +++ b/file.erb @@ -0,0 +1 @@ +<%= rawcode %> diff --git a/fsharp.html.markdown b/fsharp.html.markdown new file mode 100644 index 00000000..b1860372 --- /dev/null +++ b/fsharp.html.markdown @@ -0,0 +1,633 @@ +--- +language: F# +author: Scott Wlaschin +author_url: http://fsharpforfunandprofit.com/ +filename: learnfsharp.fs +--- + +F# is a general purpose functional/OO programming language. It's free and open source, and runs on Linux, Mac, Windows and more. + +It has a powerful type system that traps many errors at compile time, but it uses type inference so that it reads more like a dynamic language. + +The syntax of F# is different from C-style languages: + +* Curly braces are not used to delimit blocks of code. Instead, indentation is used (like Python). +* Whitespace is used to separate parameters rather than commas. + +If you want to try out the code below, you can go to [tryfsharp.org](http://www.tryfsharp.org/Create) and paste it into an interactive REPL. + +```csharp + +// single line comments use a double slash +(* multi line comments use (* . . . *) pair + +-end of multi line comment- *) + +// ================================================ +// Basic Syntax +// ================================================ + +// ------ "Variables" (but not really) ------ +// The "let" keyword defines an (immutable) value +let myInt = 5 +let myFloat = 3.14 +let myString = "hello" //note that no types needed + +// ------ Lists ------ +let twoToFive = [2;3;4;5] // Square brackets create a list with + // semicolon delimiters. +let oneToFive = 1 :: twoToFive // :: creates list with new 1st element +// The result is [1;2;3;4;5] +let zeroToFive = [0;1] @ twoToFive // @ concats two lists + +// IMPORTANT: commas are never used as delimiters, only semicolons! + +// ------ Functions ------ +// The "let" keyword also defines a named function. +let square x = x * x // Note that no parens are used. +square 3 // Now run the function. Again, no parens. + +let add x y = x + y // don't use add (x,y)! It means something + // completely different. +add 2 3 // Now run the function. + +// to define a multiline function, just use indents. No semicolons needed. +let evens list = + let isEven x = x%2 = 0 // Define "isEven" as a sub function + List.filter isEven list // List.filter is a library function + // with two parameters: a boolean function + // and a list to work on + +evens oneToFive // Now run the function + +// You can use parens to clarify precedence. In this example, +// do "map" first, with two args, then do "sum" on the result. +// Without the parens, "List.map" would be passed as an arg to List.sum +let sumOfSquaresTo100 = + List.sum ( List.map square [1..100] ) + +// You can pipe the output of one operation to the next using "|>" +// Piping data around is very common in F#, similar to UNIX pipes. + +// Here is the same sumOfSquares function written using pipes +let sumOfSquaresTo100piped = + [1..100] |> List.map square |> List.sum // "square" was defined earlier + +// you can define lambdas (anonymous functions) using the "fun" keyword +let sumOfSquaresTo100withFun = + [1..100] |> List.map (fun x -> x*x) |> List.sum + +// In F# there is no "return" keyword. A function always +// returns the value of the last expression used. + +// ------ Pattern Matching ------ +// Match..with.. is a supercharged case/switch statement. +let simplePatternMatch = + let x = "a" + match x with + | "a" -> printfn "x is a" + | "b" -> printfn "x is b" + | _ -> printfn "x is something else" // underscore matches anything + +// F# doesn't allow nulls by default -- you must use an Option type +// and then pattern match. +// Some(..) and None are roughly analogous to Nullable wrappers +let validValue = Some(99) +let invalidValue = None + +// In this example, match..with matches the "Some" and the "None", +// and also unpacks the value in the "Some" at the same time. +let optionPatternMatch input = + match input with + | Some i -> printfn "input is an int=%d" i + | None -> printfn "input is missing" + +optionPatternMatch validValue +optionPatternMatch invalidValue + +// ------ Printing ------ +// The printf/printfn functions are similar to the +// Console.Write/WriteLine functions in C#. +printfn "Printing an int %i, a float %f, a bool %b" 1 2.0 true +printfn "A string %s, and something generic %A" "hello" [1;2;3;4] + +// There are also sprintf/sprintfn functions for formatting data +// into a string, similar to String.Format in C#. + +// ================================================ +// More on functions +// ================================================ + +// F# is a true functional language -- functions are first +// class entities and can be combined easy to make powerful +// constructs + +// Modules are used to group functions together +// Indentation is needed for each nested module. +module FunctionExamples = + + // define a simple adding function + let add x y = x + y + + // basic usage of a function + let a = add 1 2 + printfn "1+2 = %i" a + + // partial application to "bake in" parameters + let add42 = add 42 + let b = add42 1 + printfn "42+1 = %i" b + + // composition to combine functions + let add1 = add 1 + let add2 = add 2 + let add3 = add1 >> add2 + let c = add3 7 + printfn "3+7 = %i" c + + // higher order functions + [1..10] |> List.map add3 |> printfn "new list is %A" + + // lists of functions, and more + let add6 = [add1; add2; add3] |> List.reduce (>>) + let d = add6 7 + printfn "1+2+3+7 = %i" d + +// ================================================ +// Lists and collection +// ================================================ + +// There are three types of ordered collection: +// * Lists are most basic immutable collection. +// * Arrays are mutable and more efficient when needed. +// * Sequences are lazy and infinite (e.g. an enumerator). +// +// Other collections include immutable maps and sets +// plus all the standard .NET collections + +module ListExamples = + + // lists use square brackets + let list1 = ["a";"b"] + let list2 = "c" :: list1 // :: is prepending + let list3 = list1 @ list2 // @ is concat + + // list comprehensions (aka generators) + let squares = [for i in 1..10 do yield i*i] + + // prime number generator + let rec sieve = function + | (p::xs) -> p :: sieve [ for x in xs do if x % p > 0 then yield x ] + | [] -> [] + let primes = sieve [2..50] + printfn "%A" primes + + // pattern matching for lists + let listMatcher aList = + match aList with + | [] -> printfn "the list is empty" + | [first] -> printfn "the list has one element %A " first + | [first; second] -> printfn "list is %A and %A" first second + | _ -> printfn "the list has more than two elements" + + listMatcher [1;2;3;4] + listMatcher [1;2] + listMatcher [1] + listMatcher [] + + // recursion using lists + let rec sum aList = + match aList with + | [] -> 0 + | x::xs -> x + sum xs + sum [1..10] + + // ----------------------------------------- + // Standard library functions + // ----------------------------------------- + + // map + let add3 x = x + 3 + [1..10] |> List.map add3 + + // filter + let even x = x % 2 = 0 + [1..10] |> List.filter even + + // many more -- see documentation + +module ArrayExamples = + + // arrays use square brackets with bar + let array1 = [| "a";"b" |] + let first = array1.[0] // indexed access using dot + + // pattern matching for arrays is same as for lists + let arrayMatcher aList = + match aList with + | [| |] -> printfn "the array is empty" + | [| first |] -> printfn "the array has one element %A " first + | [| first; second |] -> printfn "array is %A and %A" first second + | _ -> printfn "the array has more than two elements" + + arrayMatcher [| 1;2;3;4 |] + + // Standard library functions just as for List + + [| 1..10 |] + |> Array.map (fun i -> i+3) + |> Array.filter (fun i -> i%2 = 0) + |> Array.iter (printfn "value is %i. ") + + +module SequenceExamples = + + // sequences use curly braces + let seq1 = seq { yield "a"; yield "b" } + + // sequences can use yield and + // can contain subsequences + let strange = seq { + // "yield! adds one element + yield 1; yield 2; + + // "yield!" adds a whole subsequence + yield! [5..10] + yield! seq { + for i in 1..10 do + if i%2 = 0 then yield i }} + // test + strange |> Seq.toList + + + // Sequences can be created using "unfold" + // Here's the fibonacci series + let fib = Seq.unfold (fun (fst,snd) -> + Some(fst + snd, (snd, fst + snd))) (0,1) + + // test + let fib10 = fib |> Seq.take 10 |> Seq.toList + printf "first 10 fibs are %A" fib10 + + +// ================================================ +// Data Types +// ================================================ + +module DataTypeExamples = + + // All data is immutable by default + + // Tuples are quick 'n easy anonymous types + // -- Use a comma to create a tuple + let twoTuple = 1,2 + let threeTuple = "a",2,true + + // Pattern match to unpack + let x,y = twoTuple //sets x=1 y=2 + + // ------------------------------------ + // Record types have named fields + // ------------------------------------ + + // Use "type" with curly braces to define a record type + type Person = {First:string; Last:string} + + // Use "let" with curly braces to create a record + let person1 = {First="John"; Last="Doe"} + + // Pattern match to unpack + let {First=first} = person1 //sets first="john" + + // ------------------------------------ + // Union types (aka variants) have a set of choices + // Only case can be valid at a time. + // ------------------------------------ + + // Use "type" with bar/pipe to define a union type + type Temp = + | DegreesC of float + | DegreesF of float + + // Use one of the cases to create one + let temp1 = DegreesF 98.6 + let temp2 = DegreesC 37.0 + + // Pattern match on all cases to unpack + let printTemp = function + | DegreesC t -> printfn "%f degC" t + | DegreesF t -> printfn "%f degF" t + + printTemp temp1 + printTemp temp2 + + // ------------------------------------ + // Recursive types + // ------------------------------------ + + // Types can be combined recursively in complex ways + // without having to create subclasses + type Employee = + | Worker of Person + | Manager of Employee list + + let jdoe = {First="John";Last="Doe"} + let worker = Worker jdoe + + // ------------------------------------ + // Modelling with types + // ------------------------------------ + + // Union types are great for modelling state without using flags + type EmailAddress = + | ValidEmailAddress of string + | InvalidEmailAddress of string + + let trySendEmail email = + match email with // use pattern matching + | ValidEmailAddress address -> () // send + | InvalidEmailAddress address -> () // dont send + + // The combination of union types and record types together + // provide a great foundation for domain driven design. + // You can create hundreds of little types that accurately + // reflect the domain. + + type CartItem = { ProductCode: string; Qty: int } + type Payment = Payment of float + type ActiveCartData = { UnpaidItems: CartItem list } + type PaidCartData = { PaidItems: CartItem list; Payment: Payment} + + type ShoppingCart = + | EmptyCart // no data + | ActiveCart of ActiveCartData + | PaidCart of PaidCartData + + // ------------------------------------ + // Built in behavior for types + // ------------------------------------ + + // Core types have useful "out-of-the-box" behavior, no coding needed. + // * Immutability + // * Pretty printing when debugging + // * Equality and comparison + // * Serialization + + // Pretty printing using %A + printfn "twoTuple=%A,\nPerson=%A,\nTemp=%A,\nEmployee=%A" + twoTuple person1 temp1 worker + + // Equality and comparison built in. + // Here's an example with cards. + type Suit = Club | Diamond | Spade | Heart + type Rank = Two | Three | Four | Five | Six | Seven | Eight + | Nine | Ten | Jack | Queen | King | Ace + + let hand = [ Club,Ace; Heart,Three; Heart,Ace; + Spade,Jack; Diamond,Two; Diamond,Ace ] + + // sorting + List.sort hand |> printfn "sorted hand is (low to high) %A" + List.max hand |> printfn "high card is %A" + List.min hand |> printfn "low card is %A" + + +// ================================================ +// Active patterns +// ================================================ + +module ActivePatternExamples = + + // F# has a special type of pattern matching called "active patterns" + // where the pattern can be parsed or detected dynamically. + + // "banana clips" are the syntax for active patterns + + // for example, define an "active" pattern to match character types... + let (|Digit|Letter|Whitespace|Other|) ch = + if System.Char.IsDigit(ch) then Digit + else if System.Char.IsLetter(ch) then Letter + else if System.Char.IsWhiteSpace(ch) then Whitespace + else Other + + // ... and then use it to make parsing logic much clearer + let printChar ch = + match ch with + | Digit -> printfn "%c is a Digit" ch + | Letter -> printfn "%c is a Letter" ch + | Whitespace -> printfn "%c is a Whitespace" ch + | _ -> printfn "%c is something else" ch + + // print a list + ['a';'b';'1';' ';'-';'c'] |> List.iter printChar + + // ----------------------------------- + // FizzBuzz using active patterns + // ----------------------------------- + + // You can create partial matching patterns as well + // Just use undercore in the defintion, and return Some if matched. + let (|MultOf3|_|) i = if i % 3 = 0 then Some MultOf3 else None + let (|MultOf5|_|) i = if i % 5 = 0 then Some MultOf5 else None + + // the main function + let fizzBuzz i = + match i with + | MultOf3 & MultOf5 -> printf "FizzBuzz, " + | MultOf3 -> printf "Fizz, " + | MultOf5 -> printf "Buzz, " + | _ -> printf "%i, " i + + // test + [1..20] |> List.iter fizzBuzz + +// ================================================ +// Conciseness +// ================================================ + +module AlgorithmExamples = + + // F# has a high signal/noise ratio, so code reads + // almost like the actual algorithm + + // ------ Example: define sumOfSquares function ------ + let sumOfSquares n = + [1..n] // 1) take all the numbers from 1 to n + |> List.map square // 2) square each one + |> List.sum // 3) sum the results + + // test + sumOfSquares 100 |> printfn "Sum of squares = %A" + + // ------ Example: define a sort function ------ + let rec sort list = + match list with + // If the list is empty + | [] -> + [] // return an empty list + // If the list is not empty + | firstElem::otherElements -> // take the first element + let smallerElements = // extract the smaller elements + otherElements // from the remaining ones + |> List.filter (fun e -> e < firstElem) + |> sort // and sort them + let largerElements = // extract the larger ones + otherElements // from the remaining ones + |> List.filter (fun e -> e >= firstElem) + |> sort // and sort them + // Combine the 3 parts into a new list and return it + List.concat [smallerElements; [firstElem]; largerElements] + + // test + sort [1;5;23;18;9;1;3] |> printfn "Sorted = %A" + +// ================================================ +// Asynchronous Code +// ================================================ + +module AsyncExample = + + // F# has built-in features to help with async code + // without encountering the "pyramid of doom" + // + // The following example downloads a set of web pages in parallel. + + open System.Net + open System + open System.IO + open Microsoft.FSharp.Control.CommonExtensions + + // Fetch the contents of a URL asynchronously + let fetchUrlAsync url = + async { // "async" keyword and curly braces + // creates an "async" object + let req = WebRequest.Create(Uri(url)) + use! resp = req.AsyncGetResponse() + // use! is async assignment + use stream = resp.GetResponseStream() + // "use" triggers automatic close() + // on resource at end of scope + use reader = new IO.StreamReader(stream) + let html = reader.ReadToEnd() + printfn "finished downloading %s" url + } + + // a list of sites to fetch + let sites = ["http://www.bing.com"; + "http://www.google.com"; + "http://www.microsoft.com"; + "http://www.amazon.com"; + "http://www.yahoo.com"] + + // do it + sites + |> List.map fetchUrlAsync // make a list of async tasks + |> Async.Parallel // set up the tasks to run in parallel + |> Async.RunSynchronously // start them off + +// ================================================ +// .NET compatability +// ================================================ + +module NetCompatibilityExamples = + + // F# can do almost everything C# can do, and it integrates + // seamlessly with .NET or Mono libraries. + + // ------- work with existing library functions ------- + + let (i1success,i1) = System.Int32.TryParse("123"); + if i1success then printfn "parsed as %i" i1 else printfn "parse failed" + + // ------- Implement interfaces on the fly! ------- + + // create a new object that implements IDisposable + let makeResource name = + { new System.IDisposable + with member this.Dispose() = printfn "%s disposed" name } + + let useAndDisposeResources = + use r1 = makeResource "first resource" + printfn "using first resource" + for i in [1..3] do + let resourceName = sprintf "\tinner resource %d" i + use temp = makeResource resourceName + printfn "\tdo something with %s" resourceName + use r2 = makeResource "second resource" + printfn "using second resource" + printfn "done." + + // ------- Object oriented code ------- + + // F# is also a fully fledged OO language. + // It supports classes, inheritance, virtual methods, etc. + + // interface with generic type + type IEnumerator<'a> = + abstract member Current : 'a + abstract MoveNext : unit -> bool + + // abstract base class with virtual methods + [<AbstractClass>] + type Shape() = + //readonly properties + abstract member Width : int with get + abstract member Height : int with get + //non-virtual method + member this.BoundingArea = this.Height * this.Width + //virtual method with base implementation + abstract member Print : unit -> unit + default this.Print () = printfn "I'm a shape" + + // concrete class that inherits from base class and overrides + type Rectangle(x:int, y:int) = + inherit Shape() + override this.Width = x + override this.Height = y + override this.Print () = printfn "I'm a Rectangle" + + //test + let r = Rectangle(2,3) + printfn "The width is %i" r.Width + printfn "The area is %i" r.BoundingArea + r.Print() + + // ------- extension methods ------- + + //Just as in C#, F# can extend existing classes with extension methods. + type System.String with + member this.StartsWithA = this.StartsWith "A" + + //test + let s = "Alice" + printfn "'%s' starts with an 'A' = %A" s s.StartsWithA + + // ------- events ------- + + type MyButton() = + let clickEvent = new Event<_>() + + [<CLIEvent>] + member this.OnClick = clickEvent.Publish + + member this.TestEvent(arg) = + clickEvent.Trigger(this, arg) + + // test + let myButton = new MyButton() + myButton.OnClick.Add(fun (sender, arg) -> + printfn "Click event with arg=%O" arg) + + myButton.TestEvent("Hello World!") + +``` + +## More Information + +For more demonstrations of F#, go to the [Try F#](http://www.tryfsharp.org/Learn) site, or my [why use F#](http://fsharpforfunandprofit.com/why-use-fsharp/) series. + +Read more about F# at [fsharp.org](http://fsharp.org/). + + + + diff --git a/haskell.html.markdown b/haskell.html.markdown new file mode 100644 index 00000000..f3baa9a5 --- /dev/null +++ b/haskell.html.markdown @@ -0,0 +1,348 @@ +--- +language: haskell +author: Adit Bhargava +author_url: http://adit.io +--- + +Haskell was designed as a practical, purely functional programming language. It's famous for +it's monads and it's type system, but I keep coming back to it because of it's elegance. Haskell +makes coding a real joy for me. + +```haskell +-- Single line comments start with two dashes. +{- Multiline comments can be enclosed +in a block like this. +-} + +---------------------------------------------------- +-- 1. Primitive Datatypes and Operators +---------------------------------------------------- + +-- You have numbers +3 -- 3 + +-- Math is what you would expect +1 + 1 -- 2 +8 - 1 -- 7 +10 * 2 -- 20 +35 / 5 -- 7.0 + +-- Division is not integer division by default +35 / 4 -- 8.75 + +-- integer division +35 `div` 4 -- 8 + +-- Boolean values are primitives +True +False + +-- Boolean operations +not True -- False +not False -- True +1 == 1 -- True +1 /= 1 -- False +1 < 10 -- True + +-- In the above examples, `not` is a function that takes one value. +-- Haskell doesn't need parentheses for function calls...all the arguments +-- are just listed after the function. So the general pattern is: +-- func arg1 arg2 arg3... +-- See the section on functions for information on how to write your own. + +-- Strings and characters +"This is a string." +'a' -- character +'You cant use single quotes for strings.' -- error! + +-- Strings can be concatenated +"Hello " ++ "world!" -- "Hello world!" + +-- A string is a list of characters +"This is a string" !! 0 -- 'T' + + +---------------------------------------------------- +-- Lists and Tuples +---------------------------------------------------- + +-- Every element in a list must have the same type. +-- Two lists that are the same +[1, 2, 3, 4, 5] +[1..5] + +-- You can also have infinite lists in Haskell! +[1..] -- a list of all the natural numbers + +-- Infinite lists work because Haskell has "lazy evaluation". This means +-- that Haskell only evaluates things when it needs to. So you can ask for +-- the 1000th element of your list and Haskell will give it to you: + +[1..] !! 999 -- 1000 + +-- And now Haskell has evaluated elements 1 - 1000 of this list...but the +-- rest of the elements of this "infinite" list don't exist yet! Haskell won't +-- actually evaluate them until it needs to. + +- joining two lists +[1..5] ++ [6..10] + +-- adding to the head of a list +0:[1..5] -- [0, 1, 2, 3, 4, 5] + +-- indexing into a list +[0..] !! 5 -- 5 + +-- more list operations +head [1..5] -- 1 +tail [1..5] -- [2, 3, 4, 5] +init [1..5] -- [1, 2, 3, 4] +last [1..5] -- 5 + +-- list comprehensions +[x*2 | x <- [1..5]] -- [2, 4, 6, 8, 10] + +-- with a conditional +[x*2 | x <- [1..5], x*2 > 4] -- [6, 8, 10] + +-- Every element in a tuple can be a different type, but a tuple has a +-- fixed length. +-- A tuple: +("haskell", 1) + +-- accessing elements of a tuple +fst ("haskell", 1) -- "haskell" +snd ("haskell", 1) -- 1 + +---------------------------------------------------- +-- 3. Functions +---------------------------------------------------- +-- A simple function that takes two variables +add a b = a + b + +-- Note that if you are using ghci (the Haskell interpreter) +-- You'll need to use `let`, i.e. +-- let add a b = a + b + +-- Using the function +add 1 2 -- 3 + +-- You can also put the function name between the two arguments +-- with backticks: +1 `add` 2 -- 3 + +-- You can also define functions that have no characters! This lets +-- you define your own operators! Here's an operator that does +-- integer division +(//) a b = a `div` b +35 // 4 -- 8 + +-- Guards: an easy way to do branching in functions +fib x + | x < 2 = x + | otherwise = fib (x - 1) + fib (x - 2) + +-- Pattern matching is similar. Here we have given three different +-- definitions for fib. Haskell will automatically call the first +-- function that matches the pattern of the value. +fib 1 = 1 +fib 2 = 2 +fib x = fib (x - 1) + fib (x - 2) + +-- Pattern matching on tuples: +foo (x, y) = (x + 1, y + 2) + +-- Pattern matching on arrays. Here `x` is the first element +-- in the array, and `xs` is the rest of the array. We can write +-- our own map function: +myMap func [x] = [func x] +myMap func (x:xs) = func x:(myMap func xs) + +-- Anonymous functions are created with a backslash followed by +-- all the arguments. +myMap (\x -> x + 2) [1..5] -- [3, 4, 5, 6, 7] + +-- using fold (called `inject` in some languages) with an anonymous +-- function. foldl1 means fold left, and use the first value in the +-- array as the initial value for the accumulator. +foldl1 (\acc x -> acc + x) [1..5] -- 15 + +---------------------------------------------------- +-- 4. More functions +---------------------------------------------------- + +-- currying: if you don't pass in all the arguments to a function, +-- it gets "curried". That means it returns a function that takes the +-- rest of the arguments. + +add a b = a + b +foo = add 10 -- foo is now a function that takes a number and adds 10 to it +foo 5 -- 15 + +-- Another way to write the same thing +foo = (+10) +foo 5 -- 15 + +-- function composition +-- the (.) function chains functions together. +-- For example, here foo is a function that takes a value. It adds 10 to it, +-- multiplies the result of that by 5, and then returns the final value. +foo = (*5) . (+10) + +-- (5 + 10) * 5 = 75 +foo 5 -- 75 + +-- fixing precedence +-- Haskell has another function called `$`. This changes the precedence +-- so that everything to the left of it gets computed first and then applied +-- to everything on the right. You can use `.` and `$` to get rid of a lot +-- of parentheses: + +-- before +(even (fib 7)) -- true + +-- after +even . fib $ 7 -- true + +---------------------------------------------------- +-- 5. Type signatures +---------------------------------------------------- + +-- Haskell has a very strong type system, and everything has a type signature. + +-- Some basic types: +5 :: Integer +"hello" :: String +True :: Bool + +-- Functions have types too. +-- `not` takes a boolean and returns a boolean: +-- not :: Bool -> Bool + +-- Here's a function that takes two arguments: +-- add :: Integer -> Integer -> Integer + +-- When you define a value, it's good practice to write it's type above it: +double :: Integer -> Integer +double x = x * 2 + +---------------------------------------------------- +-- 6. Control Flow and If Statements +---------------------------------------------------- + +-- if statements +haskell = if 1 == 1 then "awesome" else "awful" -- haskell = "awesome" + +-- if statements can be on multiple lines too, indentation is important +haskell = if 1 == 1 + then "awesome" + else "awful" + +-- case statements: Here's how you could parse command line arguments +case args of + "help" -> printHelp + "start" -> startProgram + _ -> putStrLn "bad args" + +-- Haskell doesn't have loops because it uses recursion instead. +-- map a function over every element in an array + +map (*2) [1..5] -- [2, 4, 6, 8, 10] + +-- you can make a for function using map +for array func = map func array + +-- and then use it +for [0..5] $ \i -> show i + +-- we could've written that like this too: +for [0..5] show + +---------------------------------------------------- +-- 7. Data Types +---------------------------------------------------- + +-- Here's how you make your own data type in Haskell + +data Color = Red | Blue | Green + +-- Now you can use it in a function: + +say :: Color -> IO String +say Red = putStrLn "You are Red!" +say Blue = putStrLn "You are Blue!" +say Green = putStrLn "You are Green!" + +-- Your data types can have parameters too: + +data Maybe a = Nothing | Just a + +-- These are all of type Maybe +Nothing +Just "hello" +Just 1 + +---------------------------------------------------- +-- 8. Haskell IO +---------------------------------------------------- + +-- While IO can't be explained fully without explaining monads, +-- it is not hard to explain enough to get going. + +-- An `IO a` value is an IO action: you can chain them with do blocks +action :: IO String +action = do + putStrLn "This is a line. Duh" + input <- getLine -- this gets a line and gives it the name "input" + input2 <- getLine + return (input1 ++ "\n" ++ input2) -- This is the result of the whole action + +-- This didn't actually do anything. When a haskell program is executed +-- an IO action called "main" is read and interpreted. + +main = do + putStrLn "Our first program. How exciting!" + result <- action -- our defined action is just like the default ones + putStrLn result + putStrLn "This was all, folks!" + +-- Haskell does IO through a monad because this allows it to be a purely +-- functional language. Our `action` function had a type signature of `IO String`. +-- In general any function that interacts with the outside world (i.e. does IO) +-- gets marked as `IO` in it's type signature. This lets us reason about what +-- functions are "pure" (don't interact with the outside world or modify state) +-- and what functions aren't. + +-- This is a powerful feature, because it's easy to run pure functions concurrently +-- so concurrency in Haskell is very easy. + + +---------------------------------------------------- +-- 9. The Haskell REPL +---------------------------------------------------- + +-- Start the repl by typing `ghci`. +-- Now you can type in Haskell code. Any new values +-- need to be created with `let`: + +let foo = 5 + +-- You can see the type of any value with `:t`: + +>:t foo +foo :: Integer +``` + +There's a lot more to Haskell, including typeclasses and monads. These are the big ideas that make Haskell such fun to code in. I'll leave you with one final Haskell example: an implementation of quicksort in Haskell: + +```haskell +qsort [] = [] +qsort (p:xs) = qsort lesser ++ [p] ++ qsort greater + where lesser = filter (< p) xs + greater = filter (>= p) xs +``` + +Haskell is easy to install. Get it [here](http://www.haskell.org/platform/). + +You can find a much gentler introduction from the excellent [Learn you a Haskell](http://learnyouahaskell.com/) + diff --git a/java.html.markdown b/java.html.markdown new file mode 100644 index 00000000..3208971d --- /dev/null +++ b/java.html.markdown @@ -0,0 +1,349 @@ +--- + +language: java + +author: Jake Prather + +author_url: http://github.com/JakeHP + +filename: learnjava.java + +--- + +Java is a general-purpose, concurrent, class-based, object-oriented computer programming language. +[Read more here.](http://docs.oracle.com/javase/tutorial/java/index.html) + +```java +// Single-line comments start with // +/* +Multi-line comments look like this. +*/ + +// Import Packages +import java.util.ArrayList; +// Import all "sub-packages" +import java.lang.Math.*; + +// Inside of the learnjava class, is your program's +// starting point. The main method. +public class learnjava +{ + //main method + public static void main (String[] args) + { + +System.out.println("->Printing"); +// Printing, and forcing a new line on next print, use println() +System.out.println("Hello World!"); +System.out.println("Integer: "+10+" Double: "+3.14+ " Boolean: "+true); +// Printing, without forcing a new line on next print, use print() +System.out.print("Hello World - "); +System.out.print("Integer: "+10+" Double: "+3.14+ " Boolean: "+true); + +/////////////////////////////////////// +// Types +/////////////////////////////////////// +System.out.println("\n\n->Types"); +// Byte - 8-bit signed two's complement integer +// (-128 <= byte <= 127) +byte fooByte = 100; + +// Short - 16-bit signed two's complement integer +// (-32,768 <= short <= 32,767) +short fooShort = 10000; + +// Integer - 32-bit signed two's complement integer +// (-2,147,483,648 <= int <= 2,147,483,647) +int fooInt = 1; + +// Long - 64-bit signed two's complement integer +// (-9,223,372,036,854,775,808 <= long <= 9,223,372,036,854,775,807) +long fooLong = 100000L; + +// (Java has no unsigned types) + +// Float - Single-precision 32-bit IEEE 754 Floating Point +float fooFloat = 234.5f; + +// Double - Double-precision 64-bit IEEE 754 Floating Point +double fooDouble = 123.4; + +// Boolean - True & False +boolean fooBoolean = true; +boolean barBoolean = false; + +// Char - A single 16-bit Unicode character +char fooChar = 'A'; + +// Make a variable a constant +final int HOURS_I_WORK_PER_WEEK = 9001; + +// Strings +String fooString = "My String Is Here!"; +// \n is an escaped character that starts a new line +String barString = "Printing on a new line?\nNo Problem!"; +System.out.println(fooString); +System.out.println(barString); + +// Arrays +//The array size must be decided upon declaration +//The format for declaring an array is follows: +//<datatype> [] <var name> = new <datatype>[<array size>]; +int [] intArray = new int[10]; +String [] stringArray = new String[1]; +boolean [] booleanArray = new boolean[100]; + +// Indexing an array - Accessing an element +System.out.println("intArray @ 0: "+intArray[0]); + +// Arrays are mutable; it's just memory! +intArray[1] = 1; +System.out.println("intArray @ 1: "+intArray[1]); // => 1 +intArray[1] = 2; +System.out.println("intArray @ 1: "+intArray[1]); // => 2 + +// Others to check out +// ArrayLists - Like arrays except more functionality is offered, +// and the size is mutable +// LinkedLists +// Maps +// HashMaps + +/////////////////////////////////////// +// Operators +/////////////////////////////////////// +System.out.println("\n->Operators"); + +int i1 = 1, i2 = 2; // Shorthand for multiple declarations + +// Arithmetic is straightforward +System.out.println("1+2 = "+(i1 + i2)); // => 3 +System.out.println("1+2 = "+(i2 - i1)); // => 1 +System.out.println("1+2 = "+(i2 * i1)); // => 2 +System.out.println("1+2 = "+(i1 / i2)); // => 0 (0.5, but truncated towards 0) + +// Modulo +System.out.println("11%3 = "+(11 % 3)); // => 2 + +// Comparison operators +System.out.println("3 == 2? "+(3 == 2)); // => 0 (false) +System.out.println("3 != 2? "+(3 != 2)); // => 1 (true) +System.out.println("3 > 2? "+(3 > 2)); // => 1 +System.out.println("3 < 2? "+(3 < 2)); // => 0 +System.out.println("2 <= 2? "+(2 <= 2)); // => 1 +System.out.println("2 >= 2? "+(2 >= 2)); // => 1 + +// Bitwise operators! +/* +~ Unary bitwise complement +<< Signed left shift +>> Signed right shift +>>> Unsigned right shift +& Bitwise AND +^ Bitwise exclusive OR +| Bitwise inclusive OR +*/ + +// Incrementations +int i=0; +System.out.println("\n->Inc/Dec-rementation"); +System.out.println(i++); //i = 1. Post-Incrementation +System.out.println(++i); //i = 2. Pre-Incrementation +System.out.println(i--); //i = 1. Post-Decrementation +System.out.println(--i); //i = 0. Pre-Decrementation + +/////////////////////////////////////// +// Control Structures +/////////////////////////////////////// +System.out.println("\n->Control Structures"); +if (false){ + System.out.println("I never run"); +}else if (false) { + System.out.println("I am also never run"); +} else { + System.out.println("I print"); +} + +// While loop +int fooWhile = 0; +while(fooWhile < 100) +{ + //System.out.println(fooWhile); + //Increment the counter + //Iterated 99 times, fooWhile 0->99 + fooWhile++; +} +System.out.println("fooWhile Value: "+fooWhile); + +// Do While Loop +int fooDoWhile = 0; +do +{ + //System.out.println(fooDoWhile); + //Increment the counter + //Iterated 99 times, fooDoWhile 0->99 + fooDoWhile++; +}while(fooDoWhile < 100); +System.out.println("fooDoWhile Value: "+fooDoWhile); + +// For Loop +int fooFor; +//for loop structure => for(<start_statement>;<conditional>;<step>) +for(fooFor=0;fooFor<100;fooFor++){ + //System.out.println(fooFor); + //Iterated 99 times, fooFor 0->99 +} +System.out.println("fooFor Value: "+fooFor); + +// Switch Case +int month = 8; +String monthString; +switch (month){ + case 1: monthString = "January"; + break; + case 2: monthString = "February"; + break; + case 3: monthString = "March"; + break; + case 4: monthString = "April"; + break; + case 5: monthString = "May"; + break; + case 6: monthString = "June"; + break; + case 7: monthString = "July"; + break; + case 8: monthString = "August"; + break; + case 9: monthString = "September"; + break; + case 10: monthString = "October"; + break; + case 11: monthString = "November"; + break; + case 12: monthString = "December"; + break; + default: monthString = "Invalid month"; + break; +} +System.out.println("Switch Case Result: "+monthString); + +/////////////////////////////////////// +// Converting Data Types And Typcasting +/////////////////////////////////////// + +// Converting data + +// Convert String To Integer +Integer.parseInt("123");//returns an integer version of "123" + +// Convert Integer To String +Integer.toString(123);//returns a string version of 123 + +// For other conversions check out the following classes: +// Double +// Long +// String + +// Typecsating +// You can also cast java objects, there's a lot of details and +// deals with some more intermediate concepts. +// Feel free to check it out here: http://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html + + +/////////////////////////////////////// +// Classes And Functions +/////////////////////////////////////// + + // Read about the class, and function syntax before + // reading this. + System.out.println("\n->Classes & Functions"); + // Call bicycle's constructor + Bicycle trek = new Bicycle(); + // Manipulate your object + trek.speedUp(3); + trek.setCadence(100); + System.out.println("trek info: "+trek.toString()); + + // Classes Syntax: + // <public/private/protected> class <class name>{ + // //data fields, constructors, functions all inside + // } + // Function Syntax: + // <public/private/protected> <return type> <function name>(<args>) + // Here is a quick rundown on access level modifiers (public, private, etc.) + // http://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html + +// This bracket ends the main method +} + // The static field is only required because this class + // is nested inside of the learnjava.java class. + public static class Bicycle { + + // Bicycle's Fields/Variables + public int cadence; + public int gear; + public int speed; + + // Constructors are a way of creating classes + // This is a default constructor + public Bicycle(){ + gear = 1; + cadence = 50; + speed = 5; + } + + // This is a specified constructor (it contains arguments) + public Bicycle(int startCadence, int startSpeed, int startGear) { + gear = startGear; + cadence = startCadence; + speed = startSpeed; + } + + // the Bicycle class has + // four functions/methods + public void setCadence(int newValue) { + cadence = newValue; + } + + public void setGear(int newValue) { + gear = newValue; + } + + public void applyBrake(int decrement) { + speed -= decrement; + } + + public void speedUp(int increment) { + speed += increment; + } + + public String toString(){ + return "gear: "+Integer.toString(gear)+ + " cadence: "+Integer.toString(cadence)+ + " speed: "+Integer.toString(speed); + } + // bracket to close nested Bicycle class + } +// bracket to close learnjava.java +} + +``` + +## Further Reading + +Other Topics To Research: + +* [Inheritance](http://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html) + +* [Polymorphism](http://docs.oracle.com/javase/tutorial/java/IandI/polymorphism.html) + +* [Abstraction](http://docs.oracle.com/javase/tutorial/java/IandI/abstract.html) + +* [Exceptions](http://docs.oracle.com/javase/tutorial/essential/exceptions/index.html) + +* [Interfaces](http://docs.oracle.com/javase/tutorial/java/IandI/createinterface.html) + +* [Generics](http://docs.oracle.com/javase/tutorial/java/generics/index.html) + +* The links provided are just to get an understanding of the topic, feel free to google and find specific examples diff --git a/lua.html.markdown b/lua.html.markdown index 66ebf6bd..4df57a92 100644 --- a/lua.html.markdown +++ b/lua.html.markdown @@ -2,6 +2,7 @@ language: lua author: Tyler Neylon author_url: http://tylerneylon.com/ +filename: learnlua.lua --- ```lua diff --git a/pets.csv b/pets.csv new file mode 100644 index 00000000..0837f473 --- /dev/null +++ b/pets.csv @@ -0,0 +1,4 @@ +name,age,weight,species +"fluffy",3,14,"cat" +"vesuvius",6,23,"fish" +"rex",5,34,"dog" diff --git a/php.html.markdown b/php.html.markdown index 753f6ab1..75bbd214 100644 --- a/php.html.markdown +++ b/php.html.markdown @@ -2,19 +2,16 @@ language: php author: Malcolm Fell author_url: http://emarref.net/ +filename: learnphp.php --- This document describes PHP 5+. -## [Basic Syntax](http://www.php.net/manual/en/language.basic-syntax.php) - -All statements must end with a semi-colon; All PHP code must be between <?php and ?> tags. PHP can also be -configured to respect the [short open tags](http://www.php.net/manual/en/ini.core.php#ini.short-open-tag) <? and ?>. - -## [Comments](http://www.php.net/manual/en/language.basic-syntax.comments.php) - ```php -<?php +<?php // PHP code must be enclosed with <?php ? > tags + +// If your php file only contains PHP code, it is best practise +// to omit the php closing tag. // Two forward slashes start a one-line comment. @@ -24,27 +21,36 @@ configured to respect the [short open tags](http://www.php.net/manual/en/ini.cor Surrounding text in slash-asterisk and asterisk-slash makes it a multi-line comment. */ -``` - -## [Types](http://www.php.net/manual/en/language.types.php) -Types are [weakly typed](http://en.wikipedia.org/wiki/Strong_and_weak_typing) and begin with the $ symbol. -A valid variable name starts with a letter or underscore, followed by any number of letters, numbers, or underscores. +// Use "echo" or "print" to print output +print('Hello '); // Prints "Hello " with no line break -### Scalars +// () are optional for print and echo +echo "World\n"; // Prints "World" with a line break +// (all statements must end with a semicolon) -```php +// Anything outside <?php tags is echoed automatically +?>Hello World Again! <?php + +/************************************ + * Types & Variables + */ + +// Variables begin with the $ symbol. +// A valid variable name starts with a letter or underscore, +// followed by any number of letters, numbers, or underscores. + // Boolean values are case-insensitive -$boolean = true; // or TRUE or True +$boolean = true; // or TRUE or True $boolean = false; // or FALSE or False // Integers -$integer = 1234; // decimal number -$integer = -123; // a negative number -$integer = 0123; // octal number (equivalent to 83 decimal) -$integer = 0x1A; // hexadecimal number (equivalent to 26 decimal) +$int1 = 19; // => 19 +$int2 = -19; // => -19 +$int3 = 019; // => 15 (a leading 0 denotes an octal number) +$int4 = 0x0F; // => 15 (a leading 0x denotes a hex literal) // Floats (aka doubles) $float = 1.234; @@ -52,28 +58,30 @@ $float = 1.2e3; $float = 7E-10; // Arithmetic -$sum = $number + $float; -$difference = $number - $float; -$product = $number * $float; -$quotient = $number / $float; +$sum = 1 + 1; // 2 +$difference = 2 - 1; // 1 +$product = 2 * 2; // 4 +$quotient = 2 / 1; // 2 // Shorthand arithmetic -$number += 1; // Add 1 to $number -$number++; // Add 1 to $number after it is used -++$number; // Add 1 to $number before it is used. -$number /= $float // Divide and assign the quotient to $number +$number = 0; +$number += 1; // Increment $number by 1 +echo $number++; // Prints 1 (increments after evaluation) +echo ++$number; // Prints 3 (increments before evalutation) +$number /= $float; // Divide and assign the quotient to $number // Strings should be enclosed in single quotes; $sgl_quotes = '$String'; // => '$String' // Avoid using double quotes except to embed other variables -$dbl_quotes = "This is a $sgl_quotes." // => 'This is a $String' +$dbl_quotes = "This is a $sgl_quotes."; // => 'This is a $String.' -// Escape special characters with backslash -$escaped = "This contains a \t tab character."; +// Special characters are only escaped in double quotes +$escaped = "This contains a \t tab character."; +$unescaped = 'This just contains a slash and a t: \t'; // Enclose a variable in curly braces if needed -$money = "I have $${integer} in the bank." +$money = "I have $${number} in the bank."; // Since PHP 5.3, nowdocs can be used for uninterpolated multi-liners $nowdoc = <<<'END' @@ -81,35 +89,40 @@ Multi line string END; +// Heredocs will do string interpolation $heredoc = <<<END Multi line $sgl_quotes -END; // Nowdoc syntax is available in PHP 5.3.0 +END; -// Manipulation -$concatenated = $sgl_quotes . $dbl_quotes; -``` +// String concatenation is done with . +echo 'This string ' . 'is concatenated'; -### Compound -```php -<?php +/******************************** + * Arrays + */ -// Arrays -$array = array(1, 2, 3); -$array = [1, 2, 3]; // As of PHP 5.4 -$string = ["One", "Two", "Three"]; -$string[0]; // Holds the value "One"; +// All arrays in PHP are associative arrays (hashmaps), // Associative arrays, known as hashmaps in some languages. -$associative = ["One" => 1, "Two" => 2, "Three" => 3]; -$associative["One"]; // Holds the value 1 -``` -## Output +// Works with all PHP versions +$associative = array('One' => 1, 'Two' => 2, 'Three' => 3); -```php -<?php +// PHP 5.4 introduced a new syntax +$associative = ['One' => 1, 'Two' => 2, 'Three' => 3]; + +echo $associative['One']; // prints 1 + +// List literals implicitly assign integer keys +$array = ['One', 'Two', 'Three']; +echo $array[0]; // => "One" + + +/******************************** + * Output + */ echo('Hello World!'); // Prints Hello World! to stdout. @@ -121,133 +134,129 @@ print('Hello World!'); // The same as echo echo 'Hello World!'; print 'Hello World!'; // So is print -echo 100; -echo $variable; -echo function_result(); +$paragraph = 'paragraph'; + +echo 100; // Echo scalar variables directly +echo $paragraph; // or variables // If short open tags are configured, or your PHP version is // 5.4.0 or greater, you can use the short echo syntax -<?= $variable ?> -``` - -## [Operators](http://www.php.net/manual/en/language.operators.php) - -### Assignment - -```php +?> +<p><?= $paragraph ?></p> <?php $x = 1; $y = 2; -$x = $y; // A now contains the same value sa $y -$x = &$y; -// $x now contains a reference to $y. Changing the value of -// $x will change the value of $y also, and vice-versa. -``` +$x = $y; // $x now contains the same value as $y +$z = &$y; +// $z now contains a reference to $y. Changing the value of +// $z will change the value of $y also, and vice-versa. +// $x will remain unchanged as the original value of $y -### Comparison +echo $x; // => 2 +echo $z; // => 2 +$y = 0; +echo $x; // => 2 +echo $z; // => 0 -```php -<?php + +/******************************** + * Logic + */ +$a = 0; +$b = '0'; +$c = '1'; +$d = '1'; + +// assert throws a warning if its argument is not true // These comparisons will always be true, even if the types aren't the same. -$a == $b // TRUE if $a is equal to $b after type juggling. -$a != $b // TRUE if $a is not equal to $b after type juggling. -$a <> $b // TRUE if $a is not equal to $b after type juggling. -$a < $b // TRUE if $a is strictly less than $b. -$a > $b // TRUE if $a is strictly greater than $b. -$a <= $b // TRUE if $a is less than or equal to $b. -$a >= $b // TRUE if $a is greater than or equal to $b. +assert($a == $b); // equality +assert($c != $a); // inequality +assert($c <> $a); // alternative inequality +assert($a < $c); +assert($c > $b); +assert($a <= $b); +assert($c >= $d); // The following will only be true if the values match and are the same type. -$a === $b // TRUE if $a is equal to $b, and they are of the same type. -$a !== $b // TRUE if $a is not equal to $b, or they are not of the same type. -1 == '1' // TRUE -1 === '1' // FALSE -``` +assert($c === $d); +assert($a !== $d); +assert(1 == '1'); +assert(1 !== '1'); -## [Type Juggling](http://www.php.net/manual/en/language.types.type-juggling.php) - -Variables can be converted between types, depending on their usage. - -```php -<?php +// Variables can be converted between types, depending on their usage. $integer = 1; -echo $integer + $integer; // Outputs 2; +echo $integer + $integer; // => 2 $string = '1'; -echo $string + $string; -// Also outputs 2 because the + operator converts the strings to integers +echo $string + $string; // => 2 (strings are coerced to integers) $string = 'one'; -echo $string + $string; +echo $string + $string; // => 0 // Outputs 0 because the + operator cannot cast the string 'one' to a number -``` -Type casting can be used to treat a variable as another type temporarily by using cast operators in parentheses. +// Type casting can be used to treat a variable as another type -```php -$boolean = (boolean) $integer; // $boolean is true +$boolean = (boolean) 1; // => true $zero = 0; -$boolean = (boolean) $zero; // $boolean is false +$boolean = (boolean) $zero; // => false +// There are also dedicated functions for casting most types $integer = 5; $string = strval($integer); -// There are also dedicated functions for casting most types $var = null; // Null value -``` -## [Control Structures](http://www.php.net/manual/en/language.control-structures.php) -### If Statements +/******************************** + * Control Structures + */ -```php -<?php - -if (/* test */) { - // Do something +if (true) { + print 'I get printed'; } -if (/* test */) { - // Do something +if (false) { + print 'I don\'t'; } else { - // Do something else + print 'I get printed'; } -if (/* test */) { - // Do something -} elseif(/* test2 */) { - // Do something else, only if test2 +if (false) { + print 'Does not get printed'; +} elseif(true) { + print 'Does'; } -if (/* test */) { - // Do something -} elseif(/* test2 */) { - // Do something else, only if test2 +$x = 0; +if ($x === '0') { + print 'Does not print'; +} elseif($x == '1') { + print 'Does not print'; } else { - // Do something default + print 'Does print'; } + +// This alternative syntax is useful for templates: ?> -<?php if (/* test */): ?> +<?php if ($x): ?> This is displayed if the test is truthy. <?php else: ?> This is displayed otherwise. <?php endif; ?> -``` - -### Switch statements -```php <?php -switch ($variable) { - case 'one': - // Do something if $variable == 'one' - break; +// Use switch to save some logic. +switch ($x) { + case '0': + print 'Switch does type coercion'; + break; // You must include a break, or you will fall through + // to cases 'two' and 'three' case 'two': case 'three': // Do something if $variable is either 'two' or 'three' @@ -256,199 +265,231 @@ switch ($variable) { // Do something by default } -``` - -### Loops - -```php -<?php - +// While, do...while and for loops are probably familiar $i = 0; while ($i < 5) { echo $i++; -} +}; // Prints "01234" + +echo "\n"; $i = 0; do { echo $i++; -} while ($i < 5); +} while ($i < 5); // Prints "01234" + +echo "\n"; for ($x = 0; $x < 10; $x++) { - echo $x; // Will echo 0 - 9 -} + echo $x; +} // Prints "0123456789" + +echo "\n"; -$wheels = ["bicycle" => 2, "car" => 4]; +$wheels = ['bicycle' => 2, 'car' => 4]; +// Foreach loops can iterate over arrays +foreach ($wheels as $wheel_count) { + echo $wheel_count; +} // Prints "24" + +echo "\n"; + +// You can iterate over the keys as well as the values foreach ($wheels as $vehicle => $wheel_count) { echo "A $vehicle has $wheel_count wheels"; } -// This loop will stop after outputting 2 +echo "\n"; + $i = 0; while ($i < 5) { - if ($i == 3) { - break; // Exit out of the while loop and continue. + if ($i === 3) { + break; // Exit out of the while loop } echo $i++; -} +} // Prints "012" -// This loop will output everything except 3 -$i = 0; -while ($i < 5) { - if ($i == 3) { +for ($i = 0; $i < 5; $i++) { + if ($i === 3) { continue; // Skip this iteration of the loop } - echo $i++; -} -``` + echo $i; +} // Prints "0124" -## Functions -Functions are created with the ```function``` keyword. - -```php -<?php +/******************************** + * Functions + */ -function my_function($my_arg) { - $my_variable = 1; +// Define a function with "function": +function my_function () { + return 'Hello'; } -// $my_variable and $my_arg cannot be accessed outside of the function -``` - -Functions may be invoked by name. +echo my_function(); // => "Hello" -```php -<?php - -my_function_name(); - -$variable = get_something(); // A function may return a value -``` +// A valid function name starts with a letter or underscore, followed by any +// number of letters, numbers, or underscores. -A valid function name starts with a letter or underscore, followed by any -number of letters, numbers, or underscores. There are three ways to declare functions. - -### [User-defined](http://www.php.net/manual/en/functions.user-defined.php) - -```php -<?php - -function my_function_name ($arg_1, $arg_2) { - // $arg_1 and $arg_2 are required +function add ($x, $y = 1) { // $y is optional and defaults to 1 + $result = $x + $y; + return $result; } -// Functions may be nested to limit scope -function outer_function ($arg_1 = null) { // $arg_1 is optional - function inner_function($arg_2 = 'two') { // $arg_2 will default to 'two' - } -} +echo add(4); // => 5 +echo add(4, 2); // => 6 -// inner_function() does not exist and cannot be called until -// outer_function() is called -``` +// $result is not accessible outside the function +// print $result; // Gives a warning. + +// Since PHP 5.3 you can declare anonymous functions; +$inc = function ($x) { + return $x + 1; +}; -This enables [currying](http://en.wikipedia.org/wiki/Currying) in PHP. +echo $inc(2); // => 3 -```php function foo ($x, $y, $z) { echo "$x - $y - $z"; } +// Functions can return functions function bar ($x, $y) { + // Use 'use' to bring in outside variables return function ($z) use ($x, $y) { foo($x, $y, $z); }; } $bar = bar('A', 'B'); -$bar('C'); -``` +$bar('C'); // Prints "A - B - C" -### [Variable](http://www.php.net/manual/en/functions.variable-functions.php) +// You can call named functions using strings +$function_name = 'add'; +echo $function_name(1, 2); // => 3 +// Useful for programatically determining which function to run. +// Or, use call_user_func(callable $callback [, $parameter [, ... ]]); -```php -<?php - -$function_name = 'my_function_name'; +/******************************** + * Includes + */ -$function_name(); // will execute the my_function_name() function +/* ``` - -### [Anonymous](http://www.php.net/manual/en/functions.anonymous.php) - -Similar to variable functions, functions may be anonymous. - ```php <?php +// PHP within included files must also begin with a PHP open tag. -function my_function($callback) { - $callback('My argument'); -} +include 'my-file.php'; +// The code in my-file.php is now available in the current scope. +// If the file cannot be included (e.g. file not found), a warning is emitted. -my_function(function ($my_argument) { - // do something -}); +include_once 'my-file.php'; +// If the code in my-file.php has been included elsewhere, it will +// not be included again. This prevents multiple class declaration errors -// Closure style -$my_function = function() { - // Do something -}; +require 'my-file.php'; +require_once 'my-file.php'; +// Same as include(), except require() will cause a fatal error if the +// file cannot be included. -$my_function(); -``` +// Contents of my-include.php: +<?php -## [Classes](http://www.php.net/manual/en/language.oop5.php) +return 'Anything you like.'; +// End file -Classes are defined with the ```class``` keyword. +// Includes and requires may also return a value. +$value = include 'my-include.php'; -```php -<?php +// Files are included based on the file path given or, if none is given, +// the include_path configuration directive. If the file isn't found in +// the include_path, include will finally check in the calling script's +// own directory and the current working directory before failing. +/* */ -class MyClass { - const MY_CONST = 'value'; - static $staticVar = 'something'; - public $property = 'value'; // Properties must declare their visibility -} +/******************************** + * Classes + */ -echo MyClass::MY_CONST; // Outputs "value"; +// Classes are defined with the class keyword -final class YouCannotExtendMe { -} -``` +class MyClass +{ + const MY_CONST = 'value'; // A constant -Classes are insantiated with the ```new``` keyword. Functions are referred to as -methods if they belong to a class. + static $staticVar = 'static'; -```php -<?php + // Properties must declare their visibility + public $property = 'public'; + public $instanceProp; + protected $prot = 'protected'; // Accessible from the class and subclasses + private $priv = 'private'; // Accessible within the class only + + // Create a constructor with __construct + public function __construct($instanceProp) { + // Access instance variables with $this + $this->instanceProp = $instanceProp; + } -class MyClass { - function myFunction() { + // Methods are declared as functions inside a class + public function myMethod() + { + print 'MyClass'; } - final function youCannotOverrideMe() { + final function youCannotOverrideMe() + { } - public static function myStaticMethod() { + public static function myStaticMethod() + { + print 'I am static'; } } -$cls = new MyClass(); // The parentheses are optional. +echo MyClass::MY_CONST; // Outputs 'value'; +echo MyClass::$staticVar; // Outputs 'static'; +MyClass::myStaticMethod(); // Outputs 'I am static'; -echo MyClass::$staticVar; // Access to static vars +// Instantiate classes using new +$my_class = new MyClass('An instance property'); +// The parentheses are optional if not passing in an argument. -echo $cls->property; // Access to properties +// Access class members using -> +echo $my_class->property; // => "public" +echo $my_class->instanceProp; // => "An instance property" +$my_class->myMethod(); // => "MyClass" -MyClass::myStaticMethod(); // myStaticMethod cannot be run on $cls -``` -PHP offers some [magic methods](http://www.php.net/manual/en/language.oop5.magic.php) for classes. +// Extend classes using "extends" +class MyOtherClass extends MyClass +{ + function printProtectedProperty() + { + echo $this->prot; + } -```php -<?php + // Override a method + function myMethod() + { + parent::myMethod(); + print ' > MyOtherClass'; + } +} + +$my_other_class = new MyOtherClass('Instance prop'); +$my_other_class->printProtectedProperty(); // => Prints "protected" +$my_other_class->myMethod(); // Prints "MyClass > MyOtherClass" + +final class YouCannotExtendMe +{ +} -class MyClass { +// You can use "magic methods" to create getters and setters +class MyMapClass +{ private $property; public function __get($key) @@ -462,16 +503,13 @@ class MyClass { } } -$x = new MyClass(); +$x = new MyMapClass(); echo $x->property; // Will use the __get() method $x->property = 'Something'; // Will use the __set() method -``` - -Classes can be abstract (using the ```abstract``` keyword), extend other classes (using the ```extends``` keyword) and -implement interfaces (using the ```implements``` keyword). An interface is declared with the ```interface``` keyword. -```php -<?php +// Classes can be abstract (using the abstract keyword) or +// implement interfaces (using the implements keyword). +// An interface is declared with the interface keyword. interface InterfaceOne { @@ -480,90 +518,112 @@ interface InterfaceOne interface InterfaceTwo { - public function doSomething(); + public function doSomethingElse(); } abstract class MyAbstractClass implements InterfaceOne { + public $x = 'doSomething'; } -class MyClass extends MyAbstractClass implements InterfaceTwo +class MyConcreteClass extends MyAbstractClass implements InterfaceTwo { + public function doSomething() + { + echo $x; + } + + public function doSomethingElse() + { + echo 'doSomethingElse'; + } } + // Classes can implement more than one interface class SomeOtherClass implements InterfaceOne, InterfaceTwo { + public function doSomething() + { + echo 'doSomething'; + } + + public function doSomethingElse() + { + echo 'doSomethingElse'; + } } -``` -### [Namespaces](http://www.php.net/manual/en/language.namespaces.rationale.php) -By default, classes exist in the global namespace, and can be explicitly called with a backslash. +/******************************** + * Traits + */ +// Traits are available from PHP 5.4.0 and are declared using "trait" + +trait MyTrait +{ + public function myTraitMethod() + { + print 'I have MyTrait'; + } +} + +class MyTraitfulClass +{ + use MyTrait; +} + +$cls = new MyTraitfulClass(); +$cls->myTraitMethod(); // Prints "I have MyTrait" + + +/******************************** + * Namespaces + */ + +// This section is separate, because a namespace declaration +// must be the first statement in a file. Let's pretend that is not the case + +/* +``` ```php <?php +// By default, classes exist in the global namespace, and can +// be explicitly called with a backslash. + $cls = new \MyClass(); -``` -```php -<?php + +// Set the namespace for a file namespace My\Namespace; class MyClass { } +// (from another file) $cls = new My\Namespace\MyClass; -``` - -Or from within another namespace. - -```php -<?php +//Or from within another namespace. namespace My\Other\Namespace; use My\Namespace\MyClass; $cls = new MyClass(); -``` -Or you can alias the namespace; - -```php -<?php +// Or you can alias the namespace; namespace My\Other\Namespace; use My\Namespace as SomeOtherNamespace; $cls = new SomeOtherNamespace\MyClass(); -``` - -### [Traits](http://www.php.net/manual/en/language.oop5.traits.php) - -Traits are available since PHP 5.4.0 and are declared using the ```trait``` keyword. - -```php -<?php -trait MyTrait { - public function myTraitMethod() - { - // Do something - } -} - -class MyClass -{ - use MyTrait; -} +*/ -$cls = new MyClass(); -$cls->myTraitMethod(); ``` ## More Information @@ -573,3 +633,5 @@ Visit the [official PHP documentation](http://www.php.net/manual/) for reference If you're interested in up-to-date best practices, visit [PHP The Right Way](http://www.phptherightway.com/). If you're coming from a language with good package management, check out [Composer](http://getcomposer.org/). + +For common standards, visit the PHP Framework Interoperability Group's [PSR standards](https://github.com/php-fig/fig-standards). diff --git a/python.html.markdown b/python.html.markdown index 2c08e73e..19e2aebe 100644 --- a/python.html.markdown +++ b/python.html.markdown @@ -2,19 +2,23 @@ language: python author: Louie Dinh author_url: http://ldinh.ca +filename: learnpython.py --- Python was created by Guido Van Rossum in the early 90's. It is now one of the most popular languages in existence. I fell in love with Python for it's syntactic clarity. It's basically executable pseudocode. +Feedback would be highly appreciated! You can reach me at [@louiedinh](http://twitter.com/louiedinh) or louiedinh [at] [google's email service] + Note: This article applies to Python 2.7 specifically, but should be applicable to Python 2.x. Look for another tour of Python 3 soon! ```python # Single line comments start with a hash. -""" Multiline comments can we written - using three "'s +""" Multiline strings can be written + using three "'s, and are often used + as comments """ #################################################### @@ -32,11 +36,11 @@ to Python 2.x. Look for another tour of Python 3 soon! # Division is a bit tricky. It is integer division and floors the results # automatically. -11 / 4 #=> 2 +5 / 2 #=> 2 # To fix division we need to learn about floats. 2.0 # This is a float -5.0 / 2.0 #=> 2.5 ahhh...much better +11.0 / 4.0 #=> 2.75 ahhh...much better # Enforce precedence with parentheses (1 + 3) * 2 #=> 8 @@ -77,6 +81,15 @@ not False #=> True # A string can be treated like a list of characters "This is a string"[0] #=> 'T' +# % can be used to format strings, like this: +"%s can be %s" % ("strings", "interpolated") + +# A newer way to format strings is the format method. +# This method is the preferred way +"{0} can be {1}".format("strings", "formatted") +# You can use keywords if you don't want to count. +"{name} wants to eat {food}".format(name="Bob", food="lasagna") + # None is an object None #=> None @@ -93,16 +106,12 @@ print "I'm Python. Nice to meet you!" some_var = 5 # Convention is to use lower_case_with_underscores some_var #=> 5 -# Accessing a previously unassigned variable is an exception -try: - some_other_var -except NameError: - print "Raises a name error" +# Accessing a previously unassigned variable is an exception. +# See Control Flow to learn more about exception handling. +some_other_var # Raises a name error -# Conditional Expressions can be used when assigning -some_var = a if a > b else b -# If a is greater than b, then a is assigned to some_var. -# Otherwise b is assigned to some_var. +# if can be used as an expression +"yahoo!" if 1 > 2 else 2 #=> "yahoo!" # Lists store sequences li = [] @@ -125,18 +134,15 @@ li[0] #=> 1 li[-1] #=> 3 # Looking out of bounds is an IndexError -try: - li[4] # Raises an IndexError -except IndexError: - print "Raises an IndexError" +li[4] # Raises an IndexError # You can look at ranges with slice syntax. # (It's a closed/open range for you mathy types.) li[1:3] #=> [2, 4] # Omit the beginning -li[:3] #=> [1, 2, 4] -# Omit the end li[2:] #=> [4, 3] +# Omit the end +li[:3] #=> [1, 2, 4] # Remove arbitrary elements from a list with del del li[2] # li is now [1, 2, 3] @@ -156,10 +162,7 @@ len(li) #=> 6 # Tuples are like lists but are immutable. tup = (1, 2, 3) tup[0] #=> 1 -try: - tup[0] = 3 # Raises a TypeError -except TypeError: - print "Tuples cannot be mutated." +tup[0] = 3 # Raises a TypeError # You can do all those list thingies on tuples too len(tup) #=> 3 @@ -167,7 +170,7 @@ tup + (4, 5, 6) #=> (1, 2, 3, 4, 5, 6) tup[:2] #=> (1, 2) 2 in tup #=> True -# However, you can unpack tuples into variables +# You can unpack tuples into variables a, b, c = (1, 2, 3) # a is now 1, b is now 2 and c is now 3 # Tuples are created by default if you leave out the parentheses d, e, f = 4, 5, 6 @@ -196,13 +199,12 @@ filled_dict.values() #=> [3, 2, 1] "one" in filled_dict #=> True 1 in filled_dict #=> False -# Trying to look up a non-existing key will raise a KeyError -filled_dict["four"] #=> KeyError + # Looking up a non-existing key is a KeyError +filled_dict["four"] # KeyError # Use get method to avoid the KeyError filled_dict.get("one") #=> 1 filled_dict.get("four") #=> None - # The get method supports a default argument when the value is missing filled_dict.get("one", 4) #=> 1 filled_dict.get("four", 4) #=> 4 @@ -215,18 +217,23 @@ filled_dict.setdefault("five", 6) #filled_dict["five"] is still 5 # Sets store ... well sets empty_set = set() # Initialize a set with a bunch of values -filled_set = set([1,2,2,3,4]) # filled_set is now set([1, 2, 3, 4]) +some_set = set([1,2,2,3,4]) # filled_set is now set([1, 2, 3, 4]) + +# Since Python 2.7, {} can be used to declare a set +filled_set = {1, 2, 2, 3, 4} # => {1 2 3 4} # Add more items to a set -filled_set.add(5) # filled_set is now set([1, 2, 3, 4, 5]) +filled_set.add(5) # filled_set is now {1, 2, 3, 4, 5} # Do set intersection with & -other_set = set([3, 4, 5 ,6]) -filled_set & other_set #=> set([3, 4, 5]) +other_set = {3, 4, 5, 6} +filled_set & other_set #=> {3, 4, 5} + # Do set union with | -filled_set | other_set #=> set([1, 2, 3, 4, 5, 6]) +filled_set | other_set #=> {1, 2, 3, 4, 5, 6} + # Do set difference with - -set([1,2,3,4]) - set([2,3,5]) #=> set([1, 4]) +{1,2,3,4} - {2,3,5} #=> {1, 4} # Check for existence in a set with in 2 in filled_set #=> True @@ -240,7 +247,7 @@ set([1,2,3,4]) - set([2,3,5]) #=> set([1, 4]) # Let's just make a variable some_var = 5 -# Here is an if statement. INDENTATION IS SIGNIFICANT IN PYTHON! +# Here is an if statement. Indentation is significant in python! # prints "some var is smaller than 10" if some_var > 10: print "some_var is totally bigger than 10." @@ -320,16 +327,17 @@ def all_the_args(*args, **kwargs): print kwargs """ all_the_args(1, 2, a=3, b=4) prints: - [1, 2] + (1, 2) {"a": 3, "b": 4} """ -# You can also use * and ** when calling a function +# When calling functions, you can do the opposite of varargs/kwargs! +# Use * to expand tuples and use ** to expand kwargs. args = (1, 2, 3, 4) kwargs = {"a": 3, "b": 4} -foo(*args) # equivalent to foo(1, 2, 3, 4) -foo(**kwargs) # equivalent to foo(a=3, b=4) -foo(*args, **kwargs) # equivalent to foo(1, 2, 3, 4, a=3, b=4) +all_the_args(*args) # equivalent to foo(1, 2, 3, 4) +all_the_args(**kwargs) # equivalent to foo(a=3, b=4) +all_the_args(*args, **kwargs) # equivalent to foo(1, 2, 3, 4, a=3, b=4) # Python has first class functions def create_adder(x): @@ -401,3 +409,11 @@ j.get_species() #=> "H. neanderthalensis" Human.grunt() #=> "*grunt*" ``` +## Further Reading + +Still up for more? Try: + +* [Learn Python The Hard Way](http://learnpythonthehardway.org/book/) +* [Dive Into Python](http://www.diveintopython.net/) +* [The Official Docs](http://docs.python.org/2.6/) +* [Hitchhiker's Guide to Python](http://docs.python-guide.org/en/latest/) diff --git a/r.html.markdown b/r.html.markdown new file mode 100644 index 00000000..f68ede0e --- /dev/null +++ b/r.html.markdown @@ -0,0 +1,328 @@ +--- +language: R +author: e99n09 +author_url: http://github.com/e99n09 +filename: learnr.r +--- + +R is a statistical computing language. + +```python + +# Comments start with hashtags. + +# You can't make a multi-line comment per se, +# but you can stack multiple comments like so. + +# Protip: hit COMMAND-ENTER to execute a line + +######################### +# The absolute basics +######################### + +# NUMERICS + +# We've got numbers! Behold the "numeric" class +5 # => [1] 5 +class(5) # => [1] "numeric" +# Try ?class for more information on the class() function +# In fact, you can look up the documentation on just about anything with ? + +# Numerics are like doubles. There's no such thing as integers +5 == 5.0 # => [1] TRUE +# Because R doesn't distinguish between integers and doubles, +# R shows the "integer" form instead of the equivalent "double" form +# whenever it's convenient: +5.0 # => [1] 5 + +# All the normal operations! +10 + 66 # => [1] 76 +53.2 - 4 # => [1] 49.2 +3.37 * 5.4 # => [1] 18.198 +2 * 2.0 # => [1] 4 +3 / 4 # => [1] 0.75 +2.0 / 2 # => [1] 1 +3 %% 2 # => [1] 1 +4 %% 2 # => [1] 0 + +# Finally, we've got not-a-numbers! They're numerics too +class(NaN) # => [1] "numeric" + +# CHARACTERS + +# We've (sort of) got strings! Behold the "character" class +"plugh" # => [1] "plugh" +class("plugh") # "character" +# There's no difference between strings and characters in R + +# LOGICALS + +# We've got booleans! Behold the "logical" class +class(TRUE) # => [1] "logical" +class(FALSE) # => [1] "logical" +# Behavior is normal +TRUE == TRUE # => [1] TRUE +TRUE == FALSE # => [1] FALSE +FALSE != FALSE # => [1] FALSE +FALSE != TRUE # => [1] TRUE +# Missing data (NA) is logical, too +class(NA) # => [1] "logical" + +# FACTORS + +# The factor class is for categorical data +# It has an attribute called levels that describes all the possible categories +factor("dog") +# => +# [1] dog +# Levels: dog +# (This will make more sense once we start talking about vectors) + +# VARIABLES + +# Lots of way to assign stuff +x = 5 # this is possible +y <- "1" # this is preferred +TRUE -> z # this works but is weird + +# We can use coerce variables to different classes +as.numeric(y) # => [1] 1 +as.character(x) # => [1] "5" + +# LOOPS + +# We've got for loops +for (i in 1:4) { + print(i) +} + +# We've got while loops +a <- 10 +while (a > 4) { + cat(a, "...", sep = "") + a <- a - 1 +} + +# Keep in mind that for and while loops run slowly in R +# Operations on entire vectors (i.e. a whole row, a whole column) +# or apply()-type functions (we'll discuss later) are preferred + +# FUNCTIONS + +# Defined like so: +myFunc <- function(x) { + x <- x * 4 + x <- x - 1 + return(x) +} + +# Called like any other R function: +myFunc(5) # => [1] 19 + +######################### +# Fun with data: vectors, matrices, data frames, and arrays +######################### + +# ONE-DIMENSIONAL + +# You can vectorize anything, so long as all components have the same type +vec <- c(4, 5, 6, 7) +vec # => [1] 4 5 6 7 +# The class of a vector is the class of its components +class(vec) # => [1] "numeric" +# If you vectorize items of different classes, weird coersions happen +c(TRUE, 4) # => [1] 1 4 +c("dog", TRUE, 4) # => [1] "dog" "TRUE" "4" + +# We ask for specific components like so (R starts counting from 1) +vec[1] # => [1] 4 +# We can also search for the indices of specific components +which(vec %% 2 == 0) +# If an index "goes over" you'll get NA: +vec[6] # => [1] NA + +# You can perform operations on entire vectors or subsets of vectors +vec * 4 # => [1] 16 20 24 28 +vec[2:3] * 5 # => [1] 25 30 + +# TWO-DIMENSIONAL (ALL ONE CLASS) + +# You can make a matrix out of entries all of the same type like so: +mat <- matrix(nrow = 3, ncol = 2, c(1,2,3,4,5,6)) +mat +# => +# [,1] [,2] +# [1,] 1 4 +# [2,] 2 5 +# [3,] 3 6 +# Unlike a vector, the class of a matrix is "matrix", no matter what's in it +class(mat) # => "matrix" +# Ask for the first row +mat[1,] # => [1] 1 4 +# Perform operation on the first column +3 * mat[,1] # => [1] 3 6 9 +# Ask for a specific cell +mat[3,2] # => [1] 6 +# Transpose the whole matrix +t(mat) +# => +# [,1] [,2] [,3] +# [1,] 1 2 3 +# [2,] 4 5 6 + +# cbind() sticks vectors together column-wise to make a matrix +mat2 <- cbind(1:4, c("dog", "cat", "bird", "dog")) +mat2 +# => +# [,1] [,2] +# [1,] "1" "dog" +# [2,] "2" "cat" +# [3,] "3" "bird" +# [4,] "4" "dog" +class(mat2) # => [1] matrix +# Again, note what happened! +# Because matrices must contain entries all of the same class, +# everything got converted to the character class +c(class(mat2[,1]), class(mat2[,2])) + +# rbind() sticks vectors together row-wise to make a matrix +mat3 <- rbind(c(1,2,4,5), c(6,7,0,4)) +mat3 +# => +# [,1] [,2] [,3] [,4] +# [1,] 1 2 4 5 +# [2,] 6 7 0 4 +# Aah, everything of the same class. No coersions. Much better. + +# TWO-DIMENSIONAL (DIFFERENT CLASSES) + +# For columns of different classes, use the data frame +dat <- data.frame(c(5,2,1,4), c("dog", "cat", "bird", "dog")) +names(dat) <- c("number", "species") # name the columns +class(dat) # => [1] "data.frame" +dat +# => +# number species +# 1 5 dog +# 2 2 cat +# 3 1 bird +# 4 4 dog +class(dat$number) # => [1] "numeric" +class(dat[,2]) # => [1] "factor" +# The data.frame() function converts character vectors to factor vectors + +# There are many twisty ways to subset data frames, all subtly unalike +dat$number # => [1] 5 2 1 4 +dat[,1] # => [1] 5 2 1 4 +dat[,"number"] # => [1] 5 2 1 4 + +# MULTI-DIMENSIONAL (ALL OF ONE CLASS) + +# Arrays creates n-dimensional tables +# You can make a two-dimensional table (sort of like a matrix) +array(c(c(1,2,4,5),c(8,9,3,6)), dim=c(2,4)) +# => +# [,1] [,2] [,3] [,4] +# [1,] 1 4 8 3 +# [2,] 2 5 9 6 +# You can use array to make three-dimensional matrices too +array(c(c(c(2,300,4),c(8,9,0)),c(c(5,60,0),c(66,7,847))), dim=c(3,2,2)) +# => +# , , 1 +# +# [,1] [,2] +# [1,] 1 4 +# [2,] 2 5 +# +# , , 2 +# +# [,1] [,2] +# [1,] 8 1 +# [2,] 9 2 + +# LISTS (MULTI-DIMENSIONAL, POSSIBLY RAGGED, OF DIFFERENT TYPES) + +# Finally, R has lists (of vectors) +list1 <- list(time = 1:40, price = c(rnorm(40,.5*list1$time,4))) # random +list1 + +# You can get items in the list like so +list1$time +# You can subset list items like vectors +list1$price[4] + +######################### +# The apply() family of functions +######################### + +# Remember mat? +mat +# => +# [,1] [,2] +# [1,] 1 4 +# [2,] 2 5 +# [3,] 3 6 +# Use apply(X, MARGIN, FUN) to apply function FUN to a matrix X +# over rows (MAR = 1) or columns (MAR = 2) +# That is, R does FUN to each row (or column) of X, much faster than a +# for or while loop would do +apply(mat, MAR = 2, myFunc) +# => +# [,1] [,2] +# [1,] 3 15 +# [2,] 7 19 +# [3,] 11 23 +# Other functions: ?lapply, ?sapply +# Don't feel too intimiated; everyone agrees they are rather confusing + +# The plyr package aims to replace (and improve upon!) the *apply() family. + +install.packages("plyr") +require(plyr) +?plyr + +######################### +# Loading data +######################### + +# "pets.csv" is a file on the internet +pets <- read.csv("http://learnxinyminutes.com/docs/pets.csv") +pets +head(pets, 2) # first two rows +tail(pets, 1) # last row + +# To save a data frame or matrix as a .csv file +write.csv(pets, "pets2.csv") # to make a new .csv file +# set working directory with setwd(), look it up with getwd() + +# Try ?read.csv and ?write.csv for more information + +######################### +# Plots +######################### + +# Scatterplots! +plot(list1$time, list1$price, main = "fake data") +# Fit a linear model +myLm <- lm(price ~ time, data = list1) +myLm # outputs result of regression +# Plot regression line on existing plot +abline(myLm, col = "red") +# Get a variety of nice diagnostics +plot(myLm) + +# Histograms! +hist(rpois(n = 10000, lambda = 5), col = "thistle") + +# Barplots! +barplot(c(1,4,5,1,2), names.arg = c("red","blue","purple","green","yellow")) + +# Try the ggplot2 package for more and better graphics + +install.packages("ggplot2") +require(ggplot2) +?ggplot2 + +``` + + |