This file is a concatenation of [Learn X in Y minutes](https://github.com/adambard/learnxinyminutes-docs) for testing purposes. It is published under the original project license ([Creative Commons Attribution-ShareAlike 3.0 Unported](http://creativecommons.org/licenses/by-sa/3.0/deed.en_US)). ------ category: tool tool: amd contributors: - ["Frederik Ring", "https://github.com/m90"] filename: learnamd.js --- ## Getting Started with AMD The **Asynchronous Module Definition** API specifies a mechanism for defining JavaScript modules such that the module and its dependencies can be asynchronously loaded. This is particularly well suited for the browser environment where synchronous loading of modules incurs performance, usability, debugging, and cross-domain access problems. ### Basic concept ```javascript // The basic AMD API consists of nothing but two methods: `define` and `require` // and is all about module definition and consumption: // `define(id?, dependencies?, factory)` defines a module // `require(dependencies, callback)` imports a set of dependencies and // consumes them in the passed callback // Let's start by using define to define a new named module // that has no dependencies. We'll do so by passing a name // and a factory function to define: define('awesomeAMD', function(){ var isAMDAwesome = function(){ return true; }; // The return value of a module's factory function is // what other modules or require calls will receive when // requiring our `awesomeAMD` module. // The exported value can be anything, (constructor) functions, // objects, primitives, even undefined (although that won't help too much). return isAMDAwesome; }); // Now, let's define another module that depends upon our `awesomeAMD` module. // Notice that there's an additional argument defining our // module's dependencies now: define('loudmouth', ['awesomeAMD'], function(awesomeAMD){ // dependencies will be passed to the factory's arguments // in the order they are specified var tellEveryone = function(){ if (awesomeAMD()){ alert('This is sOoOo rad!'); } else { alert('Pretty dull, isn\'t it?'); } }; return tellEveryone; }); // As we do know how to use define now, let's use `require` to // kick off our program. `require`'s signature is `(arrayOfDependencies, callback)`. require(['loudmouth'], function(loudmouth){ loudmouth(); }); // To make this tutorial run code, let's implement a very basic // (non-asynchronous) version of AMD right here on the spot: function define(name, deps, factory){ // notice how modules without dependencies are handled define[name] = require(factory ? deps : [], factory || deps); } function require(deps, callback){ var args = []; // first let's retrieve all the dependencies needed // by the require call for (var i = 0; i < deps.length; i++){ args[i] = define[deps[i]]; } // satisfy all the callback's dependencies return callback.apply(null, args); } // you can see this code in action here: http://jsfiddle.net/qap949pd/ ``` ### Real-world usage with require.js In contrast to the introductory example, `require.js` (the most popular AMD library) actually implements the **A** in **AMD**, enabling you to load modules and their dependencies asynchronously via XHR: ```javascript /* file: app/main.js */ require(['modules/someClass'], function(SomeClass){ // the callback is deferred until the dependency is loaded var thing = new SomeClass(); }); console.log('So here we are, waiting!'); // this will run first ``` By convention, you usually store one module in one file. `require.js` can resolve module names based on file paths, so you don't have to name your modules, but can simply reference them using their location. In the example `someClass` is assumed to be in the `modules` folder, relative to your configuration's `baseUrl`: * app/ * main.js * modules/ * someClass.js * someHelpers.js * ... * daos/ * things.js * ... This means we can define `someClass` without specifying a module id: ```javascript /* file: app/modules/someClass.js */ define(['daos/things', 'modules/someHelpers'], function(thingsDao, helpers){ // module definition, of course, will also happen asynchronously function SomeClass(){ this.method = function(){/**/}; // ... } return SomeClass; }); ``` To alter the default path mapping behavior use `requirejs.config(configObj)` in your `main.js`: ```javascript /* file: main.js */ requirejs.config({ baseUrl : 'app', paths : { // you can also load modules from other locations jquery : '//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min', coolLibFromBower : '../bower_components/cool-lib/coollib' } }); require(['jquery', 'coolLibFromBower', 'modules/someHelpers'], function($, coolLib, helpers){ // a `main` file needs to call require at least once, // otherwise no code will ever run coolLib.doFancyStuffWith(helpers.transform($('#foo'))); }); ``` `require.js`-based apps will usually have a single entry point (`main.js`) that is passed to the `require.js` script tag as a data-attribute. It will be automatically loaded and executed on pageload: ```html A hundred script tags? Never again! ``` ### Optimizing a whole project using r.js Many people prefer using AMD for sane code organization during development, but still want to ship a single script file in production instead of performing hundreds of XHRs on page load. `require.js` comes with a script called `r.js` (that you will probably run in node.js, although Rhino is supported too) that can analyse your project's dependency graph, and build a single file containing all your modules (properly named), minified and ready for consumption. Install it using `npm`: ```shell $ npm install requirejs -g ``` Now you can feed it with a configuration file: ```shell $ r.js -o app.build.js ``` For our above example the configuration might look like: ```javascript /* file : app.build.js */ ({ name : 'main', // name of the entry point out : 'main-built.js', // name of the file to write the output to baseUrl : 'app', paths : { // `empty:` tells r.js that this should still be loaded from the CDN, using // the location specified in `main.js` jquery : 'empty:', coolLibFromBower : '../bower_components/cool-lib/coollib' } }) ``` To use the built file in production, simply swap `data-main`: ```html ``` An incredibly detailed [overview of build options](https://github.com/jrburke/r.js/blob/master/build/example.build.js) is available in the GitHub repo. ### Topics not covered in this tutorial * [Loader plugins / transforms](http://requirejs.org/docs/plugins.html) * [CommonJS style loading and exporting](http://requirejs.org/docs/commonjs.html) * [Advanced configuration](http://requirejs.org/docs/api.html#config) * [Shim configuration (loading non-AMD modules)](http://requirejs.org/docs/api.html#config-shim) * [CSS loading and optimizing with require.js](http://requirejs.org/docs/optimization.html#onecss) * [Using almond.js for builds](https://github.com/jrburke/almond) ### Further reading: * [Official Spec](https://github.com/amdjs/amdjs-api/wiki/AMD) * [Why AMD?](http://requirejs.org/docs/whyamd.html) * [Universal Module Definition](https://github.com/umdjs/umd) ### Implementations: * [require.js](http://requirejs.org) * [dojo toolkit](http://dojotoolkit.org/documentation/tutorials/1.9/modules/) * [cujo.js](http://cujojs.com/) * [curl.js](https://github.com/cujojs/curl) * [lsjs](https://github.com/zazl/lsjs) * [mmd](https://github.com/alexlawrence/mmd) --- category: tool tool: AngularJS contributors: - ["Walter Cordero", "http://waltercordero.com"] filename: learnangular.html --- ## AngularJS Tutorial. AngularJS version 1.0 was released in 2012. Miško Hevery, a Google employee, started to work with AngularJS in 2009. The idea turned out very well, and the project is now officially supported by Google. AngularJS is a JavaScript framework. It can be added to an HTML page with a "script" tag. AngularJS extends HTML attributes with Directives, and binds data to HTML with Expressions. ##What You Should Already Know Before you study AngularJS, you should have a basic understanding of: - HTML - CSS - JavaScript ```html // AngularJS is a JavaScript framework. It is a library written in JavaScript. // AngularJS is distributed as a JavaScript file, and can be added to a web page with a script tag: // /////////////////////////////////// // AngularJS Extends HTML //AngularJS extends HTML with ng-directives. //The ng-app directive defines an AngularJS application. //The ng-model directive binds the value of HTML controls (input, select, textarea) to application data. //The ng-bind directive binds application data to the HTML view.

Name:

/* * Example explained: * AngularJS starts automatically when the web page has loaded. * The ng-app directive tells AngularJS that the
element is the "owner" of an AngularJS application. * The ng-model directive binds the value of the input field to the application variable name. * The ng-bind directive binds the innerHTML of the

element to the application variable name. */ Here are content to be interpreted /////////////////////////////////// // AngularJS Expressions // AngularJS expressions are written inside double braces: {{ expression }}. // AngularJS expressions binds data to HTML the same way as the ng-bind directive. // AngularJS will "output" data exactly where the expression is written. // AngularJS expressions are much like JavaScript expressions: They can contain literals, operators, and variables. // Example {{ 5 + 5 }} or {{ firstName + " " + lastName }}

My first expression: {{ 5 + 5 }}

//If you remove the ng-app directive, HTML will display the expression as it is, without solving it:

My first expression: {{ 5 + 5 }}

// AngularJS expressions bind AngularJS data to HTML the same way as the ng-bind directive.

Name:

{{name}}

// AngularJS numbers are like JavaScript numbers:

Total in dollar: {{ quantity * cost }}

//AngularJS strings are like JavaScript strings:

The name is

//AngularJS objects are like JavaScript objects:

The name is {{ person.lastName }}

//AngularJS arrays are like JavaScript arrays:

The third result is {{ points[2] }}

// Like JavaScript expressions, AngularJS expressions can contain literals, operators, and variables. // Unlike JavaScript expressions, AngularJS expressions can be written inside HTML. // AngularJS expressions do not support conditionals, loops, and exceptions, while JavaScript expressions do. // AngularJS expressions support filters, while JavaScript expressions do not. /////////////////////////////////// // AngularJS Directives //AngularJS directives are extended HTML attributes with the prefix ng-. //The ng-app directive initializes an AngularJS application. //The ng-init directive initializes application data. //The ng-model directive binds the value of HTML controls (input, select, textarea) to application data.

Name:

You wrote: {{ firstName }}

//Using ng-init is not very common. You will learn how to initialize data in the chapter about controllers. //The ng-repeat directive repeats an HTML element:
//The ng-repeat directive used on an array of objects:
// AngularJS is perfect for database CRUD (Create Read Update Delete) applications. // Just imagine if these objects were records from a database. // The ng-app directive defines the root element of an AngularJS application. // The ng-app directive will auto-bootstrap (automatically initialize) the application when a web page is loaded. // Later you will learn how ng-app can have a value (like ng-app="myModule"), to connect code modules. // The ng-init directive defines initial values for an AngularJS application. // Normally, you will not use ng-init. You will use a controller or module instead. // You will learn more about controllers and modules later. //The ng-model directive binds the value of HTML controls (input, select, textarea) to application data. //The ng-model directive can also: //Provide type validation for application data (number, email, required). //Provide status for application data (invalid, dirty, touched, error). //Provide CSS classes for HTML elements. //Bind HTML elements to HTML forms. //The ng-repeat directive clones HTML elements once for each item in a collection (in an array). /////////////////////////////////// // AngularJS Controllers // AngularJS controllers control the data of AngularJS applications. // AngularJS controllers are regular JavaScript Objects. // AngularJS applications are controlled by controllers. // The ng-controller directive defines the application controller. // A controller is a JavaScript Object, created by a standard JavaScript object constructor.
First Name:
Last Name:

Full Name: {{firstName + " " + lastName}}
//Application explained: //The AngularJS application is defined by ng-app="myApp". The application runs inside the
. //The ng-controller="myCtrl" attribute is an AngularJS directive. It defines a controller. //The myCtrl function is a JavaScript function. //AngularJS will invoke the controller with a $scope object. //In AngularJS, $scope is the application object (the owner of application variables and functions). //The controller creates two properties (variables) in the scope (firstName and lastName). //The ng-model directives bind the input fields to the controller properties (firstName and lastName). //The example above demonstrated a controller object with two properties: lastName and firstName. //A controller can also have methods (variables as functions):
First Name:
Last Name:

Full Name: {{fullName()}}
//In larger applications, it is common to store controllers in external files. //Just copy the code between the tags into an external file named personController.js:
First Name:
Last Name:

Full Name: {{firstName + " " + lastName}}
// For the next example we will create a new controller file: angular.module('myApp', []).controller('namesCtrl', function($scope) { $scope.names = [ {name:'Jani',country:'Norway'}, {name:'Hege',country:'Sweden'}, {name:'Kai',country:'Denmark'} ]; }); //Save the file as namesController.js: //And then use the controller file in an application:
  • {{ x.name + ', ' + x.country }}
/////////////////////////////////// // AngularJS Filters // Filters can be added to expressions and directives using a pipe character. // AngularJS filters can be used to transform data: - **currency**: Format a number to a currency format. - **filter**: Select a subset of items from an array. - **lowercase**: Format a string to lower case. - **orderBy**: Orders an array by an expression. - **uppercase**: Format a string to upper case. //A filter can be added to an expression with a pipe character (|) and a filter. //(For the next two examples we will use the person controller from the previous chapter) //The uppercase filter format strings to upper case:

The name is {{ lastName | uppercase }}

//The lowercase filter format strings to lower case:

The name is {{ lastName | lowercase }}

//The currency filter formats a number as currency:

Total = {{ (quantity * price) | currency }}

//A filter can be added to a directive with a pipe character (|) and a filter. //The orderBy filter orders an array by an expression:
  • {{ x.name + ', ' + x.country }}
//An input filter can be added to a directive with a pipe character (|) //and filter followed by a colon and a model name. //The filter selects a subset of an array:

  • {{ (x.name | uppercase) + ', ' + x.country }}
/////////////////////////////////// // AngularJS AJAX - $http //$http is an AngularJS service for reading data from remote servers. // The following data can be provided by a web server: // http://www.w3schools.com/angular/customers.php // **Check the URL to see the data format** // AngularJS $http is a core service for reading data from web servers. // $http.get(url) is the function to use for reading server data.
  • {{ x.Name + ', ' + x.Country }}
Application explained: // The AngularJS application is defined by ng-app. The application runs inside a
. // The ng-controller directive names the controller object. // The customersCtrl function is a standard JavaScript object constructor. // AngularJS will invoke customersCtrl with a $scope and $http object. // $scope is the application object (the owner of application variables and functions). // $http is an XMLHttpRequest object for requesting external data. // $http.get() reads JSON data from http://www.w3schools.com/angular/customers.php. // If success, the controller creates a property (names) in the scope, with JSON data from the server. // Requests for data from a different server (than the requesting page), are called cross-site HTTP requests. // Cross-site requests are common on the web. Many pages load CSS, images, and scripts from different servers. // In modern browsers, cross-site HTTP requests from scripts are restricted to same site for security reasons. // The following line, in our PHP examples, has been added to allow cross-site access. header("Access-Control-Allow-Origin: *"); /////////////////////////////////// // AngularJS Tables // Displaying tables with angular is very simple:
{{ x.Name }} {{ x.Country }}
// To sort the table, add an orderBy filter:
{{ x.Name }} {{ x.Country }}
// To display the table index, add a with $index:
{{ $index + 1 }} {{ x.Name }} {{ x.Country }}
// Using $even and $odd
{{ x.Name }} {{ x.Name }} {{ x.Country }} {{ x.Country }}
/////////////////////////////////// // AngularJS HTML DOM //AngularJS has directives for binding application data to the attributes of HTML DOM elements. // The ng-disabled directive binds AngularJS application data to the disabled attribute of HTML elements.

Button

//Application explained: // The ng-disabled directive binds the application data mySwitch to the HTML button's disabled attribute. // The ng-model directive binds the value of the HTML checkbox element to the value of mySwitch. // If the value of mySwitch evaluates to true, the button will be disabled:

// If the value of mySwitch evaluates to false, the button will not be disabled:

// The ng-show directive shows or hides an HTML element.

I am visible.

I am not visible.

// The ng-show directive shows (or hides) an HTML element based on the value of ng-show. // You can use any expression that evaluates to true or false:

I am visible.

/////////////////////////////////// // AngularJS Events // AngularJS has its own HTML events directives. // The ng-click directive defines an AngularJS click event.

{{ count }}

// The ng-hide directive can be used to set the visibility of a part of an application. // The value ng-hide="true" makes an HTML element invisible. // The value ng-hide="false" makes the element visible.

First Name:
Last Name:

Full Name: {{firstName + " " + lastName}}

//Application explained: // The first part of the personController is the same as in the chapter about controllers. // The application has a default property (a variable): $scope.myVar = false; // The ng-hide directive sets the visibility, of a

element with two input fields, // according to the value (true or false) of myVar. // The function toggle() toggles myVar between true and false. // The value ng-hide="true" makes the element invisible. // The ng-show directive can also be used to set the visibility of a part of an application. // The value ng-show="false" makes an HTML element invisible. // The value ng-show="true" makes the element visible. // Here is the same example as above, using ng-show instead of ng-hide:

First Name:
Last Name:

Full Name: {{firstName + " " + lastName}}

/////////////////////////////////// // AngularJS Modules // An AngularJS module defines an application. // The module is a container for the different parts of an application. // The module is a container for the application controllers. // Controllers always belong to a module. // This application ("myApp") has one controller ("myCtrl"):
{{ firstName + " " + lastName }}
// It is common in AngularJS applications to put the module and the controllers in JavaScript files. // In this example, "myApp.js" contains an application module definition, while "myCtrl.js" contains the controller:
{{ firstName + " " + lastName }}
//myApp.js var app = angular.module("myApp", []); // The [] parameter in the module definition can be used to define dependent modules. // myCtrl.js app.controller("myCtrl", function($scope) { $scope.firstName = "John"; $scope.lastName= "Doe"; }); // Global functions should be avoided in JavaScript. They can easily be overwritten // or destroyed by other scripts. // AngularJS modules reduces this problem, by keeping all functions local to the module. // While it is common in HTML applications to place scripts at the end of the // element, it is recommended that you load the AngularJS library either // in the or at the start of the . // This is because calls to angular.module can only be compiled after the library has been loaded.
{{ firstName + " " + lastName }}
/////////////////////////////////// // AngularJS Applications // AngularJS modules define AngularJS applications. // AngularJS controllers control AngularJS applications. // The ng-app directive defines the application, the ng-controller directive defines the controller.
First Name:
Last Name:

Full Name: {{firstName + " " + lastName}}
// AngularJS modules define applications: var app = angular.module('myApp', []); // AngularJS controllers control applications: app.controller('myCtrl', function($scope) { $scope.firstName= "John"; $scope.lastName= "Doe"; }); ``` ## Source & References **Examples** - [http://www.w3schools.com/angular/angular_examples.asp](http://www.w3schools.com/angular/angular_examples.asp) **References** - [http://www.w3schools.com/angular/angular_ref_directives.asp](http://www.w3schools.com/angular/angular_ref_directives.asp) - [http://www.w3schools.com/angular/default.asp](http://www.w3schools.com/angular/default.asp) - [https://teamtreehouse.com/library/angular-basics/](https://teamtreehouse.com/library/angular-basics/) --- language: html lang: ar-ar filename: learnhtml-tf.html contributors: - ["Christophe THOMAS", "https://github.com/WinChris"] translators: - ["Ader", "https://github.com/y1n0"] --- HTML اختصار ل HyperText Markup Language، أي "لغة ترميز النص التشعبي". هي لغة تمكننا من كتابة صفحات موجهة لشبكة الويب العالمي. هي لغة توصيف للنص، تسمح بكتابة صفحات ويب عن طريق تحديد كيفية عرض النصوص والمعلومات. في الحقيقة، ملفات html هي ملفات تحتوي على نصوص بسيطة. ما هو توصيف النص هذا؟ هو طريقة لتنظيم معلومات النص عن طريق إحاطته بوُسوم فتح ووسوم غلق. هذه الوسوم تعطي معاني محددة للنص الذي تحيطه. كباقي لغات الحاسوب، هناك الكثير من إصدارات HTML. سنتحدث هنا عن HTLM5. **ملاحظة:** يمكنك تجريب مختلف الوسوم والعناصر بينما تقرأ الدرس عبر موقع كـ [codepen](http://codepen.io/pen/) حتى ترى تأثيرها وتعرف كيف تعمل وتتعود على استعمالها. هذه المادة تُعنى أساسا بتركيب HTML .وبعض النصائح المفيدة ```html موقعي

مرحبا بالعالم!

الق نظرة كيف يبدو هذا من هنا

هذه فقرة.

هذه فقرة أخرى.

  • هذا عنصر من لائحة غير مرقمة. (لائحة بالعرائض)
  • هذا عنصر آخر
  • وهذا آخر عنصر في اللائحة
موقعي

مرحبا بالعالم!

ألق نظرة كيف يبدو هذا من هنا

هذه فقرة.

هذه فقرة أخرى.

  • هذا عنصر من لائحة غير مرقمة. (لائحة بالعرائض)
  • هذا عنصر آخر
  • وهذا آخر عنصر في اللائحة
العنوان الأول العنوان الثاني
الصف الأول، العمود الأول الصف الأول، العمود الثاني
الصف الثاني، العمود الأول الصف الثاني، العمود الأول
``` ## الاستعمال HTML يُكتب في ملفات تنتهي بـ `.html`. ## لمعرفة المزيد * [wikipedia](https://en.wikipedia.org/wiki/HTML) * [HTML tutorial](https://developer.mozilla.org/en-US/docs/Web/HTML) * [W3School](http://www.w3schools.com/html/html_intro.asp) --- language: asciidoc contributors: - ["Ryan Mavilia", "http://unoriginality.rocks/"] filename: asciidoc.md --- AsciiDoc is a markup language similar to Markdown and it can be used for anything from books to blogs. Created in 2002 by Stuart Rackham the language is simple but it allows for a great amount of customization. Document Header Headers are optional and can't contain blank lines. It must be offset from content by at least one blank line. Title Only ``` = Document Title First sentence of document. ``` Title and Author ``` = Document Title First Last Start of this document. ``` Multiple Authors ``` = Document Title John Doe ; Jane Doe; Black Beard Start of a doc with multiple authors. ``` Revision Line (requires an author line) ``` = Doc Title V1 Potato Man v1.0, 2016-01-13 This article about chips is going to be fun. ``` Paragraphs ``` You don't need anything special for paragraphs. Add a blank line between paragraphs to separate them. To create a line blank add a + and you will receive a line break! ``` Formatting Text ``` _underscore creates italics_ *asterisks for bold* *_combine for extra fun_* `use ticks to signify monospace` `*bolded monospace*` ``` Section Titles ``` = Level 0 (may only be used in document's header) == Level 1

=== Level 2

==== Level 3

===== Level 4

====== Level 5
======= Level 6 ``` Lists To create a bulleted list use asterisks. ``` * foo * bar * baz ``` To create a numbered list use periods. ``` . item 1 . item 2 . item 3 ``` You can nest lists by adding extra asterisks or periods up to five times. ``` * foo 1 ** foo 2 *** foo 3 **** foo 4 ***** foo 5 . foo 1 .. foo 2 ... foo 3 .... foo 4 ..... foo 5 ``` --- category: Algorithms & Data Structures name: Asymptotic Notation contributors: - ["Jake Prather", "http://github.com/JakeHP"] - ["Divay Prakash", "http://github.com/divayprakash"] --- # Asymptotic Notations ## What are they? Asymptotic Notations are languages that allow us to analyze an algorithm's running time by identifying its behavior as the input size for the algorithm increases. This is also known as an algorithm's growth rate. Does the algorithm suddenly become incredibly slow when the input size grows? Does it mostly maintain its quick run time as the input size increases? Asymptotic Notation gives us the ability to answer these questions. ## Are there alternatives to answering these questions? One way would be to count the number of primitive operations at different input sizes. Though this is a valid solution, the amount of work this takes for even simple algorithms does not justify its use. Another way is to physically measure the amount of time an algorithm takes to complete given different input sizes. However, the accuracy and relativity (times obtained would only be relative to the machine they were computed on) of this method is bound to environmental variables such as computer hardware specifications, processing power, etc. ## Types of Asymptotic Notation In the first section of this doc we described how an Asymptotic Notation identifies the behavior of an algorithm as the input size changes. Let us imagine an algorithm as a function f, n as the input size, and f(n) being the running time. So for a given algorithm f, with input size n you get some resultant run time f(n). This results in a graph where the Y axis is the runtime, X axis is the input size, and plot points are the resultants of the amount of time for a given input size. You can label a function, or algorithm, with an Asymptotic Notation in many different ways. Some examples are, you can describe an algorithm by its best case, worse case, or equivalent case. The most common is to analyze an algorithm by its worst case. You typically don't evaluate by best case because those conditions aren't what you're planning for. A very good example of this is sorting algorithms; specifically, adding elements to a tree structure. Best case for most algorithms could be as low as a single operation. However, in most cases, the element you're adding will need to be sorted appropriately through the tree, which could mean examining an entire branch. This is the worst case, and this is what we plan for. ### Types of functions, limits, and simplification ``` Logarithmic Function - log n Linear Function - an + b Quadratic Function - an^2 + bn + c Polynomial Function - an^z + . . . + an^2 + a*n^1 + a*n^0, where z is some constant Exponential Function - a^n, where a is some constant ``` These are some basic function growth classifications used in various notations. The list starts at the slowest growing function (logarithmic, fastest execution time) and goes on to the fastest growing (exponential, slowest execution time). Notice that as 'n', or the input, increases in each of those functions, the result clearly increases much quicker in quadratic, polynomial, and exponential, compared to logarithmic and linear. One extremely important note is that for the notations about to be discussed you should do your best to use simplest terms. This means to disregard constants, and lower order terms, because as the input size (or n in our f(n) example) increases to infinity (mathematical limits), the lower order terms and constants are of little to no importance. That being said, if you have constants that are 2^9001, or some other ridiculous, unimaginable amount, realize that simplifying will skew your notation accuracy. Since we want simplest form, lets modify our table a bit... ``` Logarithmic - log n Linear - n Quadratic - n^2 Polynomial - n^z, where z is some constant Exponential - a^n, where a is some constant ``` ### Big-O Big-O, commonly written as **O**, is an Asymptotic Notation for the worst case, or ceiling of growth for a given function. It provides us with an _**asymptotic upper bound**_ for the growth rate of runtime of an algorithm. Say `f(n)` is your algorithm runtime, and `g(n)` is an arbitrary time complexity you are trying to relate to your algorithm. `f(n)` is O(g(n)), if for some real constants c (c > 0) and n0, `f(n)` <= `c g(n)` for every input size n (n > n0). *Example 1* ``` f(n) = 3log n + 100 g(n) = log n ``` Is `f(n)` O(g(n))? Is `3 log n + 100` O(log n)? Let's look to the definition of Big-O. ``` 3log n + 100 <= c * log n ``` Is there some pair of constants c, n0 that satisfies this for all n > 0? ``` 3log n + 100 <= 150 * log n, n > 2 (undefined at n = 1) ``` Yes! The definition of Big-O has been met therefore `f(n)` is O(g(n)). *Example 2* ``` f(n) = 3*n^2 g(n) = n ``` Is `f(n)` O(g(n))? Is `3 * n^2` O(n)? Let's look at the definition of Big-O. ``` 3 * n^2 <= c * n ``` Is there some pair of constants c, n0 that satisfies this for all n > 0? No, there isn't. `f(n)` is NOT O(g(n)). ### Big-Omega Big-Omega, commonly written as **Ω**, is an Asymptotic Notation for the best case, or a floor growth rate for a given function. It provides us with an _**asymptotic lower bound**_ for the growth rate of runtime of an algorithm. `f(n)` is Ω(g(n)), if for some real constants c (c > 0) and n0 (n0 > 0), `f(n)` is >= `c g(n)` for every input size n (n > n0). ### Note The asymptotic growth rates provided by big-O and big-omega notation may or may not be asymptotically tight. Thus we use small-o and small-omega notation to denote bounds that are not asymptotically tight. ### Small-o Small-o, commonly written as **o**, is an Asymptotic Notation to denote the upper bound (that is not asymptotically tight) on the growth rate of runtime of an algorithm. `f(n)` is o(g(n)), if for some real constants c (c > 0) and n0 (n0 > 0), `f(n)` is < `c g(n)` for every input size n (n > n0). The definitions of O-notation and o-notation are similar. The main difference is that in f(n) = O(g(n)), the bound f(n) <= g(n) holds for _**some**_ constant c > 0, but in f(n) = o(g(n)), the bound f(n) < c g(n) holds for _**all**_ constants c > 0. ### Small-omega Small-omega, commonly written as **ω**, is an Asymptotic Notation to denote the lower bound (that is not asymptotically tight) on the growth rate of runtime of an algorithm. `f(n)` is ω(g(n)), if for some real constants c (c > 0) and n0 (n0 > 0), `f(n)` is > `c g(n)` for every input size n (n > n0). The definitions of Ω-notation and ω-notation are similar. The main difference is that in f(n) = Ω(g(n)), the bound f(n) >= g(n) holds for _**some**_ constant c > 0, but in f(n) = ω(g(n)), the bound f(n) > c g(n) holds for _**all**_ constants c > 0. ### Theta Theta, commonly written as **Θ**, is an Asymptotic Notation to denote the _**asymptotically tight bound**_ on the growth rate of runtime of an algorithm. `f(n)` is Θ(g(n)), if for some real constants c1, c2 and n0 (c1 > 0, c2 > 0, n0 > 0), `c1 g(n)` is < `f(n)` is < `c2 g(n)` for every input size n (n > n0). ∴ `f(n)` is Θ(g(n)) implies `f(n)` is O(g(n)) as well as `f(n)` is Ω(g(n)). Feel free to head over to additional resources for examples on this. Big-O is the primary notation use for general algorithm time complexity. ### Ending Notes It's hard to keep this kind of topic short, and you should definitely go through the books and online resources listed. They go into much greater depth with definitions and examples. More where x='Algorithms & Data Structures' is on its way; we'll have a doc up on analyzing actual code examples soon. ## Books * [Algorithms](http://www.amazon.com/Algorithms-4th-Robert-Sedgewick/dp/032157351X) * [Algorithm Design](http://www.amazon.com/Algorithm-Design-Foundations-Analysis-Internet/dp/0471383651) ## Online Resources * [MIT](http://web.mit.edu/16.070/www/lecture/big_o.pdf) * [KhanAcademy](https://www.khanacademy.org/computing/computer-science/algorithms/asymptotic-notation/a/asymptotic-notation) * [Big-O Cheatsheet](http://bigocheatsheet.com/) - common structures, operations, and algorithms, ranked by complexity. --- language: awk filename: learnawk.awk contributors: - ["Marshall Mason", "http://github.com/marshallmason"] --- AWK is a standard tool on every POSIX-compliant UNIX system. It's like a stripped-down Perl, perfect for text-processing tasks and other scripting needs. It has a C-like syntax, but without semicolons, manual memory management, or static typing. It excels at text processing. You can call to it from a shell script, or you can use it as a stand-alone scripting language. Why use AWK instead of Perl? Mostly because AWK is part of UNIX. You can always count on it, whereas Perl's future is in question. AWK is also easier to read than Perl. For simple text-processing scripts, particularly ones that read files line by line and split on delimiters, AWK is probably the right tool for the job. ```awk #!/usr/bin/awk -f # Comments are like this # AWK programs consist of a collection of patterns and actions. The most # important pattern is called BEGIN. Actions go into brace blocks. BEGIN { # BEGIN will run at the beginning of the program. It's where you put all # the preliminary set-up code, before you process any text files. If you # have no text files, then think of BEGIN as the main entry point. # Variables are global. Just set them or use them, no need to declare.. count = 0 # Operators just like in C and friends a = count + 1 b = count - 1 c = count * 1 d = count / 1 e = count % 1 # modulus f = count ^ 1 # exponentiation a += 1 b -= 1 c *= 1 d /= 1 e %= 1 f ^= 1 # Incrementing and decrementing by one a++ b-- # As a prefix operator, it returns the incremented value ++a --b # Notice, also, no punctuation such as semicolons to terminate statements # Control statements if (count == 0) print "Starting with count of 0" else print "Huh?" # Or you could use the ternary operator print (count == 0) ? "Starting with count of 0" : "Huh?" # Blocks consisting of multiple lines use braces while (a < 10) { print "String concatenation is done" " with a series" " of" " space-separated strings" print a a++ } for (i = 0; i < 10; i++) print "Good ol' for loop" # As for comparisons, they're the standards: a < b # Less than a <= b # Less than or equal a != b # Not equal a == b # Equal a > b # Greater than a >= b # Greater than or equal # Logical operators as well a && b # AND a || b # OR # In addition, there's the super useful regular expression match if ("foo" ~ "^fo+$") print "Fooey!" if ("boo" !~ "^fo+$") print "Boo!" # Arrays arr[0] = "foo" arr[1] = "bar" # Unfortunately, there is no other way to initialize an array. Ya just # gotta chug through every value line by line like that. # You also have associative arrays assoc["foo"] = "bar" assoc["bar"] = "baz" # And multi-dimensional arrays, with some limitations I won't mention here multidim[0,0] = "foo" multidim[0,1] = "bar" multidim[1,0] = "baz" multidim[1,1] = "boo" # You can test for array membership if ("foo" in assoc) print "Fooey!" # You can also use the 'in' operator to traverse the keys of an array for (key in assoc) print assoc[key] # The command line is in a special array called ARGV for (argnum in ARGV) print ARGV[argnum] # You can remove elements of an array # This is particularly useful to prevent AWK from assuming the arguments # are files for it to process delete ARGV[1] # The number of command line arguments is in a variable called ARGC print ARGC # AWK has several built-in functions. They fall into three categories. I'll # demonstrate each of them in their own functions, defined later. return_value = arithmetic_functions(a, b, c) string_functions() io_functions() } # Here's how you define a function function arithmetic_functions(a, b, c, localvar) { # Probably the most annoying part of AWK is that there are no local # variables. Everything is global. For short scripts, this is fine, even # useful, but for longer scripts, this can be a problem. # There is a work-around (ahem, hack). Function arguments are local to the # function, and AWK allows you to define more function arguments than it # needs. So just stick local variable in the function declaration, like I # did above. As a convention, stick in some extra whitespace to distinguish # between actual function parameters and local variables. In this example, # a, b, and c are actual parameters, while d is merely a local variable. # Now, to demonstrate the arithmetic functions # Most AWK implementations have some standard trig functions localvar = sin(a) localvar = cos(a) localvar = atan2(a, b) # arc tangent of b / a # And logarithmic stuff localvar = exp(a) localvar = log(a) # Square root localvar = sqrt(a) # Truncate floating point to integer localvar = int(5.34) # localvar => 5 # Random numbers srand() # Supply a seed as an argument. By default, it uses the time of day localvar = rand() # Random number between 0 and 1. # Here's how to return a value return localvar } function string_functions( localvar, arr) { # AWK, being a string-processing language, has several string-related # functions, many of which rely heavily on regular expressions. # Search and replace, first instance (sub) or all instances (gsub) # Both return number of matches replaced localvar = "fooooobar" sub("fo+", "Meet me at the ", localvar) # localvar => "Meet me at the bar" gsub("e+", ".", localvar) # localvar => "m..t m. at th. bar" # Search for a string that matches a regular expression # index() does the same thing, but doesn't allow a regular expression match(localvar, "t") # => 4, since the 't' is the fourth character # Split on a delimiter split("foo-bar-baz", arr, "-") # a => ["foo", "bar", "baz"] # Other useful stuff sprintf("%s %d %d %d", "Testing", 1, 2, 3) # => "Testing 1 2 3" substr("foobar", 2, 3) # => "oob" substr("foobar", 4) # => "bar" length("foo") # => 3 tolower("FOO") # => "foo" toupper("foo") # => "FOO" } function io_functions( localvar) { # You've already seen print print "Hello world" # There's also printf printf("%s %d %d %d\n", "Testing", 1, 2, 3) # AWK doesn't have file handles, per se. It will automatically open a file # handle for you when you use something that needs one. The string you used # for this can be treated as a file handle, for purposes of I/O. This makes # it feel sort of like shell scripting: print "foobar" >"/tmp/foobar.txt" # Now the string "/tmp/foobar.txt" is a file handle. You can close it: close("/tmp/foobar.txt") # Here's how you run something in the shell system("echo foobar") # => prints foobar # Reads a line from standard input and stores in localvar getline localvar # Reads a line from a pipe "echo foobar" | getline localvar # localvar => "foobar" close("echo foobar") # Reads a line from a file and stores in localvar getline localvar <"/tmp/foobar.txt" close("/tmp/foobar.txt") } # As I said at the beginning, AWK programs consist of a collection of patterns # and actions. You've already seen the all-important BEGIN pattern. Other # patterns are used only if you're processing lines from files or standard # input. # # When you pass arguments to AWK, they are treated as file names to process. # It will process them all, in order. Think of it like an implicit for loop, # iterating over the lines in these files. these patterns and actions are like # switch statements inside the loop. /^fo+bar$/ { # This action will execute for every line that matches the regular # expression, /^fo+bar$/, and will be skipped for any line that fails to # match it. Let's just print the line: print # Whoa, no argument! That's because print has a default argument: $0. # $0 is the name of the current line being processed. It is created # automatically for you. # You can probably guess there are other $ variables. Every line is # implicitly split before every action is called, much like the shell # does. And, like the shell, each field can be access with a dollar sign # This will print the second and fourth fields in the line print $2, $4 # AWK automatically defines many other variables to help you inspect and # process each line. The most important one is NF # Prints the number of fields on this line print NF # Print the last field on this line print $NF } # Every pattern is actually a true/false test. The regular expression in the # last pattern is also a true/false test, but part of it was hidden. If you # don't give it a string to test, it will assume $0, the line that it's # currently processing. Thus, the complete version of it is this: $0 ~ /^fo+bar$/ { print "Equivalent to the last pattern" } a > 0 { # This will execute once for each line, as long as a is positive } # You get the idea. Processing text files, reading in a line at a time, and # doing something with it, particularly splitting on a delimiter, is so common # in UNIX that AWK is a scripting language that does all of it for you, without # you needing to ask. All you have to do is write the patterns and actions # based on what you expect of the input, and what you want to do with it. # Here's a quick example of a simple script, the sort of thing AWK is perfect # for. It will read a name from standard input and then will print the average # age of everyone with that first name. Let's say you supply as an argument the # name of a this data file: # # Bob Jones 32 # Jane Doe 22 # Steve Stevens 83 # Bob Smith 29 # Bob Barker 72 # # Here's the script: BEGIN { # First, ask the user for the name print "What name would you like the average age for?" # Get a line from standard input, not from files on the command line getline name <"/dev/stdin" } # Now, match every line whose first field is the given name $1 == name { # Inside here, we have access to a number of useful variables, already # pre-loaded for us: # $0 is the entire line # $3 is the third field, the age, which is what we're interested in here # NF is the number of fields, which should be 3 # NR is the number of records (lines) seen so far # FILENAME is the name of the file being processed # FS is the field separator being used, which is " " here # ...etc. There are plenty more, documented in the man page. # Keep track of a running total and how many lines matched sum += $3 nlines++ } # Another special pattern is called END. It will run after processing all the # text files. Unlike BEGIN, it will only run if you've given it input to # process. It will run after all the files have been read and processed # according to the rules and actions you've provided. The purpose of it is # usually to output some kind of final report, or do something with the # aggregate of the data you've accumulated over the course of the script. END { if (nlines) print "The average age for " name " is " sum / nlines } ``` Further Reading: * [Awk tutorial](http://www.grymoire.com/Unix/Awk.html) * [Awk man page](https://linux.die.net/man/1/awk) * [The GNU Awk User's Guide](https://www.gnu.org/software/gawk/manual/gawk.html) GNU Awk is found on most Linux systems. --- category: tool tool: bash contributors: - ["Max Yankov", "https://github.com/golergka"] - ["Darren Lin", "https://github.com/CogBear"] - ["Alexandre Medeiros", "http://alemedeiros.sdf.org"] - ["Denis Arh", "https://github.com/darh"] - ["akirahirose", "https://twitter.com/akirahirose"] - ["Anton Strömkvist", "http://lutic.org/"] - ["Rahil Momin", "https://github.com/iamrahil"] - ["Gregrory Kielian", "https://github.com/gskielian"] - ["Etan Reisner", "https://github.com/deryni"] - ["Jonathan Wang", "https://github.com/Jonathansw"] - ["Leo Rudberg", "https://github.com/LOZORD"] - ["Betsy Lorton", "https://github.com/schbetsy"] - ["John Detter", "https://github.com/jdetter"] filename: LearnBash.sh --- Bash is a name of the unix shell, which was also distributed as the shell for the GNU operating system and as default shell on Linux and Mac OS X. Nearly all examples below can be a part of a shell script or executed directly in the shell. [Read more here.](http://www.gnu.org/software/bash/manual/bashref.html) ```bash #!/bin/bash # First line of the script is shebang which tells the system how to execute # the script: http://en.wikipedia.org/wiki/Shebang_(Unix) # As you already figured, comments start with #. Shebang is also a comment. # Simple hello world example: echo Hello world! # Each command starts on a new line, or after semicolon: echo 'This is the first line'; echo 'This is the second line' # Declaring a variable looks like this: Variable="Some string" # But not like this: Variable = "Some string" # Bash will decide that Variable is a command it must execute and give an error # because it can't be found. # Or like this: Variable= 'Some string' # Bash will decide that 'Some string' is a command it must execute and give an # error because it can't be found. (In this case the 'Variable=' part is seen # as a variable assignment valid only for the scope of the 'Some string' # command.) # Using the variable: echo $Variable echo "$Variable" echo '$Variable' # When you use the variable itself — assign it, export it, or else — you write # its name without $. If you want to use the variable's value, you should use $. # Note that ' (single quote) won't expand the variables! # Parameter expansion ${ }: echo ${Variable} # This is a simple usage of parameter expansion # Parameter Expansion gets a value from a variable. It "expands" or prints the value # During the expansion time the value or parameter are able to be modified # Below are other modifications that add onto this expansion # String substitution in variables echo ${Variable/Some/A} # This will substitute the first occurrence of "Some" with "A" # Substring from a variable Length=7 echo ${Variable:0:Length} # This will return only the first 7 characters of the value # Default value for variable echo ${Foo:-"DefaultValueIfFooIsMissingOrEmpty"} # This works for null (Foo=) and empty string (Foo=""); zero (Foo=0) returns 0. # Note that it only returns default value and doesn't change variable value. # Brace Expansion { } # Used to generate arbitrary strings echo {1..10} echo {a..z} # This will output the range from the start value to the end value # Builtin variables: # There are some useful builtin variables, like echo "Last program's return value: $?" echo "Script's PID: $$" echo "Number of arguments passed to script: $#" echo "All arguments passed to script: $@" echo "Script's arguments separated into different variables: $1 $2..." # Now that we know how to echo and use variables, # let's learn some of the other basics of bash! # Our current directory is available through the command `pwd`. # `pwd` stands for "print working directory". # We can also use the builtin variable `$PWD`. # Observe that the following are equivalent: echo "I'm in $(pwd)" # execs `pwd` and interpolates output echo "I'm in $PWD" # interpolates the variable # If you get too much output in your terminal, or from a script, the command # `clear` clears your screen clear # Ctrl-L also works for clearing output # Reading a value from input: echo "What's your name?" read Name # Note that we didn't need to declare a new variable echo Hello, $Name! # We have the usual if structure: # use 'man test' for more info about conditionals if [ $Name != $USER ] then echo "Your name isn't your username" else echo "Your name is your username" fi # NOTE: if $Name is empty, bash sees the above condition as: if [ != $USER ] # which is invalid syntax # so the "safe" way to use potentially empty variables in bash is: if [ "$Name" != $USER ] ... # which, when $Name is empty, is seen by bash as: if [ "" != $USER ] ... # which works as expected # There is also conditional execution echo "Always executed" || echo "Only executed if first command fails" echo "Always executed" && echo "Only executed if first command does NOT fail" # To use && and || with if statements, you need multiple pairs of square brackets: if [ "$Name" == "Steve" ] && [ "$Age" -eq 15 ] then echo "This will run if $Name is Steve AND $Age is 15." fi if [ "$Name" == "Daniya" ] || [ "$Name" == "Zach" ] then echo "This will run if $Name is Daniya OR Zach." fi # Expressions are denoted with the following format: echo $(( 10 + 5 )) # Unlike other programming languages, bash is a shell so it works in the context # of a current directory. You can list files and directories in the current # directory with the ls command: ls # These commands have options that control their execution: ls -l # Lists every file and directory on a separate line ls -t # Sorts the directory contents by last-modified date (descending) ls -R # Recursively `ls` this directory and all of its subdirectories # Results of the previous command can be passed to the next command as input. # grep command filters the input with provided patterns. That's how we can list # .txt files in the current directory: ls -l | grep "\.txt" # Use `cat` to print files to stdout: cat file.txt # We can also read the file using `cat`: Contents=$(cat file.txt) echo "START OF FILE\n$Contents\nEND OF FILE" # Use `cp` to copy files or directories from one place to another. # `cp` creates NEW versions of the sources, # so editing the copy won't affect the original (and vice versa). # Note that it will overwrite the destination if it already exists. cp srcFile.txt clone.txt cp -r srcDirectory/ dst/ # recursively copy # Look into `scp` or `sftp` if you plan on exchanging files between computers. # `scp` behaves very similarly to `cp`. # `sftp` is more interactive. # Use `mv` to move files or directories from one place to another. # `mv` is similar to `cp`, but it deletes the source. # `mv` is also useful for renaming files! mv s0urc3.txt dst.txt # sorry, l33t hackers... # Since bash works in the context of a current directory, you might want to # run your command in some other directory. We have cd for changing location: cd ~ # change to home directory cd .. # go up one directory # (^^say, from /home/username/Downloads to /home/username) cd /home/username/Documents # change to specified directory cd ~/Documents/.. # still in home directory..isn't it?? # Use subshells to work across directories (echo "First, I'm here: $PWD") && (cd someDir; echo "Then, I'm here: $PWD") pwd # still in first directory # Use `mkdir` to create new directories. mkdir myNewDir # The `-p` flag causes new intermediate directories to be created as necessary. mkdir -p myNewDir/with/intermediate/directories # You can redirect command input and output (stdin, stdout, and stderr). # Read from stdin until ^EOF$ and overwrite hello.py with the lines # between "EOF": cat > hello.py << EOF #!/usr/bin/env python from __future__ import print_function import sys print("#stdout", file=sys.stdout) print("#stderr", file=sys.stderr) for line in sys.stdin: print(line, file=sys.stdout) EOF # Run hello.py with various stdin, stdout, and stderr redirections: python hello.py < "input.in" python hello.py > "output.out" python hello.py 2> "error.err" python hello.py > "output-and-error.log" 2>&1 python hello.py > /dev/null 2>&1 # The output error will overwrite the file if it exists, # if you want to append instead, use ">>": python hello.py >> "output.out" 2>> "error.err" # Overwrite output.out, append to error.err, and count lines: info bash 'Basic Shell Features' 'Redirections' > output.out 2>> error.err wc -l output.out error.err # Run a command and print its file descriptor (e.g. /dev/fd/123) # see: man fd echo <(echo "#helloworld") # Overwrite output.out with "#helloworld": cat > output.out <(echo "#helloworld") echo "#helloworld" > output.out echo "#helloworld" | cat > output.out echo "#helloworld" | tee output.out >/dev/null # Cleanup temporary files verbosely (add '-i' for interactive) # WARNING: `rm` commands cannot be undone rm -v output.out error.err output-and-error.log rm -r tempDir/ # recursively delete # Commands can be substituted within other commands using $( ): # The following command displays the number of files and directories in the # current directory. echo "There are $(ls | wc -l) items here." # The same can be done using backticks `` but they can't be nested - the preferred way # is to use $( ). echo "There are `ls | wc -l` items here." # Bash uses a case statement that works similarly to switch in Java and C++: case "$Variable" in #List patterns for the conditions you want to meet 0) echo "There is a zero.";; 1) echo "There is a one.";; *) echo "It is not null.";; esac # for loops iterate for as many arguments given: # The contents of $Variable is printed three times. for Variable in {1..3} do echo "$Variable" done # Or write it the "traditional for loop" way: for ((a=1; a <= 3; a++)) do echo $a done # They can also be used to act on files.. # This will run the command 'cat' on file1 and file2 for Variable in file1 file2 do cat "$Variable" done # ..or the output from a command # This will cat the output from ls. for Output in $(ls) do cat "$Output" done # while loop: while [ true ] do echo "loop body here..." break done # You can also define functions # Definition: function foo () { echo "Arguments work just like script arguments: $@" echo "And: $1 $2..." echo "This is a function" return 0 } # or simply bar () { echo "Another way to declare functions!" return 0 } # Calling your function foo "My name is" $Name # There are a lot of useful commands you should learn: # prints last 10 lines of file.txt tail -n 10 file.txt # prints first 10 lines of file.txt head -n 10 file.txt # sort file.txt's lines sort file.txt # report or omit repeated lines, with -d it reports them uniq -d file.txt # prints only the first column before the ',' character cut -d ',' -f 1 file.txt # replaces every occurrence of 'okay' with 'great' in file.txt, (regex compatible) sed -i 's/okay/great/g' file.txt # print to stdout all lines of file.txt which match some regex # The example prints lines which begin with "foo" and end in "bar" grep "^foo.*bar$" file.txt # pass the option "-c" to instead print the number of lines matching the regex grep -c "^foo.*bar$" file.txt # Other useful options are: grep -r "^foo.*bar$" someDir/ # recursively `grep` grep -n "^foo.*bar$" file.txt # give line numbers grep -rI "^foo.*bar$" someDir/ # recursively `grep`, but ignore binary files # perform the same initial search, but filter out the lines containing "baz" grep "^foo.*bar$" file.txt | grep -v "baz" # if you literally want to search for the string, # and not the regex, use fgrep (or grep -F) fgrep "foobar" file.txt # trap command allows you to execute a command when a signal is received by your script. # Here trap command will execute rm if any one of the three listed signals is received. trap "rm $TEMP_FILE; exit" SIGHUP SIGINT SIGTERM # `sudo` is used to perform commands as the superuser NAME1=$(whoami) NAME2=$(sudo whoami) echo "Was $NAME1, then became more powerful $NAME2" # Read Bash shell builtins documentation with the bash 'help' builtin: help help help help for help return help source help . # Read Bash manpage documentation with man apropos bash man 1 bash man bash # Read info documentation with info (? for help) apropos info | grep '^info.*(' man info info info info 5 info # Read bash info documentation: info bash info bash 'Bash Features' info bash 6 info --apropos bash ``` --- language: "Brainfuck" filename: brainfuck.bf contributors: - ["Prajit Ramachandran", "http://prajitr.github.io/"] - ["Mathias Bynens", "http://mathiasbynens.be/"] --- Brainfuck (not capitalized except at the start of a sentence) is an extremely minimal Turing-complete programming language with just 8 commands. You can try brainfuck on your browser with [brainfuck-visualizer](http://fatiherikli.github.io/brainfuck-visualizer/). ```bf Any character not "><+-.,[]" (excluding quotation marks) is ignored. Brainfuck is represented by an array with 30,000 cells initialized to zero and a data pointer pointing at the current cell. There are eight commands: + : Increments the value at the current cell by one. - : Decrements the value at the current cell by one. > : Moves the data pointer to the next cell (cell on the right). < : Moves the data pointer to the previous cell (cell on the left). . : Prints the ASCII value at the current cell (i.e. 65 = 'A'). , : Reads a single input character into the current cell. [ : If the value at the current cell is zero, skips to the corresponding ] . Otherwise, move to the next instruction. ] : If the value at the current cell is zero, move to the next instruction. Otherwise, move backwards in the instructions to the corresponding [ . [ and ] form a while loop. Obviously, they must be balanced. Let's look at some basic brainfuck programs. ++++++ [ > ++++++++++ < - ] > +++++ . This program prints out the letter 'A'. First, it increments cell #1 to 6. Cell #1 will be used for looping. Then, it enters the loop ([) and moves to cell #2. It increments cell #2 10 times, moves back to cell #1, and decrements cell #1. This loop happens 6 times (it takes 6 decrements for cell #1 to reach 0, at which point it skips to the corresponding ] and continues on). At this point, we're on cell #1, which has a value of 0, while cell #2 has a value of 60. We move on cell #2, increment 5 times, for a value of 65, and then print cell #2's value. 65 is 'A' in ASCII, so 'A' is printed to the terminal. , [ > + < - ] > . This program reads a character from the user input and copies the character into cell #1. Then we start a loop. Move to cell #2, increment the value at cell #2, move back to cell #1, and decrement the value at cell #1. This continues on until cell #1 is 0, and cell #2 holds cell #1's old value. Because we're on cell #1 at the end of the loop, move to cell #2, and then print out the value in ASCII. Also keep in mind that the spaces are purely for readability purposes. You could just as easily write it as: ,[>+<-]>. Try and figure out what this program does: ,>,< [ > [ >+ >+ << -] >> [- << + >>] <<< -] >> This program takes two numbers for input, and multiplies them. The gist is it first reads in two inputs. Then it starts the outer loop, conditioned on cell #1. Then it moves to cell #2, and starts the inner loop conditioned on cell #2, incrementing cell #3. However, there comes a problem: At the end of the inner loop, cell #2 is zero. In that case, inner loop won't work anymore since next time. To solve this problem, we also increment cell #4, and then recopy cell #4 into cell #2. Then cell #3 is the result. ``` And that's brainfuck. Not that hard, eh? For fun, you can write your own brainfuck programs, or you can write a brainfuck interpreter in another language. The interpreter is fairly simple to implement, but if you're a masochist, try writing a brainfuck interpreter… in brainfuck. --- name: perl category: language language: perl filename: learnperl-bg.pl contributors: - ["Korjavin Ivan", "http://github.com/korjavin"] - ["Dan Book", "http://github.com/Grinnz"] translators: - ["Красимир Беров", "https://github.com/kberov"] lang: bg-bg --- Perl 5 е изключително мощен език за програмиране с широка област на приложение и над 25 годишна история. Perl 5 работи на повече от 100 операционни системи от мини до супер-компютри и е подходящ както за бърза разработка на скриптове така и за огромни приложения. ```perl # Едноредовите коментари започват със знака диез. #### Стриктен режим и предупреждения use strict; use warnings; # Силно препоръчително е всички скриптове и модули да включват тези редове. # strict спира компилацията в случай на необявени предварително променливи. # warnings показва предупредителни съобщения в случай на често допускани грешки, # например използване на променливи без стойност в низове. #### Типове променливи в Perl # Променливите започват със съответен знак (sigil - от латински sigillum ), # който представлява символ, указващ типа на променливата. Името на самата # променлива започва с буква или знак за подчертаване (_), следван от какъвто и # да е брой букви, цифри или знаци за подчертаване. Забележете, че ако напишете # 'use utf8;' (без кавичките), можете да използвате всякакви букви за имена на # променливите, включително и български. ### Perl има три главни типа променливи: $scalar (скалар), @array (масив), and %hash (хеш). ## Скалари # Скаларът представлява единична стойност: my $animal = "camel"; my $answer = 42; use utf8; my $животно = 'камила'; # Стойностите на скаларите могат да бъдат низове, цели числа или числа с # плаваща запетая (десетични дроби). Perl автоматично ги ползва и превръща от # един тип стойност в друга, според както е необходимо. ## Масиви # Масивът представлява списък от стойности: my @animals = ("камила", "llama", "owl"); my @numbers = (23, 42, 69); my @mixed = ("camel", 42, 1.23); # Елементите на масива се достъпват като се използват квадратни скоби и $, # който указва каква стойност ще бъде върната (скалар). my $second = $animals[1]; ## Хешове # Хешът представлява набор от двойки ключ/стойност: my %fruit_color = ("ябълка", "червена", "banana", "yellow"); # Може да използвате празно пространство и оператора "=>" (тлъста запетая), # за да ги изложите по-прегледно: %fruit_color = ( ябълка => "червена", banana => "yellow", ); # Елементите (стойностите) от хеша се достъпват чрез използване на ключовете. # Ключовете се ограждат с фигурни скоби и се поставя $ пред името на хеша. my $color = $fruit_color{ябълка}; # Скаларите, масивите и хешовете са документирани по-пълно в perldata. # На командния ред напишете (без кавичките) 'perldoc perldata'. #### Указатели (Референции) # По-сложни типове данни могат да бъдат създавани чрез използване на указатели, # които ви позволяват да изграждате масиви и хешове в други масиви и хешове. my $array_ref = \@array; my $hash_ref = \%hash; my @array_of_arrays = (\@array1, \@array2, \@array3); # Също така можете да създавате безименни масиви и хешове, към които сочат само # указатели. my $fruits = ["apple", "banana"]; my $colors = {apple => "red", banana => "yellow"}; # Можете да достигате до безименните структури като поставяте отпред съответния # знак на структурата, която искате да достъпите (дереферирате). my @fruits_array = @$fruits; my %colors_hash = %$colors; # Можете да използвате оператора стрелка (->), за да достигнете до отделна # скаларна стойност. my $first = $array_ref->[0]; my $value = $hash_ref->{banana}; # Вижте perlreftut и perlref, където ще намерите по-задълбочена документация за # указателите (референциите). #### Условни изрази и цикли # В Perl ще срещнете повечето от обичайните изрази за условия и обхождане (цикли). if ($var) { ... } elsif ($var eq 'bar') { ... } else { ... } unless (условие) { ... } # Това е друг, по-четим вариант на "if (!условие)" # Perl-овския начин след-условие print "Yow!" if $zippy; print "Нямаме банани" unless $bananas; # докато while (условие) { ... } # цикли for и повторение for (my $i = 0; $i < $max; $i++) { print "index is $i"; } for (my $i = 0; $i < @elements; $i++) { print "Current element is " . $elements[$i]; } for my $element (@elements) { print $element; } # мълчаливо - използва се подразбиращата се променлива $_. for (@elements) { print; } # Отново Perl-овския начин след- print for @elements; # отпечатване на стойностите чрез обхождане ключовете на указател към хеш print $hash_ref->{$_} for keys %$hash_ref; #### Регулярни (обикновени) изрази # Поддръжката на регулярни изрази е залеганала дълбоко в Perl. Задълбочена # документация ще намерите в perlrequick, perlretut и на други места. # Но ето накратко: # Просто съвпадение if (/foo/) { ... } # истина ако $_ съдържа "foo" if ($x =~ /foo/) { ... } # истина ако $x съдържа "foo" # Просто заместване $x =~ s/foo/bar/; # замества foo с bar в $x $x =~ s/foo/bar/g; # Замества ВСИЧКИ ПОЯВИ на foo с bar в $x #### Файлове и Вход/Изход (I/O) # Можете да отворите файл за въвеждане на данни в него или за извеждане на # данни от него като използвате функцията "open()". open(my $in, "<", "input.txt") or die "Не мога да отворя input.txt: $!"; open(my $out, ">", "output.txt") or die "Can't open output.txt: $!"; open(my $log, ">>", "my.log") or die "Can't open my.log: $!"; # Можете да четете от отворен файлов манипулатор като използвате оператора # "<>". В скаларен контекст той чете по един ред от файла наведнъж, а в списъчен # контекст изчита всички редове от файла наведнъж като присвоява всеки ред на # масива: my $line = <$in>; my @lines = <$in>; #### Подпрограми (функции) # Да се пишат подпрограми е лесно: sub logger { my $logmessage = shift; open my $logfile, ">>", "my.log" or die "Could not open my.log: $!"; print $logfile $logmessage; } # Сега можем да ползваме подпрограмата като всяка друга вградена функция: logger("Имаме подпрограма, която пише във файл-отчет!"); #### Модули # Модулът е набор от програмен код на Perl, обикновено подпрограми, който може # да бъде използван в друг програмен код на Perl. Обикновено се съхранява във # файл с разширение .pm, така че perl (програмата) да може лесно да го разпознае. # В MyModule.pm package MyModule; use strict; use warnings; sub trim { my $string = shift; $string =~ s/^\s+//; $string =~ s/\s+$//; return $string; } 1; # От другаде: use MyModule; MyModule::trim($string); # Чрез модула Exporter може да направите функциите си износни, така че други # програми да могат да ги внасят (импортират). # Такива функции се използват така: use MyModule 'trim'; trim($string); # Много Perl-модули могат да се свалят от CPAN (http://www.cpan.org/). Те # притежават редица полезни свойства, които ще ви помогнат да си свършите работа # без да откривате колелото. Голям брой известни модули като Exporter са включени # в дистрибуцията на самия Perl. Вижте perlmod за повече подробности, свързани с # модулите в Perl. #### Обекти # Обектите в Perl са просто референции, които знаят на кой клас (пакет) # принадлежат. По този начин методите (подпрограми), които се извикват срещу # тях могат да бъдат намерени в съответния клас. За да се случи това, в # конструкторите (обикновено new) се използва вградената функция # bless. Ако използвате обаче модули като Moose или Moo, няма да ви се налага # сами да извиквате bless (ще видите малко по-долу). package MyCounter; use strict; use warnings; sub new { my $class = shift; my $self = {count => 0}; return bless $self, $class; } sub count { my $self = shift; return $self->{count}; } sub increment { my $self = shift; $self->{count}++; } 1; # Методите могат да се извикват на клас или на обект като се използва оператора # стрелка (->). use MyCounter; my $counter = MyCounter->new; print $counter->count, "\n"; # 0 $counter->increment; print $counter->count, "\n"; # 1 # Модулите Moose и Moo от CPAN ви помагат леснот да създавате класове. Те # предоставят готов конструктор (new) и прост синтаксис за деклариране на # свойства на обектите (attributes). Този клас може да се използва по същия начин # като предишния по-горе. package MyCounter; use Moo; # внася strict и warnings has 'count' => (is => 'rwp', default => 0, init_arg => undef); sub increment { my $self = shift; $self->_set_count($self->count + 1); } 1; # Обектно-ориентираното програмиране е разгледано по-задълбочено в perlootut, # а изпълнението му на ниско ниво в Perl е обяснено в perlobj. ``` #### Често задавани въпроси (FAQ) # perlfaq съдържа въпроси и отговори, отнасящи се до много общи задачи и предлага # за ползване добри модлули от CPAN, подходящи за решаване на различни проблеми. #### Повече за четене - [Въведение в Perl](http://www.slideshare.net/kberov/01-intro-bg) - [PERL - Курс на МГУ "Св.Иван Рилски" (13 ЧАСТИ)](http://www.mgu.bg/drugi/ebooks/belchevski/perl.html) - [perl-tutorial](http://perl-tutorial.org/) - [Learn at www.perl.com](http://www.perl.org/learn.html) - [perldoc](http://perldoc.perl.org/) - и идващото с perl: `perldoc perlintro` --- language: c++ filename: learncpp.cpp contributors: - ["Steven Basart", "http://github.com/xksteven"] - ["Matt Kline", "https://github.com/mrkline"] - ["Geoff Liu", "http://geoffliu.me"] - ["Connor Waters", "http://github.com/connorwaters"] - ["Ankush Goyal", "http://github.com/ankushg07"] - ["Jatin Dhankhar", "https://github.com/jatindhankhar"] --- C++ is a systems programming language that, [according to its inventor Bjarne Stroustrup](http://channel9.msdn.com/Events/Lang-NEXT/Lang-NEXT-2014/Keynote), was designed to - be a "better C" - support data abstraction - support object-oriented programming - support generic programming Though its syntax can be more difficult or complex than newer languages, it is widely used because it compiles to native instructions that can be directly run by the processor and offers tight control over hardware (like C) while offering high-level features such as generics, exceptions, and classes. This combination of speed and functionality makes C++ one of the most widely-used programming languages. ```c++ ////////////////// // Comparison to C ////////////////// // C++ is _almost_ a superset of C and shares its basic syntax for // variable declarations, primitive types, and functions. // Just like in C, your program's entry point is a function called // main with an integer return type. // This value serves as the program's exit status. // See http://en.wikipedia.org/wiki/Exit_status for more information. int main(int argc, char** argv) { // Command line arguments are passed in by argc and argv in the same way // they are in C. // argc indicates the number of arguments, // and argv is an array of C-style strings (char*) // representing the arguments. // The first argument is the name by which the program was called. // argc and argv can be omitted if you do not care about arguments, // giving the function signature of int main() // An exit status of 0 indicates success. return 0; } // However, C++ varies in some of the following ways: // In C++, character literals are chars sizeof('c') == sizeof(char) == 1 // In C, character literals are ints sizeof('c') == sizeof(int) // C++ has strict prototyping void func(); // function which accepts no arguments // In C void func(); // function which may accept any number of arguments // Use nullptr instead of NULL in C++ int* ip = nullptr; // C standard headers are available in C++, // but are prefixed with "c" and have no .h suffix. #include int main() { printf("Hello, world!\n"); return 0; } /////////////////////// // Function overloading /////////////////////// // C++ supports function overloading // provided each function takes different parameters. void print(char const* myString) { printf("String %s\n", myString); } void print(int myInt) { printf("My int is %d", myInt); } int main() { print("Hello"); // Resolves to void print(const char*) print(15); // Resolves to void print(int) } ///////////////////////////// // Default function arguments ///////////////////////////// // You can provide default arguments for a function // if they are not provided by the caller. void doSomethingWithInts(int a = 1, int b = 4) { // Do something with the ints here } int main() { doSomethingWithInts(); // a = 1, b = 4 doSomethingWithInts(20); // a = 20, b = 4 doSomethingWithInts(20, 5); // a = 20, b = 5 } // Default arguments must be at the end of the arguments list. void invalidDeclaration(int a = 1, int b) // Error! { } ///////////// // Namespaces ///////////// // Namespaces provide separate scopes for variable, function, // and other declarations. // Namespaces can be nested. namespace First { namespace Nested { void foo() { printf("This is First::Nested::foo\n"); } } // end namespace Nested } // end namespace First namespace Second { void foo() { printf("This is Second::foo\n"); } } void foo() { printf("This is global foo\n"); } int main() { // Includes all symbols from namespace Second into the current scope. Note // that simply foo() no longer works, since it is now ambiguous whether // we're calling the foo in namespace Second or the top level. using namespace Second; Second::foo(); // prints "This is Second::foo" First::Nested::foo(); // prints "This is First::Nested::foo" ::foo(); // prints "This is global foo" } /////////////// // Input/Output /////////////// // C++ input and output uses streams // cin, cout, and cerr represent stdin, stdout, and stderr. // << is the insertion operator and >> is the extraction operator. #include // Include for I/O streams using namespace std; // Streams are in the std namespace (standard library) int main() { int myInt; // Prints to stdout (or terminal/screen) cout << "Enter your favorite number:\n"; // Takes in input cin >> myInt; // cout can also be formatted cout << "Your favorite number is " << myInt << "\n"; // prints "Your favorite number is " cerr << "Used for error messages"; } ////////// // Strings ////////// // Strings in C++ are objects and have many member functions #include using namespace std; // Strings are also in the namespace std (standard library) string myString = "Hello"; string myOtherString = " World"; // + is used for concatenation. cout << myString + myOtherString; // "Hello World" cout << myString + " You"; // "Hello You" // C++ strings are mutable. myString.append(" Dog"); cout << myString; // "Hello Dog" ///////////// // References ///////////// // In addition to pointers like the ones in C, // C++ has _references_. // These are pointer types that cannot be reassigned once set // and cannot be null. // They also have the same syntax as the variable itself: // No * is needed for dereferencing and // & (address of) is not used for assignment. using namespace std; string foo = "I am foo"; string bar = "I am bar"; string& fooRef = foo; // This creates a reference to foo. fooRef += ". Hi!"; // Modifies foo through the reference cout << fooRef; // Prints "I am foo. Hi!" // Doesn't reassign "fooRef". This is the same as "foo = bar", and // foo == "I am bar" // after this line. cout << &fooRef << endl; //Prints the address of foo fooRef = bar; cout << &fooRef << endl; //Still prints the address of foo cout << fooRef; // Prints "I am bar" //The address of fooRef remains the same, i.e. it is still referring to foo. const string& barRef = bar; // Create a const reference to bar. // Like C, const values (and pointers and references) cannot be modified. barRef += ". Hi!"; // Error, const references cannot be modified. // Sidetrack: Before we talk more about references, we must introduce a concept // called a temporary object. Suppose we have the following code: string tempObjectFun() { ... } string retVal = tempObjectFun(); // What happens in the second line is actually: // - a string object is returned from tempObjectFun // - a new string is constructed with the returned object as argument to the // constructor // - the returned object is destroyed // The returned object is called a temporary object. Temporary objects are // created whenever a function returns an object, and they are destroyed at the // end of the evaluation of the enclosing expression (Well, this is what the // standard says, but compilers are allowed to change this behavior. Look up // "return value optimization" if you're into this kind of details). So in this // code: foo(bar(tempObjectFun())) // assuming foo and bar exist, the object returned from tempObjectFun is // passed to bar, and it is destroyed before foo is called. // Now back to references. The exception to the "at the end of the enclosing // expression" rule is if a temporary object is bound to a const reference, in // which case its life gets extended to the current scope: void constReferenceTempObjectFun() { // constRef gets the temporary object, and it is valid until the end of this // function. const string& constRef = tempObjectFun(); ... } // Another kind of reference introduced in C++11 is specifically for temporary // objects. You cannot have a variable of its type, but it takes precedence in // overload resolution: void someFun(string& s) { ... } // Regular reference void someFun(string&& s) { ... } // Reference to temporary object string foo; someFun(foo); // Calls the version with regular reference someFun(tempObjectFun()); // Calls the version with temporary reference // For example, you will see these two versions of constructors for // std::basic_string: basic_string(const basic_string& other); basic_string(basic_string&& other); // Idea being if we are constructing a new string from a temporary object (which // is going to be destroyed soon anyway), we can have a more efficient // constructor that "salvages" parts of that temporary string. You will see this // concept referred to as "move semantics". ///////////////////// // Enums ///////////////////// // Enums are a way to assign a value to a constant most commonly used for // easier visualization and reading of code enum ECarTypes { Sedan, Hatchback, SUV, Wagon }; ECarTypes GetPreferredCarType() { return ECarTypes::Hatchback; } // As of C++11 there is an easy way to assign a type to the enum which can be // useful in serialization of data and converting enums back-and-forth between // the desired type and their respective constants enum ECarTypes : uint8_t { Sedan, // 0 Hatchback, // 1 SUV = 254, // 254 Hybrid // 255 }; void WriteByteToFile(uint8_t InputValue) { // Serialize the InputValue to a file } void WritePreferredCarTypeToFile(ECarTypes InputCarType) { // The enum is implicitly converted to a uint8_t due to its declared enum type WriteByteToFile(InputCarType); } // On the other hand you may not want enums to be accidentally cast to an integer // type or to other enums so it is instead possible to create an enum class which // won't be implicitly converted enum class ECarTypes : uint8_t { Sedan, // 0 Hatchback, // 1 SUV = 254, // 254 Hybrid // 255 }; void WriteByteToFile(uint8_t InputValue) { // Serialize the InputValue to a file } void WritePreferredCarTypeToFile(ECarTypes InputCarType) { // Won't compile even though ECarTypes is a uint8_t due to the enum // being declared as an "enum class"! WriteByteToFile(InputCarType); } ////////////////////////////////////////// // Classes and object-oriented programming ////////////////////////////////////////// // First example of classes #include // Declare a class. // Classes are usually declared in header (.h or .hpp) files. class Dog { // Member variables and functions are private by default. std::string name; int weight; // All members following this are public // until "private:" or "protected:" is found. public: // Default constructor Dog(); // Member function declarations (implementations to follow) // Note that we use std::string here instead of placing // using namespace std; // above. // Never put a "using namespace" statement in a header. void setName(const std::string& dogsName); void setWeight(int dogsWeight); // Functions that do not modify the state of the object // should be marked as const. // This allows you to call them if given a const reference to the object. // Also note the functions must be explicitly declared as _virtual_ // in order to be overridden in derived classes. // Functions are not virtual by default for performance reasons. virtual void print() const; // Functions can also be defined inside the class body. // Functions defined as such are automatically inlined. void bark() const { std::cout << name << " barks!\n"; } // Along with constructors, C++ provides destructors. // These are called when an object is deleted or falls out of scope. // This enables powerful paradigms such as RAII // (see below) // The destructor should be virtual if a class is to be derived from; // if it is not virtual, then the derived class' destructor will // not be called if the object is destroyed through a base-class reference // or pointer. virtual ~Dog(); }; // A semicolon must follow the class definition. // Class member functions are usually implemented in .cpp files. Dog::Dog() { std::cout << "A dog has been constructed\n"; } // Objects (such as strings) should be passed by reference // if you are modifying them or const reference if you are not. void Dog::setName(const std::string& dogsName) { name = dogsName; } void Dog::setWeight(int dogsWeight) { weight = dogsWeight; } // Notice that "virtual" is only needed in the declaration, not the definition. void Dog::print() const { std::cout << "Dog is " << name << " and weighs " << weight << "kg\n"; } Dog::~Dog() { std::cout << "Goodbye " << name << "\n"; } int main() { Dog myDog; // prints "A dog has been constructed" myDog.setName("Barkley"); myDog.setWeight(10); myDog.print(); // prints "Dog is Barkley and weighs 10 kg" return 0; } // prints "Goodbye Barkley" // Inheritance: // This class inherits everything public and protected from the Dog class // as well as private but may not directly access private members/methods // without a public or protected method for doing so class OwnedDog : public Dog { public: void setOwner(const std::string& dogsOwner); // Override the behavior of the print function for all OwnedDogs. See // http://en.wikipedia.org/wiki/Polymorphism_(computer_science)#Subtyping // for a more general introduction if you are unfamiliar with // subtype polymorphism. // The override keyword is optional but makes sure you are actually // overriding the method in a base class. void print() const override; private: std::string owner; }; // Meanwhile, in the corresponding .cpp file: void OwnedDog::setOwner(const std::string& dogsOwner) { owner = dogsOwner; } void OwnedDog::print() const { Dog::print(); // Call the print function in the base Dog class std::cout << "Dog is owned by " << owner << "\n"; // Prints "Dog is and weights " // "Dog is owned by " } ////////////////////////////////////////// // Initialization and Operator Overloading ////////////////////////////////////////// // In C++ you can overload the behavior of operators such as +, -, *, /, etc. // This is done by defining a function which is called // whenever the operator is used. #include using namespace std; class Point { public: // Member variables can be given default values in this manner. double x = 0; double y = 0; // Define a default constructor which does nothing // but initialize the Point to the default value (0, 0) Point() { }; // The following syntax is known as an initialization list // and is the proper way to initialize class member values Point (double a, double b) : x(a), y(b) { /* Do nothing except initialize the values */ } // Overload the + operator. Point operator+(const Point& rhs) const; // Overload the += operator Point& operator+=(const Point& rhs); // It would also make sense to add the - and -= operators, // but we will skip those for brevity. }; Point Point::operator+(const Point& rhs) const { // Create a new point that is the sum of this one and rhs. return Point(x + rhs.x, y + rhs.y); } Point& Point::operator+=(const Point& rhs) { x += rhs.x; y += rhs.y; return *this; } int main () { Point up (0,1); Point right (1,0); // This calls the Point + operator // Point up calls the + (function) with right as its parameter Point result = up + right; // Prints "Result is upright (1,1)" cout << "Result is upright (" << result.x << ',' << result.y << ")\n"; return 0; } ///////////////////// // Templates ///////////////////// // Templates in C++ are mostly used for generic programming, though they are // much more powerful than generic constructs in other languages. They also // support explicit and partial specialization and functional-style type // classes; in fact, they are a Turing-complete functional language embedded // in C++! // We start with the kind of generic programming you might be familiar with. To // define a class or function that takes a type parameter: template class Box { public: // In this class, T can be used as any other type. void insert(const T&) { ... } }; // During compilation, the compiler actually generates copies of each template // with parameters substituted, so the full definition of the class must be // present at each invocation. This is why you will see template classes defined // entirely in header files. // To instantiate a template class on the stack: Box intBox; // and you can use it as you would expect: intBox.insert(123); // You can, of course, nest templates: Box > boxOfBox; boxOfBox.insert(intBox); // Until C++11, you had to place a space between the two '>'s, otherwise '>>' // would be parsed as the right shift operator. // You will sometimes see // template // instead. The 'class' keyword and 'typename' keywords are _mostly_ // interchangeable in this case. For the full explanation, see // http://en.wikipedia.org/wiki/Typename // (yes, that keyword has its own Wikipedia page). // Similarly, a template function: template void barkThreeTimes(const T& input) { input.bark(); input.bark(); input.bark(); } // Notice that nothing is specified about the type parameters here. The compiler // will generate and then type-check every invocation of the template, so the // above function works with any type 'T' that has a const 'bark' method! Dog fluffy; fluffy.setName("Fluffy") barkThreeTimes(fluffy); // Prints "Fluffy barks" three times. // Template parameters don't have to be classes: template void printMessage() { cout << "Learn C++ in " << Y << " minutes!" << endl; } // And you can explicitly specialize templates for more efficient code. Of // course, most real-world uses of specialization are not as trivial as this. // Note that you still need to declare the function (or class) as a template // even if you explicitly specified all parameters. template<> void printMessage<10>() { cout << "Learn C++ faster in only 10 minutes!" << endl; } printMessage<20>(); // Prints "Learn C++ in 20 minutes!" printMessage<10>(); // Prints "Learn C++ faster in only 10 minutes!" ///////////////////// // Exception Handling ///////////////////// // The standard library provides a few exception types // (see http://en.cppreference.com/w/cpp/error/exception) // but any type can be thrown an as exception #include #include // All exceptions thrown inside the _try_ block can be caught by subsequent // _catch_ handlers. try { // Do not allocate exceptions on the heap using _new_. throw std::runtime_error("A problem occurred"); } // Catch exceptions by const reference if they are objects catch (const std::exception& ex) { std::cout << ex.what(); } // Catches any exception not caught by previous _catch_ blocks catch (...) { std::cout << "Unknown exception caught"; throw; // Re-throws the exception } /////// // RAII /////// // RAII stands for "Resource Acquisition Is Initialization". // It is often considered the most powerful paradigm in C++ // and is the simple concept that a constructor for an object // acquires that object's resources and the destructor releases them. // To understand how this is useful, // consider a function that uses a C file handle: void doSomethingWithAFile(const char* filename) { // To begin with, assume nothing can fail. FILE* fh = fopen(filename, "r"); // Open the file in read mode. doSomethingWithTheFile(fh); doSomethingElseWithIt(fh); fclose(fh); // Close the file handle. } // Unfortunately, things are quickly complicated by error handling. // Suppose fopen can fail, and that doSomethingWithTheFile and // doSomethingElseWithIt return error codes if they fail. // (Exceptions are the preferred way of handling failure, // but some programmers, especially those with a C background, // disagree on the utility of exceptions). // We now have to check each call for failure and close the file handle // if a problem occurred. bool doSomethingWithAFile(const char* filename) { FILE* fh = fopen(filename, "r"); // Open the file in read mode if (fh == nullptr) // The returned pointer is null on failure. return false; // Report that failure to the caller. // Assume each function returns false if it failed if (!doSomethingWithTheFile(fh)) { fclose(fh); // Close the file handle so it doesn't leak. return false; // Propagate the error. } if (!doSomethingElseWithIt(fh)) { fclose(fh); // Close the file handle so it doesn't leak. return false; // Propagate the error. } fclose(fh); // Close the file handle so it doesn't leak. return true; // Indicate success } // C programmers often clean this up a little bit using goto: bool doSomethingWithAFile(const char* filename) { FILE* fh = fopen(filename, "r"); if (fh == nullptr) return false; if (!doSomethingWithTheFile(fh)) goto failure; if (!doSomethingElseWithIt(fh)) goto failure; fclose(fh); // Close the file return true; // Indicate success failure: fclose(fh); return false; // Propagate the error } // If the functions indicate errors using exceptions, // things are a little cleaner, but still sub-optimal. void doSomethingWithAFile(const char* filename) { FILE* fh = fopen(filename, "r"); // Open the file in read mode if (fh == nullptr) throw std::runtime_error("Could not open the file."); try { doSomethingWithTheFile(fh); doSomethingElseWithIt(fh); } catch (...) { fclose(fh); // Be sure to close the file if an error occurs. throw; // Then re-throw the exception. } fclose(fh); // Close the file // Everything succeeded } // Compare this to the use of C++'s file stream class (fstream) // fstream uses its destructor to close the file. // Recall from above that destructors are automatically called // whenever an object falls out of scope. void doSomethingWithAFile(const std::string& filename) { // ifstream is short for input file stream std::ifstream fh(filename); // Open the file // Do things with the file doSomethingWithTheFile(fh); doSomethingElseWithIt(fh); } // The file is automatically closed here by the destructor // This has _massive_ advantages: // 1. No matter what happens, // the resource (in this case the file handle) will be cleaned up. // Once you write the destructor correctly, // It is _impossible_ to forget to close the handle and leak the resource. // 2. Note that the code is much cleaner. // The destructor handles closing the file behind the scenes // without you having to worry about it. // 3. The code is exception safe. // An exception can be thrown anywhere in the function and cleanup // will still occur. // All idiomatic C++ code uses RAII extensively for all resources. // Additional examples include // - Memory using unique_ptr and shared_ptr // - Containers - the standard library linked list, // vector (i.e. self-resizing array), hash maps, and so on // all automatically destroy their contents when they fall out of scope. // - Mutexes using lock_guard and unique_lock // containers with object keys of non-primitive values (custom classes) require // compare function in the object itself or as a function pointer. Primitives // have default comparators, but you can override it. class Foo { public: int j; Foo(int a) : j(a) {} }; struct compareFunction { bool operator()(const Foo& a, const Foo& b) const { return a.j < b.j; } }; //this isn't allowed (although it can vary depending on compiler) //std::map fooMap; std::map fooMap; fooMap[Foo(1)] = 1; fooMap.find(Foo(1)); //true /////////////////////////////////////// // Lambda Expressions (C++11 and above) /////////////////////////////////////// // lambdas are a convenient way of defining an anonymous function // object right at the location where it is invoked or passed as // an argument to a function. // For example, consider sorting a vector of pairs using the second // value of the pair vector > tester; tester.push_back(make_pair(3, 6)); tester.push_back(make_pair(1, 9)); tester.push_back(make_pair(5, 0)); // Pass a lambda expression as third argument to the sort function // sort is from the header sort(tester.begin(), tester.end(), [](const pair& lhs, const pair& rhs) { return lhs.second < rhs.second; }); // Notice the syntax of the lambda expression, // [] in the lambda is used to "capture" variables // The "Capture List" defines what from the outside of the lambda should be available inside the function body and how. // It can be either: // 1. a value : [x] // 2. a reference : [&x] // 3. any variable currently in scope by reference [&] // 4. same as 3, but by value [=] // Example: vector dog_ids; // number_of_dogs = 3; for(int i = 0; i < 3; i++) { dog_ids.push_back(i); } int weight[3] = {30, 50, 10}; // Say you want to sort dog_ids according to the dogs' weights // So dog_ids should in the end become: [2, 0, 1] // Here's where lambda expressions come in handy sort(dog_ids.begin(), dog_ids.end(), [&weight](const int &lhs, const int &rhs) { return weight[lhs] < weight[rhs]; }); // Note we captured "weight" by reference in the above example. // More on Lambdas in C++ : http://stackoverflow.com/questions/7627098/what-is-a-lambda-expression-in-c11 /////////////////////////////// // Range For (C++11 and above) /////////////////////////////// // You can use a range for loop to iterate over a container int arr[] = {1, 10, 3}; for(int elem: arr){ cout << elem << endl; } // You can use "auto" and not worry about the type of the elements of the container // For example: for(auto elem: arr) { // Do something with each element of arr } ///////////////////// // Fun stuff ///////////////////// // Aspects of C++ that may be surprising to newcomers (and even some veterans). // This section is, unfortunately, wildly incomplete; C++ is one of the easiest // languages with which to shoot yourself in the foot. // You can override private methods! class Foo { virtual void bar(); }; class FooSub : public Foo { virtual void bar(); // Overrides Foo::bar! }; // 0 == false == NULL (most of the time)! bool* pt = new bool; *pt = 0; // Sets the value points by 'pt' to false. pt = 0; // Sets 'pt' to the null pointer. Both lines compile without warnings. // nullptr is supposed to fix some of that issue: int* pt2 = new int; *pt2 = nullptr; // Doesn't compile pt2 = nullptr; // Sets pt2 to null. // There is an exception made for bools. // This is to allow you to test for null pointers with if(!ptr), // but as a consequence you can assign nullptr to a bool directly! *pt = nullptr; // This still compiles, even though '*pt' is a bool! // '=' != '=' != '='! // Calls Foo::Foo(const Foo&) or some variant (see move semantics) copy // constructor. Foo f2; Foo f1 = f2; // Calls Foo::Foo(const Foo&) or variant, but only copies the 'Foo' part of // 'fooSub'. Any extra members of 'fooSub' are discarded. This sometimes // horrifying behavior is called "object slicing." FooSub fooSub; Foo f1 = fooSub; // Calls Foo::operator=(Foo&) or variant. Foo f1; f1 = f2; /////////////////////////////////////// // Tuples (C++11 and above) /////////////////////////////////////// #include // Conceptually, Tuples are similar to old data structures (C-like structs) but instead of having named data members, // its elements are accessed by their order in the tuple. // We start with constructing a tuple. // Packing values into tuple auto first = make_tuple(10, 'A'); const int maxN = 1e9; const int maxL = 15; auto second = make_tuple(maxN, maxL); // Printing elements of 'first' tuple cout << get<0>(first) << " " << get<1>(first) << "\n"; //prints : 10 A // Printing elements of 'second' tuple cout << get<0>(second) << " " << get<1>(second) << "\n"; // prints: 1000000000 15 // Unpacking tuple into variables int first_int; char first_char; tie(first_int, first_char) = first; cout << first_int << " " << first_char << "\n"; // prints : 10 A // We can also create tuple like this. tuple third(11, 'A', 3.14141); // tuple_size returns number of elements in a tuple (as a constexpr) cout << tuple_size::value << "\n"; // prints: 3 // tuple_cat concatenates the elements of all the tuples in the same order. auto concatenated_tuple = tuple_cat(first, second, third); // concatenated_tuple becomes = (10, 'A', 1e9, 15, 11, 'A', 3.14141) cout << get<0>(concatenated_tuple) << "\n"; // prints: 10 cout << get<3>(concatenated_tuple) << "\n"; // prints: 15 cout << get<5>(concatenated_tuple) << "\n"; // prints: 'A' ///////////////////// // Containers ///////////////////// // Containers or the Standard Template Library are some predefined templates. // They manage the storage space for its elements and provide // member functions to access and manipulate them. // Few containers are as follows: // Vector (Dynamic array) // Allow us to Define the Array or list of objects at run time #include vector Vector_name; // used to initialize the vector cin >> val; Vector_name.push_back(val); // will push the value of variable into array // To iterate through vector, we have 2 choices: // Normal looping for(int i=0; i::iterator it; // initialize the iterator for vector for(it=vector_name.begin(); it!=vector_name.end();++it) // For accessing the element of the vector // Operator [] var = vector_name[index]; // Will assign value at that index to var // Set // Sets are containers that store unique elements following a specific order. // Set is a very useful container to store unique values in sorted order // without any other functions or code. #include set ST; // Will initialize the set of int data type ST.insert(30); // Will insert the value 30 in set ST ST.insert(10); // Will insert the value 10 in set ST ST.insert(20); // Will insert the value 20 in set ST ST.insert(30); // Will insert the value 30 in set ST // Now elements of sets are as follows // 10 20 30 // To erase an element ST.erase(20); // Will erase element with value 20 // Set ST: 10 30 // To iterate through Set we use iterators set::iterator it; for(it=ST.begin();it map mymap; // Will initialize the map with key as char and value as int mymap.insert(pair('A',1)); // Will insert value 1 for key A mymap.insert(pair('Z',26)); // Will insert value 26 for key Z // To iterate map::iterator it; for (it=mymap.begin(); it!=mymap.end(); ++it) std::cout << it->first << "->" << it->second << '\n'; // Output: // A->1 // Z->26 // To find the value corresponding to a key it = mymap.find('Z'); cout << it->second; // Output: 26 /////////////////////////////////// // Logical and Bitwise operators ////////////////////////////////// // Most of the operators in C++ are same as in other languages // Logical operators // C++ uses Short-circuit evaluation for boolean expressions, i.e, the second argument is executed or // evaluated only if the first argument does not suffice to determine the value of the expression true && false // Performs **logical and** to yield false true || false // Performs **logical or** to yield true ! true // Performs **logical not** to yield false // Instead of using symbols equivalent keywords can be used true and false // Performs **logical and** to yield false true or false // Performs **logical or** to yield true not true // Performs **logical not** to yield false // Bitwise operators // **<<** Left Shift Operator // << shifts bits to the left 4 << 1 // Shifts bits of 4 to left by 1 to give 8 // x << n can be thought as x * 2^n // **>>** Right Shift Operator // >> shifts bits to the right 4 >> 1 // Shifts bits of 4 to right by 1 to give 2 // x >> n can be thought as x / 2^n ~4 // Performs a bitwise not 4 | 3 // Performs bitwise or 4 & 3 // Performs bitwise and 4 ^ 3 // Performs bitwise xor // Equivalent keywords are compl 4 // Performs a bitwise not 4 bitor 3 // Performs bitwise or 4 bitand 3 // Performs bitwise and 4 xor 3 // Performs bitwise xor ``` Further Reading: An up-to-date language reference can be found at Additional resources may be found at --- language: c filename: learnc.c contributors: - ["Adam Bard", "http://adambard.com/"] - ["Árpád Goretity", "http://twitter.com/H2CO3_iOS"] - ["Jakub Trzebiatowski", "http://cbs.stgn.pl"] - ["Marco Scannadinari", "https://marcoms.github.io"] - ["Zachary Ferguson", "https://github.io/zfergus2"] - ["himanshu", "https://github.com/himanshu81494"] --- Ah, C. Still **the** language of modern high-performance computing. C is the lowest-level language most programmers will ever use, but it more than makes up for it with raw speed. Just be aware of its manual memory management and C will take you as far as you need to go. ```c // Single-line comments start with // - only available in C99 and later. /* Multi-line comments look like this. They work in C89 as well. */ /* Multi-line comments don't nest /* Be careful */ // comment ends on this line... */ // ...not this one! // Constants: #define // Constants are written in all-caps out of convention, not requirement #define DAYS_IN_YEAR 365 // Enumeration constants are also ways to declare constants. // All statements must end with a semicolon enum days {SUN = 1, MON, TUE, WED, THU, FRI, SAT}; // MON gets 2 automatically, TUE gets 3, etc. // Import headers with #include #include #include #include // (File names between are headers from the C standard library.) // For your own headers, use double quotes instead of angle brackets: //#include "my_header.h" // Declare function signatures in advance in a .h file, or at the top of // your .c file. void function_1(); int function_2(void); // Must declare a 'function prototype' before main() when functions occur after // your main() function. int add_two_ints(int x1, int x2); // function prototype // although `int add_two_ints(int, int);` is also valid (no need to name the args), // it is recommended to name arguments in the prototype as well for easier inspection // Your program's entry point is a function called // main with an integer return type. int main(void) { // your program } // The command line arguments used to run your program are also passed to main // argc being the number of arguments - your program's name counts as 1 // argv is an array of character arrays - containing the arguments themselves // argv[0] = name of your program, argv[1] = first argument, etc. int main (int argc, char** argv) { // print output using printf, for "print formatted" // %d is an integer, \n is a newline printf("%d\n", 0); // => Prints 0 /////////////////////////////////////// // Types /////////////////////////////////////// // All variables MUST be declared at the top of the current block scope // we declare them dynamically along the code for the sake of the tutorial // ints are usually 4 bytes int x_int = 0; // shorts are usually 2 bytes short x_short = 0; // chars are guaranteed to be 1 byte char x_char = 0; char y_char = 'y'; // Char literals are quoted with '' // 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; // floats are usually 32-bit floating point numbers float x_float = 0.0f; // 'f' suffix here denotes floating point literal // doubles are usually 64-bit floating-point numbers double x_double = 0.0; // real numbers without any suffix are doubles // integer types may be unsigned (greater than or equal to zero) unsigned short ux_short; unsigned int ux_int; unsigned long long ux_long_long; // chars inside single quotes are integers in machine's character set. '0'; // => 48 in the ASCII character set. 'A'; // => 65 in the ASCII character set. // sizeof(T) gives you the size of a variable with type T in bytes // sizeof(obj) yields the size of the expression (variable, literal, etc.). printf("%zu\n", sizeof(int)); // => 4 (on most machines with 4-byte words) // If the argument of the `sizeof` operator is an expression, then its argument // is not evaluated (except VLAs (see below)). // The value it yields in this case is a compile-time constant. int a = 1; // size_t is an unsigned integer type of at least 2 bytes used to represent // the size of an object. size_t size = sizeof(a++); // a++ is not evaluated printf("sizeof(a++) = %zu where a = %d\n", size, a); // prints "sizeof(a++) = 4 where a = 1" (on a 32-bit architecture) // 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: char my_array[20] = {0}; // Indexing an array is like other languages -- or, // rather, other languages are like C my_array[0]; // => 0 // Arrays are mutable; it's just memory! my_array[1] = 2; printf("%d\n", my_array[1]); // => 2 // In C99 (and as an optional feature in C11), variable-length arrays (VLAs) // can be declared as well. The size of such an array need not be a compile // time constant: printf("Enter the array size: "); // ask the user for an array size int array_size; fscanf(stdin, "%d", &array_size); int var_length_array[array_size]; // declare the VLA printf("sizeof array = %zu\n", sizeof var_length_array); // Example: // > Enter the array size: 10 // > sizeof array = 40 // Strings are just arrays of chars terminated by a NULL (0x00) byte, // represented in strings as the special character '\0'. // (We don't have to include the NULL 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 printf("%d\n", a_string[16]); // => 0 // i.e., byte #17 is 0 (as are 18, 19, and 20) // If we have characters between single quotes, that's a character literal. // It's of type `int`, and *not* `char` (for historical reasons). int cha = 'a'; // fine char chb = 'a'; // fine too (implicit conversion from int to char) // Multi-dimensional arrays: int multi_array[2][5] = { {1, 2, 3, 4, 5}, {6, 7, 8, 9, 0} }; // access elements: int array_int = multi_array[0][2]; // => 3 /////////////////////////////////////// // Operators /////////////////////////////////////// // Shorthands for multiple declarations: int i1 = 1, i2 = 2; float f1 = 1.0, f2 = 2.0; int b, c; b = c = 0; // Arithmetic is straightforward i1 + i2; // => 3 i2 - i1; // => 1 i2 * i1; // => 2 i1 / i2; // => 0 (0.5, but truncated towards 0) // You need to cast at least one integer to float to get a floating-point result (float)i1 / i2; // => 0.5f i1 / (double)i2; // => 0.5 // Same with double f1 / f2; // => 0.5, plus or minus epsilon // Floating-point numbers and calculations are not exact // Modulo is there as well 11 % 3; // => 2 // Comparison operators are probably familiar, but // there is no Boolean type in C. We use ints instead. // (Or _Bool or bool in C99.) // 0 is false, anything else is true. (The comparison // operators always yield 0 or 1.) 3 == 2; // => 0 (false) 3 != 2; // => 1 (true) 3 > 2; // => 1 3 < 2; // => 0 2 <= 2; // => 1 2 >= 2; // => 1 // C is not Python - comparisons don't chain. // Warning: The line below will compile, but it means `(0 < a) < 2`. // This expression is always true, because (0 < a) could be either 1 or 0. // In this case it's 1, because (0 < 1). int between_0_and_2 = 0 < a < 2; // Instead use: int between_0_and_2 = 0 < a && a < 2; // Logic works on ints !3; // => 0 (Logical not) !0; // => 1 1 && 1; // => 1 (Logical and) 0 && 1; // => 0 0 || 1; // => 1 (Logical or) 0 || 0; // => 0 // Conditional ternary expression ( ? : ) int e = 5; int f = 10; int z; z = (e > f) ? e : f; // => 10 "if e > f return e, else return f." // Increment and decrement operators: int j = 0; int s = j++; // Return j THEN increase j. (s = 0, j = 1) s = ++j; // Increase j THEN return j. (s = 2, j = 2) // same with j-- and --j // Bitwise operators! ~0x0F; // => 0xFFFFFFF0 (bitwise negation, "1's complement", example result for 32-bit int) 0x0F & 0xF0; // => 0x00 (bitwise AND) 0x0F | 0xF0; // => 0xFF (bitwise OR) 0x04 ^ 0x0F; // => 0x0B (bitwise XOR) 0x01 << 1; // => 0x02 (bitwise left shift (by 1)) 0x02 >> 1; // => 0x01 (bitwise right shift (by 1)) // Be careful when shifting signed integers - the following are undefined: // - shifting into the sign bit of a signed integer (int a = 1 << 31) // - left-shifting a negative number (int a = -1 << 2) // - shifting by an offset which is >= the width of the type of the LHS: // int a = 1 << 32; // UB if int is 32 bits wide /////////////////////////////////////// // Control Structures /////////////////////////////////////// if (0) { printf("I am never run\n"); } else if (0) { printf("I am also never run\n"); } else { printf("I print\n"); } // While loops exist int ii = 0; while (ii < 10) { //ANY value less than ten is true. printf("%d, ", ii++); // ii++ increments ii AFTER using its current value. } // => prints "0, 1, 2, 3, 4, 5, 6, 7, 8, 9, " printf("\n"); int kk = 0; do { printf("%d, ", kk); } while (++kk < 10); // ++kk increments kk BEFORE using its current 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++) { printf("%d, ", jj); } // => prints "0, 1, 2, 3, 4, 5, 6, 7, 8, 9, " printf("\n"); // *****NOTES*****: // Loops and Functions MUST have a body. If no body is needed: int i; for (i = 0; i <= 5; i++) { ; // use semicolon to act as the body (null statement) } // Or for (i = 0; i <= 5; i++); // branching with multiple choices: switch() switch (a) { case 0: // labels need to be integral *constant* expressions printf("Hey, 'a' equals 0!\n"); break; // if you don't break, control flow falls over labels case 1: printf("Huh, 'a' equals 1!\n"); break; // Be careful - without a "break", execution continues until the // next "break" is reached. case 3: case 4: printf("Look at that.. 'a' is either 3, or 4\n"); break; default: // if `some_integral_expression` didn't match any of the labels fputs("Error!\n", stderr); exit(-1); break; } /* using "goto" in C */ typedef enum { false, true } bool; // for C don't have bool as data type :( bool disaster = false; int i, j; for(i=0;i<100;++i) for(j=0;j<100;++j) { if((i + j) >= 150) disaster = true; if(disaster) goto error; } error : printf("Error occurred at i = %d & j = %d.\n", i, j); /* https://ideone.com/GuPhd6 this will print out "Error occurred at i = 52 & j = 99." */ /////////////////////////////////////// // Typecasting /////////////////////////////////////// // Every value in C has a type, but you can cast one value into another type // if you want (with some constraints). int x_hex = 0x01; // You can assign vars with hex literals // Casting between types will attempt to preserve their numeric values printf("%d\n", x_hex); // => Prints 1 printf("%d\n", (short) x_hex); // => Prints 1 printf("%d\n", (char) x_hex); // => Prints 1 // Types will overflow without warning printf("%d\n", (unsigned char) 257); // => 1 (Max char = 255 if char is 8 bits long) // For determining the max value of a `char`, a `signed char` and an `unsigned char`, // respectively, use the CHAR_MAX, SCHAR_MAX and UCHAR_MAX macros from // 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 /////////////////////////////////////// // 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", (void *)&x); // Use & to retrieve the address of a variable // (%p formats an object pointer of type void *) // => Prints some address in memory; // Pointers start with * in their declaration int *px, not_a_pointer; // px is a pointer to an int px = &x; // Stores the address of x in px printf("%p\n", (void *)px); // => Prints some address in memory printf("%zu, %zu\n", sizeof(px), sizeof(not_a_pointer)); // => Prints "8, 4" on a typical 64-bit system // To retrieve the value at the address a pointer is pointing to, // put * in front to dereference it. // Note: yes, it may be confusing that '*' is used for _both_ declaring a // pointer and dereferencing it. printf("%d\n", *px); // => Prints 0, the value of x // You can also change the value the pointer is pointing to. // We'll have to wrap the dereference 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 // Arrays are a good way to allocate a contiguous block of memory int x_array[20]; //declares array of size 20 (cannot change size) int xx; for (xx = 0; xx < 20; xx++) { x_array[xx] = 20 - xx; } // Initialize x_array to 20, 19, 18,... 2, 1 // Declare a pointer of type int and initialize it to point to x_array int* x_ptr = x_array; // x_ptr now points to the first element in the array (the integer 20). // This works because arrays often decay into pointers to their first element. // For example, when an array is passed to a function or is assigned to a pointer, // it decays into (implicitly converted to) a pointer. // Exceptions: when the array is the argument of the `&` (address-of) operator: int arr[10]; int (*ptr_to_arr)[10] = &arr; // &arr is NOT of type `int *`! // It's of type "pointer to array" (of ten `int`s). // or when the array is a string literal used for initializing a char array: char otherarr[] = "foobarbazquirk"; // or when it's the argument of the `sizeof` or `alignof` operator: int arraythethird[10]; int *ptr = arraythethird; // equivalent with int *ptr = &arr[0]; printf("%zu, %zu\n", sizeof arraythethird, sizeof ptr); // probably prints "40, 4" or "40, 8" // Pointers are incremented and decremented based on their type // (this is called pointer arithmetic) printf("%d\n", *(x_ptr + 1)); // => Prints 19 printf("%d\n", x_array[1]); // => Prints 19 // You can also dynamically allocate contiguous blocks of memory with the // standard library function malloc, which takes one argument of type size_t // representing the number of bytes to allocate (usually from the heap, although this // may not be true on e.g. embedded systems - the C standard says nothing about it). int *my_ptr = malloc(sizeof(*my_ptr) * 20); for (xx = 0; xx < 20; xx++) { *(my_ptr + xx) = 20 - xx; // my_ptr[xx] = 20-xx } // Initialize memory to 20, 19, 18, 17... 2, 1 (as ints) // Note that there is no standard way to get the length of a // dynamically allocated array in C. Because of this, if your arrays are // going to be passed around your program a lot, you need another variable // to keep track of the number of elements (size) of an array. See the // functions section for more info. int size = 10; int *my_arr = malloc(sizeof(int) * size); // Add an element to the array size++; my_arr = realloc(my_arr, sizeof(int) * size); my_arr[10] = 5; // Dereferencing memory that you haven't allocated gives // "unpredictable results" - the program is said to invoke "undefined behavior" printf("%d\n", *(my_ptr + 21)); // => Prints who-knows-what? It may even crash. // 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 // (this is called a "memory leak"): free(my_ptr); // Strings are arrays of char, but they are usually represented as a // pointer-to-char (which is a pointer to the first element of the array). // It's good practice to use `const char *' when referring to a string literal, // since string literals shall not be modified (i.e. "foo"[0] = 'a' is ILLEGAL.) const char *my_str = "This is my very own string literal"; printf("%c\n", *my_str); // => 'T' // This is not the case if the string is an array // (potentially initialized with a string literal) // that resides in writable memory, as in: char foo[] = "foo"; foo[0] = 'a'; // this is legal, foo now contains "aoo" function_1(); } // end main function /////////////////////////////////////// // Functions /////////////////////////////////////// // Function declaration syntax: // () int add_two_ints(int x1, int x2) { return x1 + x2; // Use return to return a value } /* Functions are call by value. When a function is called, the arguments passed to the function are copies of the original arguments (except arrays). Anything you do to the arguments in the function do not change the value of the original argument where the function was called. Use pointers if you need to edit the original argument values. Example: in-place string reversal */ // A void function returns no value void str_reverse(char *str_in) { char tmp; int ii = 0; size_t len = strlen(str_in); // `strlen()` is part of the c standard library for (ii = 0; ii < len / 2; ii++) { tmp = str_in[ii]; str_in[ii] = str_in[len - ii - 1]; // ii-th char from end str_in[len - ii - 1] = tmp; } } //NOTE: string.h header file needs to be included to use strlen() /* char c[] = "This is a test."; str_reverse(c); printf("%s\n", c); // => ".tset a si sihT" */ /* as we can return only one variable to change values of more than one variables we use call by reference */ void swapTwoNumbers(int *a, int *b) { int temp = *a; *a = *b; *b = temp; } /* int first = 10; int second = 20; printf("first: %d\nsecond: %d\n", first, second); swapTwoNumbers(&first, &second); printf("first: %d\nsecond: %d\n", first, second); // values will be swapped */ /* With regards to arrays, they will always be passed to functions as pointers. Even if you statically allocate an array like `arr[10]`, it still gets passed as a pointer to the first element in any function calls. Again, there is no standard way to get the size of a dynamically allocated array in C. */ // Size must be passed! // Otherwise, this function has no way of knowing how big the array is. void printIntArray(int *arr, int size) { int i; for (i = 0; i < size; i++) { printf("arr[%d] is: %d\n", i, arr[i]); } } /* int my_arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; int size = 10; printIntArray(my_arr, size); // will print "arr[0] is: 1" etc */ // if referring to external variables outside function, must use extern keyword. int i = 0; void testFunc() { extern int i; //i here is now using external variable i } // make external variables private to source file with static: static int j = 0; //other files using testFunc2() cannot access variable j void testFunc2() { extern int j; } //**You may also declare functions as static to make them private** /////////////////////////////////////// // User-defined types and structs /////////////////////////////////////// // Typedefs can be used to create type aliases typedef int my_type; my_type my_type_var = 0; // Structs are just collections of data, the members are allocated sequentially, // in the order they are written: struct rectangle { int width; int height; }; // It's not generally true that // sizeof(struct rectangle) == sizeof(int) + sizeof(int) // due to potential padding between the structure members (this is for alignment // reasons). [1] void function_1() { struct rectangle my_rec; // Access struct members with . my_rec.width = 10; my_rec.height = 20; // You can declare pointers to structs struct rectangle *my_rec_ptr = &my_rec; // Use dereferencing to set struct pointer members... (*my_rec_ptr).width = 30; // ... or even better: prefer the -> shorthand for the sake of readability my_rec_ptr->height = 10; // Same as (*my_rec_ptr).height = 10; } // You can apply a typedef to a struct for convenience typedef struct rectangle rect; int area(rect r) { return r.width * r.height; } // if you have large structs, you can pass them "by pointer" to avoid copying // the whole struct: int areaptr(const rect *r) { return r->width * r->height; } /////////////////////////////////////// // Function pointers /////////////////////////////////////// /* At run time, functions are located at known memory addresses. Function pointers are much like any other pointer (they just store a memory address), but can be used to invoke functions directly, and to pass handlers (or callback functions) around. However, definition syntax may be initially confusing. Example: use str_reverse from a pointer */ void str_reverse_through_pointer(char *str_in) { // Define a function pointer variable, named f. void (*f)(char *); // Signature should exactly match the target function. f = &str_reverse; // Assign the address for the actual function (determined at run time) // f = str_reverse; would work as well - functions decay into pointers, similar to arrays (*f)(str_in); // Just calling the function through the pointer // f(str_in); // That's an alternative but equally valid syntax for calling it. } /* As long as function signatures match, you can assign any function to the same pointer. Function pointers are usually typedef'd for simplicity and readability, as follows: */ typedef void (*my_fnp_type)(char *); // Then used when declaring the actual pointer variable: // ... // my_fnp_type f; //Special characters: /* '\a'; // alert (bell) character '\n'; // newline character '\t'; // tab character (left justifies text) '\v'; // vertical tab '\f'; // new page (form feed) '\r'; // carriage return '\b'; // backspace character '\0'; // NULL character. Usually put at end of strings in C. // hello\n\0. \0 used by convention to mark end of string. '\\'; // backslash '\?'; // question mark '\''; // single quote '\"'; // double quote '\xhh'; // hexadecimal number. Example: '\xb' = vertical tab character '\0oo'; // octal number. Example: '\013' = vertical tab character //print formatting: "%d"; // integer "%3d"; // integer with minimum of length 3 digits (right justifies text) "%s"; // string "%f"; // float "%ld"; // long "%3.2f"; // minimum 3 digits left and 2 digits right decimal float "%7.4s"; // (can do with strings too) "%c"; // char "%p"; // pointer "%x"; // hexadecimal "%o"; // octal "%%"; // prints % */ /////////////////////////////////////// // Order of Evaluation /////////////////////////////////////// //---------------------------------------------------// // Operators | Associativity // //---------------------------------------------------// // () [] -> . | left to right // // ! ~ ++ -- + = *(type)sizeof | right to left // // * / % | left to right // // + - | left to right // // << >> | left to right // // < <= > >= | left to right // // == != | left to right // // & | left to right // // ^ | left to right // // | | left to right // // && | left to right // // || | left to right // // ?: | right to left // // = += -= *= /= %= &= ^= |= <<= >>= | right to left // // , | left to right // //---------------------------------------------------// /******************************* Header Files ********************************** Header files are an important part of C as they allow for the connection of C source files and can simplify code and definitions by separating them into separate files. Header files are syntactically similar to C source files but reside in ".h" files. They can be included in your C source file by using the precompiler command #include "example.h", given that example.h exists in the same directory as the C file. */ /* A safe guard to prevent the header from being defined too many times. This */ /* happens in the case of circle dependency, the contents of the header is */ /* already defined. */ #ifndef EXAMPLE_H /* if EXAMPLE_H is not yet defined. */ #define EXAMPLE_H /* Define the macro EXAMPLE_H. */ /* Other headers can be included in headers and therefore transitively */ /* included into files that include this header. */ #include /* Like c source files macros can be defined in headers and used in files */ /* that include this header file. */ #define EXAMPLE_NAME "Dennis Ritchie" /* Function macros can also be defined. */ #define ADD(a, b) (a + b) /* Structs and typedefs can be used for consistency between files. */ typedef struct node { int val; struct node *next; } Node; /* So can enumerations. */ enum traffic_light_state {GREEN, YELLOW, RED}; /* Function prototypes can also be defined here for use in multiple files, */ /* but it is bad practice to define the function in the header. Definitions */ /* should instead be put in a C file. */ Node createLinkedList(int *vals, int len); /* Beyond the above elements, other definitions should be left to a C source */ /* file. Excessive includes or definitions should, also not be contained in */ /* a header file but instead put into separate headers or a C file. */ #endif /* End of the if precompiler directive. */ ``` ## Further Reading Best to find yourself a copy of [K&R, aka "The C Programming Language"](https://en.wikipedia.org/wiki/The_C_Programming_Language) It is *the* book about C, written by Dennis Ritchie, the creator of C, and Brian Kernighan. Be careful, though - it's ancient and it contains some inaccuracies (well, ideas that are not considered good anymore) or now-changed practices. Another good resource is [Learn C The Hard Way](http://c.learncodethehardway.org/book/). If you have a question, read the [compl.lang.c Frequently Asked Questions](http://c-faq.com). It's very important to use proper spacing, indentation and to be consistent with your coding style in general. Readable code is better than clever code and fast code. For a good, sane coding style to adopt, see the [Linux kernel coding style](https://www.kernel.org/doc/Documentation/process/coding-style.rst). Other than that, Google is your friend. [1] [Why isn't sizeof for a struct equal to the sum of sizeof of each member?](http://stackoverflow.com/questions/119123/why-isnt-sizeof-for-a-struct-equal-to-the-sum-of-sizeof-of-each-member) --- name: Go category: language language: Go lang: ca-es filename: learngo-ca.go contributors: - ["Sonia Keys", "https://github.com/soniakeys"] - ["Christopher Bess", "https://github.com/cbess"] - ["Jesse Johnson", "https://github.com/holocronweaver"] - ["Quint Guvernator", "https://github.com/qguv"] - ["Jose Donizetti", "https://github.com/josedonizetti"] - ["Alexej Friesen", "https://github.com/heyalexej"] - ["Clayton Walker", "https://github.com/cwalk"] - ["Leonid Shevtsov", "https://github.com/leonid-shevtsov"] translators: - ["Xavier Sala", "http://github.com/utrescu"] --- Go es va crear degut a la necessitat de fer la feina ràpidament. No segueix la darrera tendència en informàtica, però és la nova forma i la més ràpida de resoldre problemes reals. Té conceptes familiars de llenguatges imperatius amb tipat estàtic. És ràpid compilant i ràpid al executar, afegeix una forma fàcil d'entedre de concurrència per CPUs de diferents núclis i té característiques que ajuden en la programació a gran escala. Go té una gran llibreria de funcions estàndard i una comunitat d'usuaris entusiasta. ```go // Comentari d'una sola línia /* Comentari multilínia */ // La clausula `package` apareix sempre a sobre de cada fitxer de codi font. // Quan es desenvolupa un executable en comptes d'una llibreria el nom que // s'ha de fer servir de `package` ha de ser 'main'. package main // `import` es fa servir per indicar quins paquets de llibreries fa servir // aquest fitxer. import ( "fmt" // Un paquet de la llibreria estàndard de Go. "io/ioutil" // Les funcions ioutil de io m "math" // La llibreria de matemàtiques que es referenciarà com a m. "net/http" // Si, un servidor web! "os" // funcions per treballar amb el sistema de fitxers "strconv" // Conversions de cadenes ) // La definició d'una funció. `main` és especial. És el punt d'entrada per // l'executable. Tant si t'agrada com si no, Go fa servir corxets. func main() { // Println imprimeix una línia al canal de sortida. // Es qualifica amb el nom del paquet, fmt. fmt.Println("Hola món!") // Crida a una altra funció dins d'aquest paquet. mesEnllaDeHola() } // Els paràmetres de les funcions es posen dins de parèntesis. // Els parèntesis fan falta encara que no hi hagi cap paràmetre. func mesEnllaDeHola() { var x int // Declaració d'una variable. // S'han de declarar abans de fer-les servir. x = 3 // Assignació d'una variable // Hi ha una forma "Curta" amb := // Descobreix el tipus, declara la variable i li assigna valor. y := 4 sum, prod := learnMultiple(x, y) // La funció retorna dos valors. fmt.Println("sum:", sum, "prod:", prod) // Sortida simple. aprenTipus() // < y minuts, aprèn més! } /* <- comentari multilínia Les funcions poden tenir paràmetres i (multiples!) valors de retorn. Aquí `x`, `y` són els argumens i `sum` i `prod` són els valors retornats. Fixa't que `x` i `sum` reben el tipus `int`. */ func learnMultiple(x, y int) (sum, prod int) { return x + y, x * y // Retorna dos valors. } // Alguns tipus incorporats i literals. func aprenTipus() { // Normalment la declaració curta et dóna el que vols. str := "Learn Go!" // tipus string s2 := `Un tipus cadena "normal" pot tenir salts de línia.` // El mateix tipus // literals Non-ASCII literal. El tipus de Go és UTF-8. g := 'Σ' // El tipus rune, és un àlies de int32 conté un caràcter unicode. f := 3.14195 // float64, un número de 64 bits amb coma flotant IEEE-754. c := 3 + 4i // complex128, representat internament amb dos float64. // Sintaxi amb var i inicialitzadors. var u uint = 7 // Sense signe, però depèn de la mida com els int. var pi float32 = 22. / 7 // Conversió de tipus amb declaració curta. n := byte('\n') // byte és un àlies de uint8. // Les taules tenen mida fixa en temps de compilació. var a4 [4]int // Taula de 4 enters inicialitzats a zero. a3 := [...]int{3, 1, 5} // Taula inicialitzada amb tres elements // amb els valors 3, 1, i 5. // Els "Slices" tenen mida dinàmica. Tant les taules com els "slices" // tenen avantatges però és més habitual que es facin servir slices. s3 := []int{4, 5, 9} // Compara amb a3. Aquí no hi ha els tres punts s4 := make([]int, 4) // Crea un slice de 4 enters inicialitzats a zero. var d2 [][]float64 // Només es declara però no hi ha valors. bs := []byte("a slice") // Sintaxi de conversió de tipus. // Com que són dinàmics es poden afegir valors nous als slices. // Per afegir-hi elements es fa servir el mètode append(). // El primer argument és l'slice en el que s'afegeix. // Sovint ell mateix com aquí sota. s := []int{1, 2, 3} // Un slice amb tres elements. s = append(s, 4, 5, 6) // Ara s tindrà tres elements més fmt.Println(s) // El resultat serà [1 2 3 4 5 6] // Per afegir un slice dins d'un altre en comptes de valors atòmics // S'hi pot passar una referència a l'altre slice o un literal acabat // amb tres punts, que vol dir que s'ha de desempaquetar els elements // i afegir-los a "s" s = append(s, []int{7, 8, 9}...) // El segon argument és un slice fmt.Println(s) // El resultat ara és [1 2 3 4 5 6 7 8 9] p, q := aprenMemoria() // Declara p i q com a punters de int. fmt.Println(*p, *q) // * segueix el punter fins a trobar els valors // Els "Mapes" són taules dinàmiques associatives com els hash o els // diccionaris d'altres llenguatges. m := map[string]int{"tres": 3, "quatre": 4} m["un"] = 1 // En Go les variables que no es fan servir generen un error. // El subratllat permet fer servir una variable i descartar-ne el valor. _, _, _, _, _, _, _, _, _, _ = str, s2, g, f, u, pi, n, a3, s4, bs // És útil per descartar algun dels valors retornats per una funció // Per exemple, es pot ignorar l'error retornat per os.Create amb la idea // de que sempre es crearà. file, _ := os.Create("output.txt") fmt.Fprint(file, "Així es pot escriure en un fitxer") file.Close() // La sortida compta com a ús d'una variable. fmt.Println(s, c, a4, s3, d2, m) aprenControlDeFluxe() // Tornem. } // A diferència d'altres llenguatges les funcions poden retornar valors amb // nom. Assignant un nom al valor retornat en la declaració de la funció // permet retornar valors des de diferents llocs del programa a més de posar // el return sense valors func aprenRetornAmbNoms(x, y int) (z int) { z = x * y return // el retorn de z és implícit perquè ja té valor } // Go té un recollidor de basura. // Té punters però no té aritmetica de punters // Es poden cometre errors amb un punter a nil però no incrementant-lo. func aprenMemoria() (p, q *int) { // Els valors retornats p i q són punters a un enter. p = new(int) // Funció per reservar memòria // A la memòria ja hi ha un 0 per defecte, no és nil. s := make([]int, 20) // Reserva un bloc de memòria de 20 enters. s[3] = 7 // Assigna un valor a un d'ells. r := -2 // Declare una altra variable local. return &s[3], &r // & agafa l'adreça d'un objecte. } func expensiveComputation() float64 { return m.Exp(10) } func aprenControlDeFluxe() { // Els "If" necessiten corxets però no parèntesis. if true { fmt.Println("ja ho hem vist") } // El format del codi està estandaritzat amb la comanda "go fmt." if false { // Pout. } else { // Gloat. } // Si cal encadenar ifs és millor fer servir switch. x := 42.0 switch x { case 0: case 1: case 42: // Els case no "passen a través" no cal "break" per separar-los. /* Per fer-ho hi ha una comanda `fallthrough`, mireu: https://github.com/golang/go/wiki/Switch#fall-through */ case 43: // No hi arriba. default: // La opció "default" és opcional } // El 'for' tampoc necessita parèntesis, com el 'if'. // Les variables dins d'un bloc if o for són local del bloc. for x := 0; x < 3; x++ { // ++ is a statement. fmt.Println("iteració", x) } // x == 42. // L'única forma de fer bucles en Go és el 'for' però té moltes variants. for { // bucle infinit. break // És una broma!. continue // No hi arriba mai. } // Es fa servir "range" per iterar a una taula, un slice, un mapa // o un canal. // range torna un valor (channel) o dos (array, slice, string o map). for key, value := range map[string]int{"un": 1, "dos": 2, "tres": 3} { // Per cada parell del mapa imprimeix la clau i el valor. fmt.Printf("clau=%s, valor=%d\n", key, value) } // Si només cal el valor es pot fer servir _ for _, name := range []string{"Robert", "Bill", "Josep"} { fmt.Printf("Hola, %s\n", name) } // Es pot usar := per declarar i assignar valors i després // comprovar-lo y > x. if y := expensiveComputation(); y > x { x = y } // Les funcions literals són closures xBig := func() bool { return x > 10000 // Referencia a x declarada sobre el switch. } x = 99999 fmt.Println("xBig:", xBig()) // cert x = 1.3e3 // x val 1300 fmt.Println("xBig:", xBig()) // fals. // A més les funcions poden ser definides i cridades com a arguments per // una funció sempre que: // a) La funció es cridi inmediatament (), // b) El tipus del resultat sigui del tipus esperat de l'argument. fmt.Println("Suma i duplica dos números: ", func(a, b int) int { return (a + b) * 2 }(10, 2)) // Es crida amb els arguments 10 i 2 // => Suma i duplica dos números: 24 // Quan el necessitis t'agradarà que hi sigui goto love love: aprenFabricaDeFuncions() // func que retorna func és divertit(3)(3) aprenDefer() // Revisió ràpida d'una paraula clau. aprendreInterficies() // Bon material properament! } func aprenFabricaDeFuncions() { // Les dues seguents són equivalents, però la segona és més pràctica fmt.Println(sentenceFactory("dia")("Un bonic", "d'estiu!")) d := sentenceFactory("dia") fmt.Println(d("Un bonic", "d'estiu!")) fmt.Println(d("Un tranquil", "de primavera!")) } // Els decoradors són habituals en altres llenguatges. // Es pot fer el mateix en Go amb funcions literals que accepten arguments. func sentenceFactory(mystring string) func(before, after string) string { return func(before, after string) string { return fmt.Sprintf("%s %s %s", before, mystring, after) // nou string } } func aprenDefer() (ok bool) { // Les comandes marcades amb defer s'executen després de que la funció // hagi acabat. defer fmt.Println("Les comandes defer s'executen en ordre invers (LIFO).") defer fmt.Println("\nAquesta és la primera línia que s'imprimeix") // Defer es fa servir gairebé sempre per tancar un fitxer, en el moment // en que acaba el mètode. return true } // Defineix Stringer com un tipus interfície amb el mètode String(). type Stringer interface { String() string } // Defineix una estrutura que conté un parell d'enters, x i y. type parell struct { x, y int } // Defineix un mètode de l'estructura parell. Ara parell implementa Stringer. func (p parell) String() string { // p és anomenat el "receptor" // Sprintf és una funció del paquet fmt. // Fa referència als camps de p. return fmt.Sprintf("(%d, %d)", p.x, p.y) } func aprendreInterficies() { // La sintaxi de claus es pot fer servir per inicialitzar un "struct". // Gràcies a := defineix i inicialitza p com un struct 'parell'. p := parell{3, 4} fmt.Println(p.String()) // Es crida al mètode de p. var i Stringer // Declara i de tipus Stringer. i = p // parell implementa Stringer per tant és vàlid. // Es pot cridar el mètode String() igual que abans. fmt.Println(i.String()) // Les funcions de fmt criden a String() per aconseguir una representació // imprimible d'un objecte. fmt.Println(p) // Treu el mateix d'abans. Println crida el mètode String. fmt.Println(i) // Idèntic resultat aprendreParamentesVariables("Aquí", "estem", "aprenent!") } // Les funcions poden tenir paràmetres variables. func aprendreParamentesVariables(myStrings ...interface{}) { // Itera per cada un dels valors dels paràmetres // Ignorant l'índex de la seva posició for _, param := range myStrings { fmt.Println("paràmetre:", param) } // Passa el valor de múltipes variables com a paràmetre. fmt.Println("parametres:", fmt.Sprintln(myStrings...)) aprenControlErrors() } func aprenControlErrors() { // ", ok" Es fa servir per saber si hi és o no. m := map[int]string{3: "tres", 4: "quatre"} if x, ok := m[1]; !ok { // ok serà fals perquè 1 no està en el mapa. fmt.Println("no hi és") } else { fmt.Print(x) // x seria el valor, si no estés en el mapa. } // Un valor d'error donarà més informació sobre l'error. if _, err := strconv.Atoi("no-int"); err != nil { // _ descarta el valor // imprimeix 'strconv.ParseInt: intenta convertir "non-int": // syntaxi invalida' fmt.Println(err) } // Es tornarà a les interfícies més tard. Mentrestant, aprenConcurrencia() } // c és un canal (channel), una forma segura de comunicar objectes. func inc(i int, c chan int) { c <- i + 1 // <- és l'operador "envia" quan un canal està a l'esquerra. } // Es pot fer servir inc per incrementar un número de forma concurrent. func aprenConcurrencia() { // La funció make es pot fer servir per crear slices, mapes i canals. c := make(chan int) // S'inicien tres goroutines. // Els números s'incrementaran de forma concurrent, En paral·lel // si la màquina on s'executa pot fer-ho i està correctament configurada. // Tots tres envien al mateix canal. go inc(0, c) // go és la comanda que inicia una nova goroutine. go inc(10, c) go inc(-805, c) // Llegeix tres resultats del canal i els imprimeix. // No es pot saber en quin ordre arribaran els resultats! fmt.Println(<-c, <-c, <-c) // Canal a la dreta <- és l'operador "rebre" cs := make(chan string) // Un altre canal que processa strings. ccs := make(chan chan string) // Un canal de canals string. go func() { c <- 84 }() // Inicia una goroutine i li envia un valor. go func() { cs <- "paraula" }() // El mateix però amb cs. // Select té una sintaxi semblant a switch però amb canals. // Selecciona un cas aleatòriament dels que poden comunicar-se. select { case i := <-c: // El valor rebit pot ser assignat a una variable, fmt.Printf("és un %T", i) case <-cs: // O es pot descartar fmt.Println("és un string") case <-ccs: // Canal buit, no preparat per la comunicació. fmt.Println("no ha passat.") } // Quan arribi aquí s'haurà agafat un valor de c o bé de cs. Una de les // goroutines iniciades haurà acabat i l'altra romandrà bloquejada. aprenProgramacioWeb() // Go ho fa. Tu vols fer-ho. } // Una funció del paquet http inicia un servidor web. func aprenProgramacioWeb() { // El primer paràmetre de ListenAndServe és l'adreça on escoltar // i el segon és una interfície http.Handler. go func() { err := http.ListenAndServe(":8080", pair{}) fmt.Println(err) // no s'han d'ignorar els errors }() requestServer() } // Es converteix "parell" en un http.Handler només implementant el // mètode ServeHTTP. func (p parell) ServeHTTP(w http.ResponseWriter, r *http.Request) { // Serveix dades en el http.ResponseWriter. w.Write([]byte("Has après Go en Y minuts!")) } func requestServer() { resp, err := http.Get("http://localhost:8080") fmt.Println(err) defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) fmt.Printf("\nEl servidor diu: `%s`", string(body)) } ``` ## Més informació L'arrel de tot en Go és la web oficial [official Go web site] (http://golang.org/). Allà es pot seguir el tutorial, jugar interactivament i llegir molt més del que hem vist aquí.En el "tour", [the docs](https://golang.org/doc/) conté informació sobre com escriure codi net i efectiu en Go, comandes per empaquetar i generar documentació, i història de les versions. És altament recomanable llegir La definició del llenguatge. És fàcil de llegir i sorprenentment curta (com la definició del llenguatge en aquests dies). Es pot jugar amb codi a [Go playground](https://play.golang.org/p/tnWMjr16Mm). Prova de fer canvis en el codi i executar-lo des del navegador! Es pot fer servir [https://play.golang.org](https://play.golang.org) com a [REPL](https://en.wikipedia.org/wiki/Read-eval-print_loop) per provar coses i codi en el navegador sense haver d'instal·lar Go. En la llista de lectures pels estudiants de Go hi ha [el codi font de la llibreria estàndard](http://golang.org/src/pkg/). Ampliament comentada, que demostra el fàcil que és de llegir i entendre els programes en Go, l'estil de programació, i les formes de treballar-hi. O es pot clicar en un nom de funció en [la documentació](http://golang.org/pkg/) i veure'n el codi! Un altre gran recurs per aprendre Go és [Go by example](https://gobyexample.com/). Go Mobile afegeix suport per plataformes mòbils (Android i iOS). Es poden escriure aplicacions mòbils o escriure llibreries de paquets de Go, que es poden cridar des de Java (android) i Objective-C (iOS). Comproveu la [Go Mobile page](https://github.com/golang/go/wiki/Mobile) per més informació. --- name: Groovy category: language language: Groovy lang: ca-es filename: learngroovy-ca.groovy contributors: - ["Roberto Pérez Alcolea", "http://github.com/rpalcolea"] translations: - ["Xavier Sala Pujolar", "http://github.com/utrescu"] --- Groovy - Un llenguatge dinàmic per la plataforma Java [Llegir-ne més.](http://www.groovy-lang.org/) ```groovy /* Posa'l en marxa tu mateix: 1) Instal.la SDKMAN - http://sdkman.io/ 2) Instal.la Groovy: sdk install groovy 3) Inicia la consola groovy escrivint: groovyConsole */ // Els comentaris d'una sola línia comencen amb dues barres inverses /* Els comentaris multilínia són com aquest. */ // Hola món println "Hola món!" /* Variables: Es poden assignar valors a les variables per fer-los servir més tard */ def x = 1 println x x = new java.util.Date() println x x = -3.1499392 println x x = false println x x = "Groovy!" println x /* Col.leccions i mapes */ // Crear una llista buida def technologies = [] /*** Afegir elements a la llista ***/ // Com en Java technologies.add("Grails") // El shift a l'esquerra afegeix i retorna la llista technologies << "Groovy" // Afegir múltiples elements technologies.addAll(["Gradle","Griffon"]) /*** Eliminar elements de la llista ***/ // Com en Java technologies.remove("Griffon") // La resta també funciona technologies = technologies - 'Grails' /*** Iterar per les llistes ***/ // Iterar per tots els elements de la llista technologies.each { println "Technology: $it"} technologies.eachWithIndex { it, i -> println "$i: $it"} /*** Comprovar el contingut de la llista ***/ //Comprovar si la llista conté un o més elements (resultat boolea) contained = technologies.contains( 'Groovy' ) // O contained = 'Groovy' in technologies // Comprovar diversos elements technologies.containsAll(['Groovy','Grails']) /*** Ordenar llistes ***/ // Ordenar una llista (canvia la original) technologies.sort() // Per ordenar sense canviar la original es pot fer: sortedTechnologies = technologies.sort( false ) /*** Manipular llistes ***/ //Canvia tots els elements de la llista Collections.replaceAll(technologies, 'Gradle', 'gradle') // Desordena la llista Collections.shuffle(technologies, new Random()) // Buida la llista technologies.clear() // Crear un mapa buit def devMap = [:] // Afegir valors al mapa devMap = ['name':'Roberto', 'framework':'Grails', 'language':'Groovy'] devMap.put('lastName','Perez') // Iterar per tots els elements del mapa devMap.each { println "$it.key: $it.value" } devMap.eachWithIndex { it, i -> println "$i: $it"} // Comprovar si la clau hi és assert devMap.containsKey('name') // Comprova si el mapa conté un valor concret assert devMap.containsValue('Roberto') // Obtenir les claus del mapa println devMap.keySet() // Obtenir els valors del mapa println devMap.values() /* Groovy Beans Els GroovyBeans són JavaBeans però amb una sintaxi molt més senzilla Quan Groovy es compila a bytecode es fan servir les regles següents. * Si el nom és declarat amb un modificador (public, private o protected) es genera el camp * Un nom declarat sense modificadors genera un camp privat amb un getter i un setter públics (per exemple una propietat) * Si la propietat és declarada final el camp privat es crea i no es genera cap setter. * Es pot declarar una propietat i també declarar un getter i un setter. * Es pot declarar una propietat i un camp amb el mateix nom, la propietat farà servir el camp. * Si es vol una propietat private o protected s'ha de definir el getter i el setter que s'han de declarar private o protected. * Si s'accedeix a una propietat de la classe que està definida en temps de compilació amb un this implícit o explícit (per exemple this.foo, o bé només foo), Groovy accedirà al camp directament en comptes de fer-ho a través del getter i el setter. * Si s'accedeix a una propietat que no existeix tant implícita com explicitament, llavors Groovy accedirà a la propietat a través de la meta classe, que pot fer que falli en temps d'execució. */ class Foo { // Propietat només de lectura final String name = "Roberto" // Propietat de només lectura amb getter públic i un setter protected String language protected void setLanguage(String language) { this.language = language } // Propietat amb el tipus definit dinàmicament def lastName } /* Bucles i estructres de control */ //Groovy té el format tradicional de if -else def x = 3 if(x==1) { println "One" } else if(x==2) { println "Two" } else { println "X greater than Two" } // Groovy també té l'operador ternari def y = 10 def x = (y > 1) ? "worked" : "failed" assert x == "worked" //I també té 'l'Operador Elvis'! //En comptes de fer servir l'operador ternari: displayName = user.name ? user.name : 'Anonymous' // Es pot escriure d'aquesta forma: displayName = user.name ?: 'Anonymous' //Bucle for //Itera en un rang def x = 0 for (i in 0 .. 30) { x += i } //Itera per una llista x = 0 for( i in [5,3,2,1] ) { x += i } //Itera per un array array = (0..20).toArray() x = 0 for (i in array) { x += i } //Itera per un mapa def map = ['name':'Roberto', 'framework':'Grails', 'language':'Groovy'] x = 0 for ( e in map ) { x += e.value } /* Operadors Hi ha una llista d'operadors que poden ser sobreescrits en Groovy: http://www.groovy-lang.org/operators.html#Operator-Overloading Operadors útils de Groovy */ //Spread operator: Invoca una acció en tots els ítems d'un grup d'objectes. def technologies = ['Groovy','Grails','Gradle'] technologies*.toUpperCase() // = a technologies.collect { it?.toUpperCase() } //Safe navigation operator: fet servir per evitar el NullPointerException. def user = User.get(1) def username = user?.username /* Closures Un Closure és com un "bloc de codi" o un punter a un mètode. És un troç de codi que està definit i que s podrà executar més tard. Més informació a: http://www.groovy-lang.org/closures.html */ //Exemple: def clos = { println "Hola món!" } println "Executant el Closure:" clos() // Passar paràmetres a un Closure def sum = { a, b -> println a+b } sum(2,4) //Els Closures poden fer referència a variables que no formen part de la // llista dels seus paràmetres. def x = 5 def multiplyBy = { num -> num * x } println multiplyBy(10) // Si es té un Closure que agafa un element com a argument, se'n pot ignorar // la definició def clos = { print it } clos( "hi" ) /* Groovy pot recordar els resultats dels Closures [1][2][3] */ def cl = {a, b -> sleep(3000) // simula un procés llarg a + b } mem = cl.memoize() def callClosure(a, b) { def start = System.currentTimeMillis() mem(a, b) println "(a = $a, b = $b) - en ${System.currentTimeMillis() - start} ms" } callClosure(1, 2) callClosure(1, 2) callClosure(2, 3) callClosure(2, 3) callClosure(3, 4) callClosure(3, 4) callClosure(1, 2) callClosure(2, 3) callClosure(3, 4) /* Expando La classe Expando és un bean dinàmic al que se li poden afegir propietats i closures com a mètodes d'una instància d'aquesta classe. http://mrhaki.blogspot.mx/2009/10/groovy-goodness-expando-as-dynamic-bean.html */ def user = new Expando(name:"Roberto") assert 'Roberto' == user.name user.lastName = 'Pérez' assert 'Pérez' == user.lastName user.showInfo = { out -> out << "Name: $name" out << ", Last name: $lastName" } def sw = new StringWriter() println user.showInfo(sw) /* Metaprogrammació (MOP) */ // Fent servir ExpandoMetaClass per afegir comportament String.metaClass.testAdd = { println "he afegit això" } String x = "test" x?.testAdd() //Intercepting method calls class Test implements GroovyInterceptable { def sum(Integer x, Integer y) { x + y } def invokeMethod(String name, args) { System.out.println "Invoca el mètode $name amb arguments: $args" } } def test = new Test() test?.sum(2,3) test?.multiply(2,3) //Groovy supporta propertyMissing per gestionar la resolució de propietats class Foo { def propertyMissing(String name) { name } } def f = new Foo() assertEquals "boo", f.boo /* TypeChecked i CompileStatic Groovy, by nature, és i sempre serà un llenguatge dinàmic però també té comprovació de tipus i definicions estàtiques More info: http://www.infoq.com/articles/new-groovy-20 */ //TypeChecked import groovy.transform.TypeChecked void testMethod() {} @TypeChecked void test() { testMeethod() def name = "Roberto" println naameee } //Un altre exemple: import groovy.transform.TypeChecked @TypeChecked Integer test() { Integer num = "1" Integer[] numbers = [1,2,3,4] Date date = numbers[1] return "Test" } //exemple de CompileStatic import groovy.transform.CompileStatic @CompileStatic int sum(int x, int y) { x + y } assert sum(2,5) == 7 ``` ## Per aprendre'n més [documentació de Groovy](http://www.groovy-lang.org/documentation.html) [Cònsola de Groovy](http://groovyconsole.appspot.com/) Uneix-te a un [grup d'usuaris Groovy] (http://www.groovy-lang.org/usergroups.html) ## Llibres * [Groovy Goodness] (https://leanpub.com/groovy-goodness-notebook) * [Groovy in Action] (http://manning.com/koenig2/) * [Programming Groovy 2: Dynamic Productivity for the Java Developer] (http://shop.oreilly.com/product/9781937785307.do) [1] http://roshandawrani.wordpress.com/2010/10/18/groovy-new-feature-closures-can-now-memorize-their-results/ [2] http://www.solutionsiq.com/resources/agileiq-blog/bid/72880/Programming-with-Groovy-Trampoline-and-Memoize [3] http://mrhaki.blogspot.mx/2011/05/groovy-goodness-cache-closure-results.html --- language: kotlin contributors: - ["S Webber", "https://github.com/s-webber"] translators: - ["Xavier Sala", "https://github.com/utrescu"] lang: ca-es filename: LearnKotlin-ca.kt --- Kotlin és un llenguatge estàtic tipat per la JVM, Android i el navegador. És interoperable al 100% amb Java. [Llegir-ne més aquí.](https://kotlinlang.org/) ```kotlin // Els comentaris d'una línia comencen amb // /* Els comentaris multilínia són com aquest */ // La paraula clau "package" funciona de la mateixa forma que en Java package com.learnxinyminutes.kotlin /* El punt d'entrada dels programes en Kotlin és una funció anomenada "main". La funció rep un array que té els arguments fets servir al executar-lo. */ fun main(args: Array) { /* La declaració de variables es pot fer tant amb "var" com amb "val". A les declarades amb "val" no se'ls hi pot canviar el valor en canvi a les declarades amb "var" si. */ val fooVal = 10 // no es podrà canviar el valor de fooVal var fooVar = 10 fooVar = 20 // fooVar si que es pot canviar /* Gairebé sempre, Kotlin pot determinar el tipus d'una variable, de manera que no caldrà definir-lo cada vegada. Però es pot definir el tipus d'una variable explícitament d'aquesta forma: */ val foo: Int = 7 /* Els "strings" es poden representar igual que com es fa en Java. Es poden escapar caràcters amb la barra inversa. */ val fooString = "Aquí està la meva cadena!" val barString = "Imprimir en dues línies?\nCap problema!" val bazString = "Es poden posar tabuladors?\tI tant!" println(fooString) println(barString) println(bazString) /* Es poden definir strings literals envoltant-los amb les triples cometes ("""). Dins hi poden haver tant salts de línies com d'altres caràcters. */ val fooRawString = """ fun helloWorld(val name : String) { println("Hola món!") } """ println(fooRawString) /* Els strings poden contenir expressions de plantilla. Les expressions de plantilla comencen amb el símbol ($). */ val fooTemplateString = "$fooString té ${fooString.length} caràcters" println(fooTemplateString) /* Perquè una variable pugui contenir null ha de ser declarada específicament com a nullable afengint-li ? al seu tipus. Es pot accedir a una variable nulable fent servir l'operador ?. L'operador ?: permet especificar un valor alternatiu en cas de que la variable sigui null. */ var fooNullable: String? = "abc" println(fooNullable?.length) // => 3 println(fooNullable?.length ?: -1) // => 3 fooNullable = null println(fooNullable?.length) // => null println(fooNullable?.length ?: -1) // => -1 /* Les funcions es declaren amb la paraula "fun". Els arguments s'especifiquen entre corxets després del nom de la funció. Els arguments poden tenir un valor per defecte. El retorn de les funcions, si cal, es posa després de l'argument. */ fun hello(name: String = "món"): String { return "Hola, $name!" } println(hello("foo")) // => Hola, foo! println(hello(name = "bar")) // => Hola, bar! println(hello()) // => Hola, món! /* Un dels paràmetres d'una funció pot ser marcat amb la paraula clau "vararg" que permet que una funció accepti un número variable d'arguments. */ fun varargExample(vararg names: Int) { println("S'han rebut ${names.size} arguments") } varargExample() // => S'han rebut 0 elements varargExample(1) // => S'ha rebut 1 element varargExample(1, 2, 3) // => S'han rebut 3 elements /* Quan una funció consisteix en una sola expressió no calen els corxets El cos de la funció es posa rere el símbol =. */ fun odd(x: Int): Boolean = x % 2 == 1 println(odd(6)) // => false println(odd(7)) // => true // Si el tipus retornat es pot determinar no cal especificar-lo. fun even(x: Int) = x % 2 == 0 println(even(6)) // => true println(even(7)) // => false // Les funcions poden tenir altres funcions com arguments i // fins i tot retornar-ne. fun not(f: (Int) -> Boolean): (Int) -> Boolean { return {n -> !f.invoke(n)} } // Les funcions amb nom es poden especificar quan fan d'arguments amb :: val notOdd = not(::odd) val notEven = not(::even) // Les expressions lambda es poden posar com arguments. val notZero = not {n -> n == 0} /* Si la lambda només té un paràmetre es pot ometre la seva declaració. El seu valor serà "it". */ val notPositive = not {it > 0} for (i in 0..4) { println("${notOdd(i)} ${notEven(i)} ${notZero(i)} ${notPositive(i)}") } // Les classes es defineixen amb "class". class ExampleClass(val x: Int) { fun memberFunction(y: Int): Int { return x + y } infix fun infixMemberFunction(y: Int): Int { return x * y } } /* Per crear una nova instància es crida al constructor. Tingueu en compte que Kotlin no té l'operador "new". */ val fooExampleClass = ExampleClass(7) // Els mètodes es poden cridar amb la notació . println(fooExampleClass.memberFunction(4)) // => 11 /* Si una funció ha estat marcada amb "infix" es pot cridar amb la notació infix. */ println(fooExampleClass infixMemberFunction 4) // => 28 /* Les classes "data" són classes que només contenen dades. Es creen automàticament els mètodes "hashCode","equals" i "toString" */ data class DataClassExample (val x: Int, val y: Int, val z: Int) val fooData = DataClassExample(1, 2, 4) println(fooData) // => DataClassExample(x=1, y=2, z=4) // Les classes data tenen un mètode "copy". val fooCopy = fooData.copy(y = 100) println(fooCopy) // => DataClassExample(x=1, y=100, z=4) // Els objectes es poden desestructurar amb múltiples variables val (a, b, c) = fooCopy println("$a $b $c") // => 1 100 4 // desestructurat en un bucle "for" for ((a, b, c) in listOf(fooData)) { println("$a $b $c") // => 1 100 4 } val mapData = mapOf("a" to 1, "b" to 2) // Els mapes també for ((key, value) in mapData) { println("$key -> $value") } // La funció "with" és similar a la de JavaScript. data class MutableDataClassExample (var x: Int, var y: Int, var z: Int) val fooMutableData = MutableDataClassExample(7, 4, 9) with (fooMutableData) { x -= 2 y += 2 z-- } println(fooMutableData) // => MutableDataClassExample(x=5, y=6, z=8) /* Es pot crear una llista amb la funció "listOf". La llista serà immutable - no s'hi poden afegir o treure elements. */ val fooList = listOf("a", "b", "c") println(fooList.size) // => 3 println(fooList.first()) // => a println(fooList.last()) // => c // Es pot accedir als elements a partir del seu índex. println(fooList[1]) // => b // Es poden crear llistes mutables amb la funció "mutableListOf". val fooMutableList = mutableListOf("a", "b", "c") fooMutableList.add("d") println(fooMutableList.last()) // => d println(fooMutableList.size) // => 4 // Es poden crear conjunts amb la funció "setOf". val fooSet = setOf("a", "b", "c") println(fooSet.contains("a")) // => true println(fooSet.contains("z")) // => false // Es poden crear mapes amb la funció "mapOf". val fooMap = mapOf("a" to 8, "b" to 7, "c" to 9) // S'accedeix als valors del mapa a partir del seu índex. println(fooMap["a"]) // => 8 /* Les sequències representen col·leccions evaluades quan fan falta. Podem crear una seqüencia amb la funció "generateSequence". */ val fooSequence = generateSequence(1, { it + 1 }) val x = fooSequence.take(10).toList() println(x) // => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] // Per exemple amb aquesta seqüència es creen els números de Fibonacci: fun fibonacciSequence(): Sequence { var a = 0L var b = 1L fun next(): Long { val result = a + b a = b b = result return a } return generateSequence(::next) } val y = fibonacciSequence().take(10).toList() println(y) // => [1, 1, 2, 3, 5, 8, 13, 21, 34, 55] // Kotlin proporciona funcions de primer ordre per treballar amb // col·leccions. val z = (1..9).map {it * 3} .filter {it < 20} .groupBy {it % 2 == 0} .mapKeys {if (it.key) "parell" else "senar"} println(z) // => {odd=[3, 9, 15], even=[6, 12, 18]} // Es pot fer servir el bucle "for" amb qualsevol cosa que proporcioni // un iterador. for (c in "hello") { println(c) } // els bucles "while" funcionen com en altres llenguatges. var ctr = 0 while (ctr < 5) { println(ctr) ctr++ } do { println(ctr) ctr++ } while (ctr < 10) /* "if" es pot fer servir com una expressió que retorna un valor. Per això no cal l'operador ternari ?: en Kotlin. */ val num = 5 val message = if (num % 2 == 0) "parell" else "senar" println("$num is $message") // => 5 is odd // "when" es pot fer servir com alternativa a les cadenes "if-else if". val i = 10 when { i < 7 -> println("primer bloc") fooString.startsWith("hola") -> println("segon bloc") else -> println("bloc else") } // "when" es pot fer servir amb un argument. when (i) { 0, 21 -> println("0 o 21") in 1..20 -> println("en el rang 1 a 20") else -> println("cap dels anteriors") } // "when" es pot fer servir com una funció que retorna valors. var result = when (i) { 0, 21 -> "0 o 21" in 1..20 -> "en el rang 1 a 20" else -> "cap dels anteriors" } println(result) /* Es pot comprovar el tipus d'un objecte fent servir l'operador "is". Si un objecte passa una comprovació es pot fer servir sense posar-hi cap casting. */ fun smartCastExample(x: Any) : Boolean { if (x is Boolean) { // x es converteix automàticament a Booleà return x } else if (x is Int) { // x es converteix automàticament a int return x > 0 } else if (x is String) { // x es converteix a string automàticament return x.isNotEmpty() } else { return false } } println(smartCastExample("Hola món!")) // => true println(smartCastExample("")) // => false println(smartCastExample(5)) // => true println(smartCastExample(0)) // => false println(smartCastExample(true)) // => true // També es pot cridar smarcast en un bloc when fun smartCastWhenExample(x: Any) = when (x) { is Boolean -> x is Int -> x > 0 is String -> x.isNotEmpty() else -> false } /* Les extensions són una forma d'afegir noves funcionalitats a una classe. És semblant a les extensions de C#. */ fun String.remove(c: Char): String { return this.filter {it != c} } println("Hola món!".remove('l')) // => Hoa, món! println(EnumExample.A) // => A println(ObjectExample.hello()) // => hola } // Les classes enumerades són semblants a les de Java enum class EnumExample { A, B, C } /* El paràmetre "object" es pot fer servir per crear objectes singleton. No es poden instanciar però es pot fer referència a la seva única instància amb el seu nom. Són similars als singletons d'Scala. */ object ObjectExample { fun hello(): String { return "hola" } } fun useObject() { ObjectExample.hello() val someRef: Any = ObjectExample // podem fer servir el nom de l'objecte } ``` ### Per llegir més * [tutorials de Kotlin](https://kotlinlang.org/docs/tutorials/) * [Provar Kotlin en el navegador](http://try.kotlinlang.org/) * [Llista de recursos de Kotlin](http://kotlin.link/) --- language: chapel filename: learnchapel.chpl contributors: - ["Ian J. Bertolacci", "http://www.cs.colostate.edu/~ibertola/"] - ["Ben Harshbarger", "http://github.com/benharsh/"] --- You can read all about Chapel at [Cray's official Chapel website](http://chapel.cray.com). In short, Chapel is an open-source, high-productivity, parallel-programming language in development at Cray Inc., and is designed to run on multi-core PCs as well as multi-kilocore supercomputers. More information and support can be found at the bottom of this document. ```chapel // Comments are C-family style // one line comment /* multi-line comment */ // Basic printing write("Hello, "); writeln("World!"); // write and writeln can take a list of things to print. // Each thing is printed right next to the others, so include your spacing! writeln("There are ", 3, " commas (\",\") in this line of code"); // Different output channels: stdout.writeln("This goes to standard output, just like plain writeln() does"); stderr.writeln("This goes to standard error"); // Variables don't have to be explicitly typed as long as // the compiler can figure out the type that it will hold. // 10 is an int, so myVar is implicitly an int var myVar = 10; myVar = -10; var mySecondVar = myVar; // var anError; would be a compile-time error. // We can (and should) explicitly type things. var myThirdVar: real; var myFourthVar: real = -1.234; myThirdVar = myFourthVar; // Types // There are a number of basic types. var myInt: int = -1000; // Signed ints var myUint: uint = 1234; // Unsigned ints var myReal: real = 9.876; // Floating point numbers var myImag: imag = 5.0i; // Imaginary numbers var myCplx: complex = 10 + 9i; // Complex numbers myCplx = myInt + myImag; // Another way to form complex numbers var myBool: bool = false; // Booleans var myStr: string = "Some string..."; // Strings var singleQuoteStr = 'Another string...'; // String literal with single quotes // Some types can have sizes. var my8Int: int(8) = 10; // 8 bit (one byte) sized int; var my64Real: real(64) = 1.516; // 64 bit (8 bytes) sized real // Typecasting. var intFromReal = myReal : int; var intFromReal2: int = myReal : int; // Type aliasing. type chroma = int; // Type of a single hue type RGBColor = 3*chroma; // Type representing a full color var black: RGBColor = (0,0,0); var white: RGBColor = (255, 255, 255); // Constants and Parameters // A const is a constant, and cannot be changed after set in runtime. const almostPi: real = 22.0/7.0; // A param is a constant whose value must be known statically at // compile-time. param compileTimeConst: int = 16; // The config modifier allows values to be set at the command line. // Set with --varCmdLineArg=Value or --varCmdLineArg Value at runtime. config var varCmdLineArg: int = -123; config const constCmdLineArg: int = 777; // config param can be set at compile-time. // Set with --set paramCmdLineArg=value at compile-time. config param paramCmdLineArg: bool = false; writeln(varCmdLineArg, ", ", constCmdLineArg, ", ", paramCmdLineArg); // References // ref operates much like a reference in C++. In Chapel, a ref cannot // be made to alias a variable other than the variable it is initialized with. // Here, refToActual refers to actual. var actual = 10; ref refToActual = actual; writeln(actual, " == ", refToActual); // prints the same value actual = -123; // modify actual (which refToActual refers to) writeln(actual, " == ", refToActual); // prints the same value refToActual = 99999999; // modify what refToActual refers to (which is actual) writeln(actual, " == ", refToActual); // prints the same value // Operators // Math operators: var a: int, thisInt = 1234, thatInt = 5678; a = thisInt + thatInt; // Addition a = thisInt * thatInt; // Multiplication a = thisInt - thatInt; // Subtraction a = thisInt / thatInt; // Division a = thisInt ** thatInt; // Exponentiation a = thisInt % thatInt; // Remainder (modulo) // Logical operators: var b: bool, thisBool = false, thatBool = true; b = thisBool && thatBool; // Logical and b = thisBool || thatBool; // Logical or b = !thisBool; // Logical negation // Relational operators: b = thisInt > thatInt; // Greater-than b = thisInt >= thatInt; // Greater-than-or-equal-to b = thisInt < a && a <= thatInt; // Less-than, and, less-than-or-equal-to b = thisInt != thatInt; // Not-equal-to b = thisInt == thatInt; // Equal-to // Bitwise operators: a = thisInt << 10; // Left-bit-shift by 10 bits; a = thatInt >> 5; // Right-bit-shift by 5 bits; a = ~thisInt; // Bitwise-negation a = thisInt ^ thatInt; // Bitwise exclusive-or // Compound assignment operators: a += thisInt; // Addition-equals (a = a + thisInt;) a *= thatInt; // Times-equals (a = a * thatInt;) b &&= thatBool; // Logical-and-equals (b = b && thatBool;) a <<= 3; // Left-bit-shift-equals (a = a << 10;) // Unlike other C family languages, there are no // pre/post-increment/decrement operators, such as: // // ++j, --j, j++, j-- // Swap operator: var old_this = thisInt; var old_that = thatInt; thisInt <=> thatInt; // Swap the values of thisInt and thatInt writeln((old_this == thatInt) && (old_that == thisInt)); // Operator overloads can also be defined, as we'll see with procedures. // Tuples // Tuples can be of the same type or different types. var sameTup: 2*int = (10, -1); var sameTup2 = (11, -6); var diffTup: (int,real,complex) = (5, 1.928, myCplx); var diffTupe2 = (7, 5.64, 6.0+1.5i); // Tuples can be accessed using square brackets or parentheses, and are // 1-indexed. writeln("(", sameTup[1], ",", sameTup(2), ")"); writeln(diffTup); // Tuples can also be written into. diffTup(1) = -1; // Tuple values can be expanded into their own variables. var (tupInt, tupReal, tupCplx) = diffTup; writeln(diffTup == (tupInt, tupReal, tupCplx)); // They are also useful for writing a list of variables, as is common in debugging. writeln((a,b,thisInt,thatInt,thisBool,thatBool)); // Control Flow // if - then - else works just like any other C-family language. if 10 < 100 then writeln("All is well"); if -1 < 1 then writeln("Continuing to believe reality"); else writeln("Send mathematician, something's wrong"); // You can use parentheses if you prefer. if (10 > 100) { writeln("Universe broken. Please reboot universe."); } if a % 2 == 0 { writeln(a, " is even."); } else { writeln(a, " is odd."); } if a % 3 == 0 { writeln(a, " is even divisible by 3."); } else if a % 3 == 1 { writeln(a, " is divided by 3 with a remainder of 1."); } else { writeln(b, " is divided by 3 with a remainder of 2."); } // Ternary: if - then - else in a statement. var maximum = if thisInt < thatInt then thatInt else thisInt; // select statements are much like switch statements in other languages. // However, select statements don't cascade like in C or Java. var inputOption = "anOption"; select inputOption { when "anOption" do writeln("Chose 'anOption'"); when "otherOption" { writeln("Chose 'otherOption'"); writeln("Which has a body"); } otherwise { writeln("Any other Input"); writeln("the otherwise case doesn't need a do if the body is one line"); } } // while and do-while loops also behave like their C counterparts. var j: int = 1; var jSum: int = 0; while (j <= 1000) { jSum += j; j += 1; } writeln(jSum); do { jSum += j; j += 1; } while (j <= 10000); writeln(jSum); // for loops are much like those in Python in that they iterate over a // range. Ranges (like the 1..10 expression below) are a first-class object // in Chapel, and as such can be stored in variables. for i in 1..10 do write(i, ", "); writeln(); var iSum: int = 0; for i in 1..1000 { iSum += i; } writeln(iSum); for x in 1..10 { for y in 1..10 { write((x,y), "\t"); } writeln(); } // Ranges and Domains // For-loops and arrays both use ranges and domains to define an index set that // can be iterated over. Ranges are single dimensional integer indices, while // domains can be multi-dimensional and represent indices of different types. // They are first-class citizen types, and can be assigned into variables. var range1to10: range = 1..10; // 1, 2, 3, ..., 10 var range2to11 = 2..11; // 2, 3, 4, ..., 11 var rangeThisToThat: range = thisInt..thatInt; // using variables var rangeEmpty: range = 100..-100; // this is valid but contains no indices // Ranges can be unbounded. var range1toInf: range(boundedType=BoundedRangeType.boundedLow) = 1.. ; // 1, 2, 3, 4, 5, ... var rangeNegInfTo1 = ..1; // ..., -4, -3, -2, -1, 0, 1 // Ranges can be strided (and reversed) using the by operator. var range2to10by2: range(stridable=true) = 2..10 by 2; // 2, 4, 6, 8, 10 var reverse2to10by2 = 2..10 by -2; // 10, 8, 6, 4, 2 var trapRange = 10..1 by -1; // Do not be fooled, this is still an empty range writeln("Size of range '", trapRange, "' = ", trapRange.length); // Note: range(boundedType= ...) and range(stridable= ...) are only // necessary if we explicitly type the variable. // The end point of a range can be determined using the count (#) operator. var rangeCount: range = -5..#12; // range from -5 to 6 // Operators can be mixed. var rangeCountBy: range(stridable=true) = -5..#12 by 2; // -5, -3, -1, 1, 3, 5 writeln(rangeCountBy); // Properties of the range can be queried. // In this example, printing the first index, last index, number of indices, // stride, and if 2 is include in the range. writeln((rangeCountBy.first, rangeCountBy.last, rangeCountBy.length, rangeCountBy.stride, rangeCountBy.member(2))); for i in rangeCountBy { write(i, if i == rangeCountBy.last then "\n" else ", "); } // Rectangular domains are defined using the same range syntax, // but they are required to be bounded (unlike ranges). var domain1to10: domain(1) = {1..10}; // 1D domain from 1..10; var twoDimensions: domain(2) = {-2..2,0..2}; // 2D domain over product of ranges var thirdDim: range = 1..16; var threeDims: domain(3) = {thirdDim, 1..10, 5..10}; // using a range variable // Domains can also be resized var resizedDom = {1..10}; writeln("before, resizedDom = ", resizedDom); resizedDom = {-10..#10}; writeln("after, resizedDom = ", resizedDom); // Indices can be iterated over as tuples. for idx in twoDimensions do write(idx, ", "); writeln(); // These tuples can also be deconstructed. for (x,y) in twoDimensions { write("(", x, ", ", y, ")", ", "); } writeln(); // Associative domains act like sets. var stringSet: domain(string); // empty set of strings stringSet += "a"; stringSet += "b"; stringSet += "c"; stringSet += "a"; // Redundant add "a" stringSet -= "c"; // Remove "c" writeln(stringSet.sorted()); // Associative domains can also have a literal syntax var intSet = {1, 2, 4, 5, 100}; // Both ranges and domains can be sliced to produce a range or domain with the // intersection of indices. var rangeA = 1.. ; // range from 1 to infinity var rangeB = ..5; // range from negative infinity to 5 var rangeC = rangeA[rangeB]; // resulting range is 1..5 writeln((rangeA, rangeB, rangeC)); var domainA = {1..10, 5..20}; var domainB = {-5..5, 1..10}; var domainC = domainA[domainB]; writeln((domainA, domainB, domainC)); // Arrays // Arrays are similar to those of other languages. // Their sizes are defined using domains that represent their indices. var intArray: [1..10] int; var intArray2: [{1..10}] int; // equivalent // They can be accessed using either brackets or parentheses for i in 1..10 do intArray[i] = -i; writeln(intArray); // We cannot access intArray[0] because it exists outside // of the index set, {1..10}, we defined it to have. // intArray[11] is illegal for the same reason. var realDomain: domain(2) = {1..5,1..7}; var realArray: [realDomain] real; var realArray2: [1..5,1..7] real; // equivalent var realArray3: [{1..5,1..7}] real; // equivalent for i in 1..5 { for j in realDomain.dim(2) { // Only use the 2nd dimension of the domain realArray[i,j] = -1.61803 * i + 0.5 * j; // Access using index list var idx: 2*int = (i,j); // Note: 'index' is a keyword realArray[idx] = - realArray[(i,j)]; // Index using tuples } } // Arrays have domains as members, and can be iterated over as normal. for idx in realArray.domain { // Again, idx is a 2*int tuple realArray[idx] = 1 / realArray[idx[1], idx[2]]; // Access by tuple and list } writeln(realArray); // The values of an array can also be iterated directly. var rSum: real = 0; for value in realArray { rSum += value; // Read a value value = rSum; // Write a value } writeln(rSum, "\n", realArray); // Associative arrays (dictionaries) can be created using associative domains. var dictDomain: domain(string) = { "one", "two" }; var dict: [dictDomain] int = ["one" => 1, "two" => 2]; dict["three"] = 3; // Adds 'three' to 'dictDomain' implicitly for key in dictDomain.sorted() do writeln(dict[key]); // Arrays can be assigned to each other in a few different ways. // These arrays will be used in the example. var thisArray : [0..5] int = [0,1,2,3,4,5]; var thatArray : [0..5] int; // First, simply assign one to the other. This copies thisArray into // thatArray, instead of just creating a reference. Therefore, modifying // thisArray does not also modify thatArray. thatArray = thisArray; thatArray[1] = -1; writeln((thisArray, thatArray)); // Assign a slice from one array to a slice (of the same size) in the other. thatArray[4..5] = thisArray[1..2]; writeln((thisArray, thatArray)); // Operations can also be promoted to work on arrays. 'thisPlusThat' is also // an array. var thisPlusThat = thisArray + thatArray; writeln(thisPlusThat); // Moving on, arrays and loops can also be expressions, where the loop // body's expression is the result of each iteration. var arrayFromLoop = for i in 1..10 do i; writeln(arrayFromLoop); // An expression can result in nothing, such as when filtering with an if-expression. var evensOrFives = for i in 1..10 do if (i % 2 == 0 || i % 5 == 0) then i; writeln(arrayFromLoop); // Array expressions can also be written with a bracket notation. // Note: this syntax uses the forall parallel concept discussed later. var evensOrFivesAgain = [i in 1..10] if (i % 2 == 0 || i % 5 == 0) then i; // They can also be written over the values of the array. arrayFromLoop = [value in arrayFromLoop] value + 1; // Procedures // Chapel procedures have similar syntax functions in other languages. proc fibonacci(n : int) : int { if n <= 1 then return n; return fibonacci(n-1) + fibonacci(n-2); } // Input parameters can be untyped to create a generic procedure. proc doublePrint(thing): void { write(thing, " ", thing, "\n"); } // The return type can be inferred, as long as the compiler can figure it out. proc addThree(n) { return n + 3; } doublePrint(addThree(fibonacci(20))); // It is also possible to take a variable number of parameters. proc maxOf(x ...?k) { // x refers to a tuple of one type, with k elements var maximum = x[1]; for i in 2..k do maximum = if maximum < x[i] then x[i] else maximum; return maximum; } writeln(maxOf(1, -10, 189, -9071982, 5, 17, 20001, 42)); // Procedures can have default parameter values, and // the parameters can be named in the call, even out of order. proc defaultsProc(x: int, y: real = 1.2634): (int,real) { return (x,y); } writeln(defaultsProc(10)); writeln(defaultsProc(x=11)); writeln(defaultsProc(x=12, y=5.432)); writeln(defaultsProc(y=9.876, x=13)); // The ? operator is called the query operator, and is used to take // undetermined values like tuple or array sizes and generic types. // For example, taking arrays as parameters. The query operator is used to // determine the domain of A. This is uesful for defining the return type, // though it's not required. proc invertArray(A: [?D] int): [D] int{ for a in A do a = -a; return A; } writeln(invertArray(intArray)); // We can query the type of arguments to generic procedures. // Here we define a procedure that takes two arguments of // the same type, yet we don't define what that type is. proc genericProc(arg1 : ?valueType, arg2 : valueType): void { select(valueType) { when int do writeln(arg1, " and ", arg2, " are ints"); when real do writeln(arg1, " and ", arg2, " are reals"); otherwise writeln(arg1, " and ", arg2, " are somethings!"); } } genericProc(1, 2); genericProc(1.2, 2.3); genericProc(1.0+2.0i, 3.0+4.0i); // We can also enforce a form of polymorphism with the where clause // This allows the compiler to decide which function to use. // Note: That means that all information needs to be known at compile-time. // The param modifier on the arg is used to enforce this constraint. proc whereProc(param N : int): void where (N > 0) { writeln("N is greater than 0"); } proc whereProc(param N : int): void where (N < 0) { writeln("N is less than 0"); } whereProc(10); whereProc(-1); // whereProc(0) would result in a compiler error because there // are no functions that satisfy the where clause's condition. // We could have defined a whereProc without a where clause // that would then have served as a catch all for all the other cases // (of which there is only one). // where clauses can also be used to constrain based on argument type. proc whereType(x: ?t) where t == int { writeln("Inside 'int' version of 'whereType': ", x); } proc whereType(x: ?t) { writeln("Inside general version of 'whereType': ", x); } whereType(42); whereType("hello"); // Intents /* Intent modifiers on the arguments convey how those arguments are passed to the procedure. * in: copy arg in, but not out * out: copy arg out, but not in * inout: copy arg in, copy arg out * ref: pass arg by reference */ proc intentsProc(in inarg, out outarg, inout inoutarg, ref refarg) { writeln("Inside Before: ", (inarg, outarg, inoutarg, refarg)); inarg = inarg + 100; outarg = outarg + 100; inoutarg = inoutarg + 100; refarg = refarg + 100; writeln("Inside After: ", (inarg, outarg, inoutarg, refarg)); } var inVar: int = 1; var outVar: int = 2; var inoutVar: int = 3; var refVar: int = 4; writeln("Outside Before: ", (inVar, outVar, inoutVar, refVar)); intentsProc(inVar, outVar, inoutVar, refVar); writeln("Outside After: ", (inVar, outVar, inoutVar, refVar)); // Similarly, we can define intents on the return type. // refElement returns a reference to an element of array. // This makes more practical sense for class methods where references to // elements in a data-structure are returned via a method or iterator. proc refElement(array : [?D] ?T, idx) ref : T { return array[idx]; } var myChangingArray : [1..5] int = [1,2,3,4,5]; writeln(myChangingArray); ref refToElem = refElement(myChangingArray, 5); // store reference to element in ref variable writeln(refToElem); refToElem = -2; // modify reference which modifies actual value in array writeln(refToElem); writeln(myChangingArray); // Operator Definitions // Chapel allows for operators to be overloaded. // We can define the unary operators: // + - ! ~ // and the binary operators: // + - * / % ** == <= >= < > << >> & | ˆ by // += -= *= /= %= **= &= |= ˆ= <<= >>= <=> // Boolean exclusive or operator. proc ^(left : bool, right : bool): bool { return (left || right) && !(left && right); } writeln(true ^ true); writeln(false ^ true); writeln(true ^ false); writeln(false ^ false); // Define a * operator on any two types that returns a tuple of those types. proc *(left : ?ltype, right : ?rtype): (ltype, rtype) { writeln("\tIn our '*' overload!"); return (left, right); } writeln(1 * "a"); // Uses our * operator. writeln(1 * 2); // Uses the default * operator. // Note: You could break everything if you get careless with your overloads. // This here will break everything. Don't do it. /* proc +(left: int, right: int): int { return left - right; } */ // Iterators // Iterators are sisters to the procedure, and almost everything about // procedures also applies to iterators. However, instead of returning a single // value, iterators may yield multiple values to a loop. // // This is useful when a complicated set or order of iterations is needed, as // it allows the code defining the iterations to be separate from the loop // body. iter oddsThenEvens(N: int): int { for i in 1..N by 2 do yield i; // yield values instead of returning. for i in 2..N by 2 do yield i; } for i in oddsThenEvens(10) do write(i, ", "); writeln(); // Iterators can also yield conditionally, the result of which can be nothing iter absolutelyNothing(N): int { for i in 1..N { if N < i { // Always false yield i; // Yield statement never happens } } } for i in absolutelyNothing(10) { writeln("Woa there! absolutelyNothing yielded ", i); } // We can zipper together two or more iterators (who have the same number // of iterations) using zip() to create a single zipped iterator, where each // iteration of the zipped iterator yields a tuple of one value yielded // from each iterator. for (positive, negative) in zip(1..5, -5..-1) do writeln((positive, negative)); // Zipper iteration is quite important in the assignment of arrays, // slices of arrays, and array/loop expressions. var fromThatArray : [1..#5] int = [1,2,3,4,5]; var toThisArray : [100..#5] int; // Some zipper operations implement other operations. // The first statement and the loop are equivalent. toThisArray = fromThatArray; for (i,j) in zip(toThisArray.domain, fromThatArray.domain) { toThisArray[i] = fromThatArray[j]; } // These two chunks are also equivalent. toThisArray = [j in -100..#5] j; writeln(toThisArray); for (i, j) in zip(toThisArray.domain, -100..#5) { toThisArray[i] = j; } writeln(toThisArray); // This is very important in understanding why this statement exhibits a // runtime error. /* var iterArray : [1..10] int = [i in 1..10] if (i % 2 == 1) then i; */ // Even though the domain of the array and the loop-expression are // the same size, the body of the expression can be thought of as an iterator. // Because iterators can yield nothing, that iterator yields a different number // of things than the domain of the array or loop, which is not allowed. // Classes // Classes are similar to those in C++ and Java, allocated on the heap. class MyClass { // Member variables var memberInt : int; var memberBool : bool = true; // Explicitly defined initializer. // We also get the compiler-generated initializer, with one argument per field. // Note that soon there will be no compiler-generated initializer when we // define any initializer(s) explicitly. proc MyClass(val : real) { this.memberInt = ceil(val): int; } // Explicitly defined deinitializer. // If we did not write one, we would get the compiler-generated deinitializer, // which has an empty body. proc deinit() { writeln("MyClass deinitializer called ", (this.memberInt, this.memberBool)); } // Class methods. proc setMemberInt(val: int) { this.memberInt = val; } proc setMemberBool(val: bool) { this.memberBool = val; } proc getMemberInt(): int{ return this.memberInt; } proc getMemberBool(): bool { return this.memberBool; } } // end MyClass // Call compiler-generated initializer, using default value for memberBool. var myObject = new MyClass(10); myObject = new MyClass(memberInt = 10); // Equivalent writeln(myObject.getMemberInt()); // Same, but provide a memberBool value explicitly. var myDiffObject = new MyClass(-1, true); myDiffObject = new MyClass(memberInt = -1, memberBool = true); // Equivalent writeln(myDiffObject); // Call the initializer we wrote. var myOtherObject = new MyClass(1.95); myOtherObject = new MyClass(val = 1.95); // Equivalent writeln(myOtherObject.getMemberInt()); // We can define an operator on our class as well, but // the definition has to be outside the class definition. proc +(A : MyClass, B : MyClass) : MyClass { return new MyClass(memberInt = A.getMemberInt() + B.getMemberInt(), memberBool = A.getMemberBool() || B.getMemberBool()); } var plusObject = myObject + myDiffObject; writeln(plusObject); // Destruction. delete myObject; delete myDiffObject; delete myOtherObject; delete plusObject; // Classes can inherit from one or more parent classes class MyChildClass : MyClass { var memberComplex: complex; } // Here's an example of generic classes. class GenericClass { type classType; var classDomain: domain(1); var classArray: [classDomain] classType; // Explicit constructor. proc GenericClass(type classType, elements : int) { this.classDomain = {1..#elements}; } // Copy constructor. // Note: We still have to put the type as an argument, but we can // default to the type of the other object using the query (?) operator. // Further, we can take advantage of this to allow our copy constructor // to copy classes of different types and cast on the fly. proc GenericClass(other : GenericClass(?otherType), type classType = otherType) { this.classDomain = other.classDomain; // Copy and cast for idx in this.classDomain do this[idx] = other[idx] : classType; } // Define bracket notation on a GenericClass // object so it can behave like a normal array // i.e. objVar[i] or objVar(i) proc this(i : int) ref : classType { return this.classArray[i]; } // Define an implicit iterator for the class // to yield values from the array to a loop // i.e. for i in objVar do ... iter these() ref : classType { for i in this.classDomain do yield this[i]; } } // end GenericClass // We can assign to the member array of the object using the bracket // notation that we defined. var realList = new GenericClass(real, 10); for i in realList.classDomain do realList[i] = i + 1.0; // We can iterate over the values in our list with the iterator // we defined. for value in realList do write(value, ", "); writeln(); // Make a copy of realList using the copy constructor. var copyList = new GenericClass(realList); for value in copyList do write(value, ", "); writeln(); // Make a copy of realList and change the type, also using the copy constructor. var copyNewTypeList = new GenericClass(realList, int); for value in copyNewTypeList do write(value, ", "); writeln(); // Modules // Modules are Chapel's way of managing name spaces. // The files containing these modules do not need to be named after the modules // (as in Java), but files implicitly name modules. // For example, this file implicitly names the learnChapelInYMinutes module module OurModule { // We can use modules inside of other modules. // Time is one of the standard modules. use Time; // We'll use this procedure in the parallelism section. proc countdown(seconds: int) { for i in 1..seconds by -1 { writeln(i); sleep(1); } } // It is possible to create arbitrarily deep module nests. // i.e. submodules of OurModule module ChildModule { proc foo() { writeln("ChildModule.foo()"); } } module SiblingModule { proc foo() { writeln("SiblingModule.foo()"); } } } // end OurModule // Using OurModule also uses all the modules it uses. // Since OurModule uses Time, we also use Time. use OurModule; // At this point we have not used ChildModule or SiblingModule so // their symbols (i.e. foo) are not available to us. However, the module // names are available, and we can explicitly call foo() through them. SiblingModule.foo(); OurModule.ChildModule.foo(); // Now we use ChildModule, enabling unqualified calls. use ChildModule; foo(); // Parallelism // In other languages, parallelism is typically done with // complicated libraries and strange class structure hierarchies. // Chapel has it baked right into the language. // We can declare a main procedure, but all the code above main still gets // executed. proc main() { writeln("PARALLELISM START"); // A begin statement will spin the body of that statement off // into one new task. // A sync statement will ensure that the progress of the main // task will not progress until the children have synced back up. sync { begin { // Start of new task's body var a = 0; for i in 1..1000 do a += 1; writeln("Done: ", a); } // End of new tasks body writeln("spun off a task!"); } writeln("Back together"); proc printFibb(n: int) { writeln("fibonacci(",n,") = ", fibonacci(n)); } // A cobegin statement will spin each statement of the body into one new // task. Notice here that the prints from each statement may happen in any // order. cobegin { printFibb(20); // new task printFibb(10); // new task printFibb(5); // new task { // This is a nested statement body and thus is a single statement // to the parent statement, executed by a single task. writeln("this gets"); writeln("executed as"); writeln("a whole"); } } // A coforall loop will create a new task for EACH iteration. // Again we see that prints happen in any order. // NOTE: coforall should be used only for creating tasks! // Using it to iterating over a structure is very a bad idea! var num_tasks = 10; // Number of tasks we want coforall taskID in 1..#num_tasks { writeln("Hello from task# ", taskID); } // forall loops are another parallel loop, but only create a smaller number // of tasks, specifically --dataParTasksPerLocale= number of tasks. forall i in 1..100 { write(i, ", "); } writeln(); // Here we see that there are sections that are in order, followed by // a section that would not follow (e.g. 1, 2, 3, 7, 8, 9, 4, 5, 6,). // This is because each task is taking on a chunk of the range 1..10 // (1..3, 4..6, or 7..9) doing that chunk serially, but each task happens // in parallel. Your results may depend on your machine and configuration // For both the forall and coforall loops, the execution of the // parent task will not continue until all the children sync up. // forall loops are particularly useful for parallel iteration over arrays. // Lets run an experiment to see how much faster a parallel loop is use Time; // Import the Time module to use Timer objects var timer: Timer; var myBigArray: [{1..4000,1..4000}] real; // Large array we will write into // Serial Experiment: timer.start(); // Start timer for (x,y) in myBigArray.domain { // Serial iteration myBigArray[x,y] = (x:real) / (y:real); } timer.stop(); // Stop timer writeln("Serial: ", timer.elapsed()); // Print elapsed time timer.clear(); // Clear timer for parallel loop // Parallel Experiment: timer.start(); // start timer forall (x,y) in myBigArray.domain { // Parallel iteration myBigArray[x,y] = (x:real) / (y:real); } timer.stop(); // Stop timer writeln("Parallel: ", timer.elapsed()); // Print elapsed time timer.clear(); // You may have noticed that (depending on how many cores you have) // the parallel loop went faster than the serial loop. // The bracket style loop-expression described // much earlier implicitly uses a forall loop. [val in myBigArray] val = 1 / val; // Parallel operation // Atomic variables, common to many languages, are ones whose operations // occur uninterrupted. Multiple threads can therefore modify atomic // variables and can know that their values are safe. // Chapel atomic variables can be of type bool, int, // uint, and real. var uranium: atomic int; uranium.write(238); // atomically write a variable writeln(uranium.read()); // atomically read a variable // Atomic operations are described as functions, so you can define your own. uranium.sub(3); // atomically subtract a variable writeln(uranium.read()); var replaceWith = 239; var was = uranium.exchange(replaceWith); writeln("uranium was ", was, " but is now ", replaceWith); var isEqualTo = 235; if uranium.compareExchange(isEqualTo, replaceWith) { writeln("uranium was equal to ", isEqualTo, " so replaced value with ", replaceWith); } else { writeln("uranium was not equal to ", isEqualTo, " so value stays the same... whatever it was"); } sync { begin { // Reader task writeln("Reader: waiting for uranium to be ", isEqualTo); uranium.waitFor(isEqualTo); writeln("Reader: uranium was set (by someone) to ", isEqualTo); } begin { // Writer task writeln("Writer: will set uranium to the value ", isEqualTo, " in..."); countdown(3); uranium.write(isEqualTo); } } // sync variables have two states: empty and full. // If you read an empty variable or write a full variable, you are waited // until the variable is full or empty again. var someSyncVar$: sync int; // varName$ is a convention not a law. sync { begin { // Reader task writeln("Reader: waiting to read."); var read_sync = someSyncVar$; writeln("Reader: value is ", read_sync); } begin { // Writer task writeln("Writer: will write in..."); countdown(3); someSyncVar$ = 123; } } // single vars can only be written once. A read on an unwritten single // results in a wait, but when the variable has a value it can be read // indefinitely. var someSingleVar$: single int; // varName$ is a convention not a law. sync { begin { // Reader task writeln("Reader: waiting to read."); for i in 1..5 { var read_single = someSingleVar$; writeln("Reader: iteration ", i,", and the value is ", read_single); } } begin { // Writer task writeln("Writer: will write in..."); countdown(3); someSingleVar$ = 5; // first and only write ever. } } // Here's an example using atomics and a sync variable to create a // count-down mutex (also known as a multiplexer). var count: atomic int; // our counter var lock$: sync bool; // the mutex lock count.write(2); // Only let two tasks in at a time. lock$.writeXF(true); // Set lock$ to full (unlocked) // Note: The value doesn't actually matter, just the state // (full:unlocked / empty:locked) // Also, writeXF() fills (F) the sync var regardless of its state (X) coforall task in 1..#5 { // Generate tasks // Create a barrier do { lock$; // Read lock$ (wait) } while (count.read() < 1); // Keep waiting until a spot opens up count.sub(1); // decrement the counter lock$.writeXF(true); // Set lock$ to full (signal) // Actual 'work' writeln("Task #", task, " doing work."); sleep(2); count.add(1); // Increment the counter lock$.writeXF(true); // Set lock$ to full (signal) } // We can define the operations + * & | ^ && || min max minloc maxloc // over an entire array using scans and reductions. // Reductions apply the operation over the entire array and // result in a scalar value. var listOfValues: [1..10] int = [15,57,354,36,45,15,456,8,678,2]; var sumOfValues = + reduce listOfValues; var maxValue = max reduce listOfValues; // 'max' give just max value // maxloc gives max value and index of the max value. // Note: We have to zip the array and domain together with the zip iterator. var (theMaxValue, idxOfMax) = maxloc reduce zip(listOfValues, listOfValues.domain); writeln((sumOfValues, maxValue, idxOfMax, listOfValues[idxOfMax])); // Scans apply the operation incrementally and return an array with the // values of the operation at that index as it progressed through the // array from array.domain.low to array.domain.high. var runningSumOfValues = + scan listOfValues; var maxScan = max scan listOfValues; writeln(runningSumOfValues); writeln(maxScan); } // end main() ``` Who is this tutorial for? ------------------------- This tutorial is for people who want to learn the ropes of chapel without having to hear about what fiber mixture the ropes are, or how they were braided, or how the braid configurations differ between one another. It won't teach you how to develop amazingly performant code, and it's not exhaustive. Refer to the [language specification](http://chapel.cray.com/language.html) and the [module documentation](http://chapel.cray.com/docs/latest/) for more details. Occasionally check back here and on the [Chapel site](http://chapel.cray.com) to see if more topics have been added or more tutorials created. ### What this tutorial is lacking: * Exposition of the [standard modules](http://chapel.cray.com/docs/latest/modules/modules.html) * Multiple Locales (distributed memory system) * Records * Parallel iterators Your input, questions, and discoveries are important to the developers! ----------------------------------------------------------------------- The Chapel language is still in-development (version 1.15.0), so there are occasional hiccups with performance and language features. The more information you give the Chapel development team about issues you encounter or features you would like to see, the better the language becomes. Feel free to email the team and other developers through the [sourceforge email lists](https://sourceforge.net/p/chapel/mailman). If you're really interested in the development of the compiler or contributing to the project, [check out the master GitHub repository](https://github.com/chapel-lang/chapel). It is under the [Apache 2.0 License](http://www.apache.org/licenses/LICENSE-2.0). Installing the Compiler ----------------------- Chapel can be built and installed on your average 'nix machine (and cygwin). [Download the latest release version](https://github.com/chapel-lang/chapel/releases/) and it's as easy as 1. `tar -xvf chapel-1.15.0.tar.gz` 2. `cd chapel-1.15.0` 3. `source util/setchplenv.bash # or .sh or .csh or .fish` 4. `make` 5. `make check # optional` You will need to `source util/setchplenv.EXT` from within the Chapel directory (`$CHPL_HOME`) every time your terminal starts so it's suggested that you drop that command in a script that will get executed on startup (like .bashrc). Chapel is easily installed with Brew for OS X 1. `brew update` 2. `brew install chapel` Compiling Code -------------- Builds like other compilers: `chpl myFile.chpl -o myExe` Notable arguments: * `--fast`: enables a number of optimizations and disables array bounds checks. Should only enable when application is stable. * `--set =`: set config param `` to `` at compile-time. * `--main-module `: use the main() procedure found in the module `` as the executable's main. * `--module-dir `: includes `` in the module search path. --- language: "CHICKEN" filename: CHICKEN.scm contributors: - ["Diwakar Wagle", "https://github.com/deewakar"] --- CHICKEN is an implementation of Scheme programming language that can compile Scheme programs to C code as well as interpret them. CHICKEN supports RSR5 and RSR7 (work in progress) standards and many extensions. ```scheme ;; #!/usr/bin/env csi -s ;; Run the CHICKEN REPL in the commandline as follows : ;; $ csi ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; 0. Syntax ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Single line comments start with a semicolon #| Block comments can span multiple lines and... #| can be nested |# |# ;; S-expression comments are used to comment out expressions #; (display "nothing") ; discard this expression ;; CHICKEN has two fundamental pieces of syntax: Atoms and S-expressions ;; an atom is something that evaluates to itself ;; all builtin data types viz. numbers, chars, booleans, strings etc. are atoms ;; Furthermore an atom can be a symbol, an identifier, a keyword, a procedure ;; or the empty list (also called null) 'athing ;; => athing '+ ;; => + + ;; => ;; S-expressions (short for symbolic expressions) consists of one or more atoms (quote +) ;; => + ; another way of writing '+ (+ 1 2 3) ;; => 6 ; this S-expression evaluates to a function call '(+ 1 2 3) ;; => (+ 1 2 3) ; evaluates to a list ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; 1. Primitive Datatypes and Operators ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Numbers 99999999999999999999 ;; integers #b1010 ;; binary ; => 10 #o10 ;; octal ; => 8 #x8ded ;; hexadecimal ; => 36333 3.14 ;; real 6.02e+23 3/4 ;; rational ;;Characters and Strings #\A ;; A char "Hello, World!" ;; strings are fixed-length arrays of characters ;; Booleans #t ;; true #f ;; false ;; Function call is written as (f x y z ...) ;; where f is a function and x,y,z, ... are arguments (print "Hello, World!") ;; => Hello, World! ;; formatted output (printf "Hello, ~a.\n" "World") ;; => Hello, World. ;; print commandline arguments (map print (command-line-arguments)) (list 'foo 'bar 'baz) ;; => (foo bar baz) (string-append "pine" "apple") ;; => "pineapple" (string-ref "tapioca" 3) ;; => #\i;; character 'i' is at index 3 (string->list "CHICKEN") ;; => (#\C #\H #\I #\C #\K #\E #\N) (string->intersperse '("1" "2") ":") ;; => "1:2" (string-split "1:2:3" ":") ;; => ("1" "2" "3") ;; Predicates are special functions that return boolean values (atom? #t) ;; => #t (symbol? #t) ;; => #f (symbol? '+) ;; => #t (procedure? +) ;; => #t (pair? '(1 2)) ;; => #t (pair? '(1 2 . 3)) ;; => #t (pair? '()) ;; => #f (list? '()) ;; => #t ;; Some arithmetic operations (+ 1 1) ;; => 2 (- 8 1) ;; => 7 (* 10 2) ;; => 20 (expt 2 3) ;; => 8 (remainder 5 2) ;; => 1 (/ 35 5) ;; => 7 (/ 1 3) ;; => 0.333333333333333 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; 2. Variables ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; You can create variables with define ;; A variable name can use any character except: ()[]{}",'`;#\ (define myvar 5) myvar ;; => 5 ;; Alias to a procedure (define ** expt) (** 2 3) ;; => 8 ;; Accessing an undefined variable raises an exception s ;; => Error: unbound variable: s ;; Local binding (let ((me "Bob")) (print me)) ;; => Bob (print me) ;; => Error: unbound variable: me ;; Assign a new value to previously defined variable (set! myvar 10) myvar ;; => 10 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; 3. Collections ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Pairs ;; 'cons' constructs pairs, ;; 'car' extracts the first element, 'cdr' extracts the rest of the elements (cons 'subject 'verb) ;; => '(subject . verb) (car (cons 'subject 'verb)) ;; => subject (cdr (cons 'subject 'verb)) ;; => verb ;; Lists ;; cons creates a new list if the second item is a list (cons 0 '()) ;; => (0) (cons 1 (cons 2 (cons 3 '()))) ;; => (1 2 3) ;; 'list' is a convenience variadic constructor for lists (list 1 2 3) ;; => (1 2 3) ;; Use 'append' to append lists together (append '(1 2) '(3 4)) ;; => (1 2 3 4) ;; Some basic operations on lists (map add1 '(1 2 3)) ;; => (2 3 4) (reverse '(1 3 4 7)) ;; => (7 4 3 1) (sort '(11 22 33 44) >) ;; => (44 33 22 11) (define days '(SUN MON FRI)) (list-ref days 1) ;; => MON (set! (list-ref days 1) 'TUE) days ;; => (SUN TUE FRI) ;; Vectors ;; Vectors are heterogeneous structures whose elements are indexed by integers ;; A Vector typically occupies less space than a list of the same length ;; Random access of an element in a vector is faster than in a list #(1 2 3) ;; => #(1 2 3) ;; literal syntax (vector 'a 'b 'c) ;; => #(a b c) (vector? #(1 2 3)) ;; => #t (vector-length #(1 (2) "a")) ;; => 3 (vector-ref #(1 (2) (3 3)) 2);; => (3 3) (define vec #(1 2 3)) (vector-set! vec 2 4) vec ;; => #(1 2 4) ;; Vectors can be created from lists and vice-verca (vector->list #(1 2 4)) ;; => '(1 2 4) (list->vector '(a b c)) ;; => #(a b c) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; 4. Functions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Use 'lambda' to create functions. ;; A function always returns the value of its last expression (lambda () "Hello World") ;; => # ;; Use extra parens around function definition to execute ((lambda () "Hello World")) ;; => Hello World ;; argument list is empty ;; A function with an argument ((lambda (x) (* x x)) 3) ;; => 9 ;; A function with two arguments ((lambda (x y) (* x y)) 2 3) ;; => 6 ;; assign a function to a variable (define sqr (lambda (x) (* x x))) sqr ;; => # (sqr 3) ;; => 9 ;; We can shorten this using the function definition syntactic sugar (define (sqr x) (* x x)) (sqr 3) ;; => 9 ;; We can redefine existing procedures (foldl cons '() '(1 2 3 4 5)) ;; => (((((() . 1) . 2) . 3) . 4) . 5) (define (foldl func accu alist) (if (null? alist) accu (foldl func (func (car alist) accu) (cdr alist)))) (foldl cons '() '(1 2 3 4 5)) ;; => (5 4 3 2 1) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; 5. Equality ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; For numbers use '=' (= 3 3.0) ;; => #t (= 2 1) ;; => #f ;; 'eq?' returns #t if two arguments refer to the same object in memory ;; In other words, it's a simple pointer comparison. (eq? '() '()) ;; => #t ;; there's only one empty list in memory (eq? (list 3) (list 3)) ;; => #f ;; not the same object (eq? 'yes 'yes) ;; => #t (eq? 3 3) ;; => #t ;; don't do this even if it works in this case (eq? 3 3.0) ;; => #f ;; it's better to use '=' for number comparisons (eq? "Hello" "Hello") ;; => #f ;; 'eqv?' is same as 'eq?' all datatypes except numbers and characters (eqv? 3 3.0) ;; => #f (eqv? (expt 2 3) (expt 2 3)) ;; => #t (eqv? 'yes 'yes) ;; => #t ;; 'equal?' recursively compares the contents of pairs, vectors, and strings, ;; applying eqv? on other objects such as numbers and symbols. ;; A rule of thumb is that objects are generally equal? if they print the same. (equal? '(1 2 3) '(1 2 3)) ;; => #t (equal? #(a b c) #(a b c)) ;; => #t (equal? 'a 'a) ;; => #t (equal? "abc" "abc") ;; => #t ;; In Summary: ;; eq? tests if objects are identical ;; eqv? tests if objects are operationally equivalent ;; equal? tests if objects have same structure and contents ;; Comparing strings for equality (string=? "Hello" "Hello") ;; => #t ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; 6. Control Flow ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Conditionals (if #t ;; test expression "True" ;; then expression "False") ;; else expression ;; => "True" (if (> 3 2) "yes" "no") ;; => "yes" ;; In conditionals, all values that are not '#f' are treated as true. ;; 0, '(), #() "" , are all true values (if 0 "0 is not false" "0 is false") ;; => "0 is not false" ;; 'cond' chains a series of tests and returns as soon as it encounters a true condition ;; 'cond' can be used to simulate 'if/elseif/else' statements (cond ((> 2 2) "not true so don't return this") ((< 2 5) "true, so return this") (else "returning default")) ;; => "true, so return this" ;; A case expression is evaluated as follows: ;; The key is evaluated and compared with each datum in sense of 'eqv?', ;; The corresponding clause in the matching datum is evaluated and returned as result (case (* 2 3) ;; the key is 6 ((2 3 5 7) 'prime) ;; datum 1 ((1 4 6 8) 'composite)) ;; datum 2; matched! ;; => composite ;; case with else clause (case (car '(c d)) ((a e i o u) 'vowel) ((w y) 'semivowel) (else 'consonant)) ;; => consonant ;; Boolean expressions ;; 'and' returns the first expression that evaluates to #f ;; otherwise, it returns the result of the last expression (and #t #f (= 2 2.0)) ;; => #f (and (< 2 5) (> 2 0) "0 < 2 < 5") ;; => "0 < 2 < 5" ;; 'or' returns the first expression that evaluates to #t ;; otherwise the result of the last expression is returned (or #f #t #f) ;; => #t (or #f #f #f) ;; => #f ;; 'when' is like 'if' without the else expression (when (positive? 5) "I'm positive") ;; => "I'm positive" ;; 'unless' is equivalent to (when (not ) ) (unless (null? '(1 2 3)) "not null") ;; => "not null" ;; Loops ;; loops can be created with the help of tail-recursions (define (loop count) (unless (= count 0) (print "hello") (loop (sub1 count)))) (loop 4) ;; => hello, hello ... ;; Or with a named let (let loop ((i 0) (limit 5)) (when (< i limit) (printf "i = ~a\n" i) (loop (add1 i) limit))) ;; => i = 0, i = 1.... ;; 'do' is another iteration construct ;; It initializes a set of variables and updates them in each iteration ;; A final expression is evaluated after the exit condition is met (do ((x 0 (add1 x ))) ;; initialize x = 0 and add 1 in each iteration ((= x 10) (print "done")) ;; exit condition and final expression (print x)) ;; command to execute in each step ;; => 0,1,2,3....9,done ;; Iteration over lists (for-each (lambda (a) (print (* a a))) '(3 5 7)) ;; => 9, 25, 49 ;; 'map' is like for-each but returns a list (map add1 '(11 22 33)) ;; => (12 23 34) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; 7. Extensions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; The CHICKEN core is very minimal, but additional features are provided by library extensions known as Eggs. ;; You can install Eggs with 'chicken-install ' command. ;; 'numbers' egg provides support for full numeric tower. (require-extension numbers) ;; complex numbers 3+4i ;; => 3+2i ;; Supports fractions without falling back to inexact flonums 1/3 ;; => 1/3 ;; provides support for large integers through bignums (expt 9 20) ;; => 12157665459056928801 ;; And other 'extended' functions (log 10 (exp 1)) ;; => 2.30258509299405 (numerator 2/3) ;; => 2 ;; 'utf8' provides unicode support (require-extension utf8) "\u03BBx:(\u03BC\u0251.\u0251\u2192\u0251).xx" ;; => "λx:(μɑ.ɑ→ɑ).xx" ;; 'posix' provides file I/O and lots of other services for unix-like operating systems ;; Some of the functions are not available in Windows system, ;; See http://wiki.call-cc.org/man/4/Unit%20posix for more details ;; Open a file to append, open "write only" and create file if it does not exist (define outfn (file-open "chicken-hen.txt" (+ open/append open/wronly open/creat))) ;; write some text to the file (file-write outfn "Did chicken came before hen?") ;; close the file (file-close outfn) ;; Open the file "read only" (define infn (file-open "chicken-hen.txt" open/rdonly)) ;; read some text from the file (file-read infn 30) ;; => ("Did chicken came before hen? ", 28) (file-close infn) ;; CHICKEN also supports SRFI (Scheme Requests For Implementation) extensions ;; See 'http://srfi.schemers.org/srfi-implementers.html" to see srfi's supported by CHICKEN (require-extension srfi-1) ;; list library (filter odd? '(1 2 3 4 5 6 7)) ;; => (1 3 5 7) (count even? '(1 2 3 4 5)) ;; => 2 (take '(12 24 36 48 60) 3) ;; => (12 24 36) (drop '(12 24 36 48 60) 2) ;; => (36 48 60) (circular-list 'z 'q) ;; => z q z q ... (require-extension srfi-13) ;; string library (string-reverse "pan") ;; => "nap" (string-index "Turkey" #\k) ;; => 3 (string-every char-upper-case? "CHICKEN") ;; => #t (string-join '("foo" "bar" "baz") ":") ;; => "foo:bar:baz" ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; 8. Macros ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; A 'for .. in ..' iteration like python, for lists (define-syntax for (syntax-rules (in) ((for elem in alist body ...) (for-each (lambda (elem) body ...) alist)))) (for x in '(2 4 8 16) (print x)) ;; => 2, 4, 8, 16 (for chr in (string->list "PENCHANT") (print chr)) ;; => P, E, N, C, H, A, N, T ;; While loop (define-syntax while (syntax-rules () ((while cond body ...) (let loop () (when cond body ... (loop)))))) (let ((str "PENCHANT") (i 0)) (while (< i (string-length str)) ;; while (condition) (print (string-ref str i)) ;; body (set! i (add1 i)))) ;; => P, E, N, C, H, A, N, T ;; Advanced Syntax-Rules Primer -> http://petrofsky.org/src/primer.txt ;; Macro system in chicken -> http://lists.gnu.org/archive/html/chicken-users/2008-04/msg00013.html ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; 9. Modules ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Also See http://wiki.call-cc.org/man/4/Modules ;; The 'test' module exports a value named 'hello' and a macro named 'greet' (module test (hello greet) (import scheme) (define-syntax greet (syntax-rules () ((_ whom) (begin (display "Hello, ") (display whom) (display " !\n") ) ) ) ) (define (hello) (greet "world") ) ) ;; we can define our modules in a separate file (say test.scm) and load them to the interpreter with ;; (load "test.scm") ;; import the module (import test) (hello) ;; => Hello, world ! (greet "schemers") ;; => Hello, schemers ! ;; We can compile the module files in to shared libraries by using following command, ;; csc -s test.scm ;; (load "test.so") ;; Functors ;; Functors are high level modules that can be parameterized by other modules ;; Following functor requires another module named 'M' that provides a function called 'multiply' ;; The functor itself exports a generic function 'square' (functor (squaring-functor (M (multiply))) (square) (import scheme M) (define (square x) (multiply x x))) ;; Module 'nums' can be passed as a parameter to 'squaring-functor' (module nums (multiply) (import scheme) ;; predefined modules (define (multiply x y) (* x y))) ;; the final module can be imported and used in our program (module number-squarer = (squaring-functor nums)) (import number-squarer) (square 3) ;; => 9 ;; We can instantiate the functor for other inputs ;; Here's another example module that can be passed to squaring-functor (module stars (multiply) (import chicken scheme) ;; chicken module for the 'use' keyword (use srfi-1) ;; we can use external libraries in our module (define (multiply x y) (list-tabulate x (lambda _ (list-tabulate y (lambda _ '*)))))) (module star-squarer = (squaring-functor stars)) (import star-squarer) (square 3) ;; => ((* * *)(* * *)(* * *)) ``` ## Further Reading * [CHICKEN User's Manual](http://wiki.call-cc.org/man/4/The%20User%27s%20Manual). * [RSR5 standards](http://www.schemers.org/Documents/Standards/R5RS) ## Extra Info * [For programmers of other languages](http://wiki.call-cc.org/chicken-for-programmers-of-other-languages) * [Compare CHICKEN syntax with other languages](http://plr.sourceforge.net/cgi-bin/plr/launch.py) --- language: "clojure macros" filename: learnclojuremacros.clj contributors: - ["Adam Bard", "http://adambard.com/"] --- As with all Lisps, Clojure's inherent [homoiconicity](https://en.wikipedia.org/wiki/Homoiconic) gives you access to the full extent of the language to write code-generation routines called "macros". Macros provide a powerful way to tailor the language to your needs. Be careful though. It's considered bad form to write a macro when a function will do. Use a macro only when you need control over when or if the arguments to a form will be evaluated. You'll want to be familiar with Clojure. Make sure you understand everything in [Clojure in Y Minutes](/docs/clojure/). ```clojure ;; Define a macro using defmacro. Your macro should output a list that can ;; be evaluated as clojure code. ;; ;; This macro is the same as if you wrote (reverse "Hello World") (defmacro my-first-macro [] (list reverse "Hello World")) ;; Inspect the result of a macro using macroexpand or macroexpand-1. ;; ;; Note that the call must be quoted. (macroexpand '(my-first-macro)) ;; -> (# "Hello World") ;; You can eval the result of macroexpand directly: (eval (macroexpand '(my-first-macro))) ; -> (\d \l \o \r \W \space \o \l \l \e \H) ;; But you should use this more succinct, function-like syntax: (my-first-macro) ; -> (\d \l \o \r \W \space \o \l \l \e \H) ;; You can make things easier on yourself by using the more succinct quote syntax ;; to create lists in your macros: (defmacro my-first-quoted-macro [] '(reverse "Hello World")) (macroexpand '(my-first-quoted-macro)) ;; -> (reverse "Hello World") ;; Notice that reverse is no longer function object, but a symbol. ;; Macros can take arguments. (defmacro inc2 [arg] (list + 2 arg)) (inc2 2) ; -> 4 ;; But, if you try to do this with a quoted list, you'll get an error, because ;; the argument will be quoted too. To get around this, clojure provides a ;; way of quoting macros: `. Inside `, you can use ~ to get at the outer scope (defmacro inc2-quoted [arg] `(+ 2 ~arg)) (inc2-quoted 2) ;; You can use the usual destructuring args. Expand list variables using ~@ (defmacro unless [arg & body] `(if (not ~arg) (do ~@body))) ; Remember the do! (macroexpand '(unless true (reverse "Hello World"))) ;; -> ;; (if (clojure.core/not true) (do (reverse "Hello World"))) ;; (unless) evaluates and returns its body if the first argument is false. ;; Otherwise, it returns nil (unless true "Hello") ; -> nil (unless false "Hello") ; -> "Hello" ;; Used without care, macros can do great evil by clobbering your vars (defmacro define-x [] '(do (def x 2) (list x))) (def x 4) (define-x) ; -> (2) (list x) ; -> (2) ;; To avoid this, use gensym to get a unique identifier (gensym 'x) ; -> x1281 (or some such thing) (defmacro define-x-safely [] (let [sym (gensym 'x)] `(do (def ~sym 2) (list ~sym)))) (def x 4) (define-x-safely) ; -> (2) (list x) ; -> (4) ;; You can use # within ` to produce a gensym for each symbol automatically (defmacro define-x-hygienically [] `(do (def x# 2) (list x#))) (def x 4) (define-x-hygienically) ; -> (2) (list x) ; -> (4) ;; It's typical to use helper functions with macros. Let's create a few to ;; help us support a (dumb) inline arithmetic syntax (declare inline-2-helper) (defn clean-arg [arg] (if (seq? arg) (inline-2-helper arg) arg)) (defn apply-arg "Given args [x (+ y)], return (+ x y)" [val [op arg]] (list op val (clean-arg arg))) (defn inline-2-helper [[arg1 & ops-and-args]] (let [ops (partition 2 ops-and-args)] (reduce apply-arg (clean-arg arg1) ops))) ;; We can test it immediately, without creating a macro (inline-2-helper '(a + (b - 2) - (c * 5))) ; -> (- (+ a (- b 2)) (* c 5)) ; However, we'll need to make it a macro if we want it to be run at compile time (defmacro inline-2 [form] (inline-2-helper form))) (macroexpand '(inline-2 (1 + (3 / 2) - (1 / 2) + 1))) ; -> (+ (- (+ 1 (/ 3 2)) (/ 1 2)) 1) (inline-2 (1 + (3 / 2) - (1 / 2) + 1)) ; -> 3 (actually, 3N, since the number got cast to a rational fraction with /) ``` ### Further Reading Writing Macros from [Clojure for the Brave and True](http://www.braveclojure.com/) [http://www.braveclojure.com/writing-macros/](http://www.braveclojure.com/writing-macros/) Official docs [http://clojure.org/macros](http://clojure.org/macros) When to use macros? [http://dunsmor.com/lisp/onlisp/onlisp_12.html](http://dunsmor.com/lisp/onlisp/onlisp_12.html) --- language: clojure filename: learnclojure.clj contributors: - ["Adam Bard", "http://adambard.com/"] --- Clojure is a Lisp family language developed for the Java Virtual Machine. It has a much stronger emphasis on pure [functional programming](https://en.wikipedia.org/wiki/Functional_programming) than Common Lisp, but includes several [STM](https://en.wikipedia.org/wiki/Software_transactional_memory) utilities to handle 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. ; Clojure is written in "forms", which are just ; lists of things inside parentheses, separated by whitespace. ; ; The clojure reader assumes that the first thing is a ; function or macro to call, and the rest are arguments. ; The first call in a file should be ns, to set the namespace (ns learnclojure) ; More basic examples: ; str will create a string out of all its arguments (str "Hello" " " "World") ; => "Hello World" ; Math is straightforward (+ 1 1) ; => 2 (- 2 1) ; => 1 (* 1 2) ; => 2 (/ 2 1) ; => 2 ; Equality is = (= 1 1) ; => true (= 2 1) ; => false ; You need not for logic, too (not true) ; => false ; Nesting forms works as you expect (+ 1 (- 3 2)) ; = 1 + (3 - 2) => 2 ; Types ;;;;;;;;;;;;; ; Clojure uses Java's object types for booleans, strings and numbers. ; Use `class` to inspect them. (class 1) ; Integer literals are java.lang.Long by default (class 1.); Float literals are java.lang.Double (class ""); Strings always double-quoted, and are java.lang.String (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 stop it from ; being evaluated '(+ 1 2) ; => (+ 1 2) ; (shorthand for (quote (+ 1 2))) ; You can eval a quoted list (eval '(+ 1 2)) ; => 3 ; Collections & Sequences ;;;;;;;;;;;;;;;;;;; ; Lists are linked-list data structures, while Vectors are array-backed. ; Vectors and Lists are java classes too! (class [1 2 3]); => clojure.lang.PersistentVector (class '(1 2 3)); => clojure.lang.PersistentList ; A list would be written as just (1 2 3), but we have to quote ; it to stop the reader thinking it's a function. ; Also, (list 1 2 3) is the same as '(1 2 3) ; "Collections" are just groups of data ; Both lists and vectors are collections: (coll? '(1 2 3)) ; => true (coll? [1 2 3]) ; => true ; "Sequences" (seqs) are abstract descriptions of lists of data. ; Only lists are seqs. (seq? '(1 2 3)) ; => true (seq? [1 2 3]) ; => false ; A seq need only provide an entry when it is accessed. ; So, seqs which can be lazy -- they can define infinite series: (range 4) ; => (0 1 2 3) (range) ; => (0 1 2 3 4 ...) (an infinite series) (take 4 (range)) ; (0 1 2 3) ; Use cons to add an item to the beginning of a list or vector (cons 4 [1 2 3]) ; => (4 1 2 3) (cons 4 '(1 2 3)) ; => (4 1 2 3) ; Conj will add an item to a collection in the most efficient way. ; For lists, they insert at the beginning. For vectors, they insert at the end. (conj [1 2 3] 4) ; => [1 2 3 4] (conj '(1 2 3) 4) ; => (4 1 2 3) ; Use concat to add lists or vectors together (concat [1 2] '(3 4)) ; => (1 2 3 4) ; Use filter, map to interact with collections (map inc [1 2 3]) ; => (2 3 4) (filter even? [1 2 3]) ; => (2) ; Use reduce to reduce them (reduce + [1 2 3 4]) ; = (+ (+ (+ 1 2) 3) 4) ; => 10 ; Reduce can take an initial-value argument too (reduce conj [] '(3 2 1)) ; = (conj (conj (conj [] 3) 2) 1) ; => [3 2 1] ; Functions ;;;;;;;;;;;;;;;;;;;;; ; Use fn to create new functions. A function always returns ; its last statement. (fn [] "Hello World") ; => fn ; (You need extra parens to call it) ((fn [] "Hello World")) ; => "Hello World" ; You can create a var using def (def x 1) x ; => 1 ; Assign a function to a var (def hello-world (fn [] "Hello World")) (hello-world) ; => "Hello World" ; You can shorten this process by using defn (defn hello-world [] "Hello World") ; The [] is the list of arguments for the function. (defn hello [name] (str "Hello " name)) (hello "Steve") ; => "Hello Steve" ; You can also use this shorthand to create functions: (def hello2 #(str "Hello " %1)) (hello2 "Fanny") ; => "Hello Fanny" ; You can have multi-variadic functions, too (defn hello3 ([] "Hello World") ([name] (str "Hello " name))) (hello3 "Jake") ; => "Hello Jake" (hello3) ; => "Hello World" ; Functions can pack extra arguments up in a seq for you (defn count-args [& args] (str "You passed " (count args) " args: " args)) (count-args 1 2 3) ; => "You passed 3 args: (1 2 3)" ; You can mix regular and packed arguments (defn hello-count [name & args] (str "Hello " name ", you passed " (count args) " extra args")) (hello-count "Finn" 1 2 3) ; => "Hello Finn, you passed 3 extra args" ; Maps ;;;;;;;;;; ; Hash maps and array maps share an interface. Hash maps have faster lookups ; but don't retain key order. (class {:a 1 :b 2 :c 3}) ; => clojure.lang.PersistentArrayMap (class (hash-map :a 1 :b 2 :c 3)) ; => clojure.lang.PersistentHashMap ; Arraymaps will automatically become hashmaps through most operations ; if they get big enough, so you don't need to worry. ; Maps can use any hashable type as a key, but usually keywords are best ; Keywords are like strings with some efficiency bonuses (class :a) ; => clojure.lang.Keyword (def stringmap {"a" 1, "b" 2, "c" 3}) stringmap ; => {"a" 1, "b" 2, "c" 3} (def keymap {:a 1, :b 2, :c 3}) keymap ; => {:a 1, :c 3, :b 2} ; By the way, commas are always treated as whitespace and do nothing. ; Retrieve a value from a map by calling it as a function (stringmap "a") ; => 1 (keymap :a) ; => 1 ; Keywords can be used to retrieve their value from a map, too! (:b keymap) ; => 2 ; Don't try this with strings. ;("a" stringmap) ; => Exception: java.lang.String cannot be cast to clojure.lang.IFn ; Retrieving a non-present key returns nil (stringmap "d") ; => nil ; Use assoc to add new keys to hash-maps (def newkeymap (assoc keymap :d 4)) newkeymap ; => {:a 1, :b 2, :c 3, :d 4} ; But remember, clojure types are immutable! keymap ; => {:a 1, :b 2, :c 3} ; Use dissoc to remove keys (dissoc keymap :a :b) ; => {:c 3} ; Sets ;;;;;; (class #{1 2 3}) ; => clojure.lang.PersistentHashSet (set [1 2 3 1 2 3 3 2 1 3 2 1]) ; => #{1 2 3} ; Add a member with conj (conj #{1 2 3} 4) ; => #{1 2 3 4} ; Remove one with disj (disj #{1 2 3} 1) ; => #{2 3} ; Test for existence by using the set as a function: (#{1 2 3} 1) ; => 1 (#{1 2 3} 4) ; => nil ; There are more functions in the clojure.sets namespace. ; Useful forms ;;;;;;;;;;;;;;;;; ; Logic constructs in clojure are just macros, and look like ; everything else (if false "a" "b") ; => "b" (if false "a") ; => nil ; Use let to create temporary bindings (let [a 1 b 2] (> a b)) ; => false ; Group statements together with do (do (print "Hello") "World") ; => "World" (prints "Hello") ; Functions have an implicit do (defn print-and-say-hello [name] (print "Saying hello to " name) (str "Hello " name)) (print-and-say-hello "Jeff") ;=> "Hello Jeff" (prints "Saying hello to Jeff") ; So does let (let [name "Urkel"] (print "Saying hello to " name) (str "Hello " name)) ; => "Hello Urkel" (prints "Saying hello to Urkel") ; Use the threading macros (-> and ->>) to express transformations of ; data more clearly. ; The "Thread-first" macro (->) inserts into each form the result of ; the previous, as the first argument (second item) (-> {:a 1 :b 2} (assoc :c 3) ;=> (assoc {:a 1 :b 2} :c 3) (dissoc :b)) ;=> (dissoc (assoc {:a 1 :b 2} :c 3) :b) ; This expression could be written as: ; (dissoc (assoc {:a 1 :b 2} :c 3) :b) ; and evaluates to {:a 1 :c 3} ; The double arrow does the same thing, but inserts the result of ; each line at the *end* of the form. This is useful for collection ; operations in particular: (->> (range 10) (map inc) ;=> (map inc (range 10) (filter odd?) ;=> (filter odd? (map inc (range 10)) (into [])) ;=> (into [] (filter odd? (map inc (range 10))) ; Result: [1 3 5 7 9] ; When you are in a situation where you want more freedom as where to ; put the result of previous data transformations in an ; expression, you can use the as-> macro. With it, you can assign a ; specific name to transformations' output and use it as a ; placeholder in your chained expressions: (as-> [1 2 3] input (map inc input);=> You can use last transform's output at the last position (nth input 2) ;=> and at the second position, in the same expression (conj [4 5 6] input [8 9 10])) ;=> or in the middle ! ; Modules ;;;;;;;;;;;;;;; ; Use "use" to get all functions from the module (use 'clojure.set) ; Now we can use set operations (intersection #{1 2 3} #{2 3 4}) ; => #{2 3} (difference #{1 2 3} #{2 3 4}) ; => #{1} ; You can choose a subset of functions to import, too (use '[clojure.set :only [intersection]]) ; Use require to import a module (require 'clojure.string) ; Use / to call functions from a module ; Here, the module is clojure.string and the function is blank? (clojure.string/blank? "") ; => true ; You can give a module a shorter name on import (require '[clojure.string :as str]) (str/replace "This is a test." #"[a-o]" str/upper-case) ; => "THIs Is A tEst." ; (#"" denotes a regular expression literal) ; You can use require (and use, but don't) from a namespace using :require. ; You don't need to quote your modules if you do it this way. (ns test (:require [clojure.string :as str] [clojure.set :as set])) ; Java ;;;;;;;;;;;;;;;;; ; Java has a huge and useful standard library, so ; you'll want to learn how to get at it. ; Use import to load a java module (import java.util.Date) ; You can import from an ns too. (ns test (:import java.util.Date java.util.Calendar)) ; Use the class name with a "." at the end to make a new instance (Date.) ; ; Use . to call methods. Or, use the ".method" shortcut (. (Date.) getTime) ; (.getTime (Date.)) ; exactly the same thing. ; Use / to call static methods (System/currentTimeMillis) ; (system is always present) ; Use doto to make dealing with (mutable) classes more tolerable (import java.util.Calendar) (doto (Calendar/getInstance) (.set 2000 1 1 0 0 0) .getTime) ; => A Date. set to 2000-01-01 00:00:00 ; STM ;;;;;;;;;;;;;;;;; ; Software Transactional Memory is the mechanism clojure uses to handle ; persistent state. There are a few constructs in clojure that use this. ; An atom is the simplest. Pass it an initial value (def my-atom (atom {})) ; Update an atom with swap!. ; swap! takes a function and calls it with the current value of the atom ; as the first argument, and any trailing arguments as the second (swap! my-atom assoc :a 1) ; Sets my-atom to the result of (assoc {} :a 1) (swap! my-atom assoc :b 2) ; Sets my-atom to the result of (assoc {:a 1} :b 2) ; Use '@' to dereference the atom and get the value my-atom ;=> Atom<#...> (Returns the Atom object) @my-atom ; => {:a 1 :b 2} ; Here's a simple counter using an atom (def counter (atom 0)) (defn inc-counter [] (swap! counter inc)) (inc-counter) (inc-counter) (inc-counter) (inc-counter) (inc-counter) @counter ; => 5 ; Other STM constructs are refs and agents. ; Refs: http://clojure.org/refs ; Agents: http://clojure.org/agents ``` ### Further Reading This is far from exhaustive, but hopefully it's enough to get you on your feet. Clojure.org has lots of articles: [http://clojure.org/](http://clojure.org/) Clojuredocs.org has documentation with examples for most core functions: [http://clojuredocs.org/quickref/Clojure%20Core](http://clojuredocs.org/quickref/Clojure%20Core) 4Clojure is a great way to build your clojure/FP skills: [http://www.4clojure.com/](http://www.4clojure.com/) Clojure-doc.org (yes, really) has a number of getting started articles: [http://clojure-doc.org/](http://clojure-doc.org/) --- language: cmake contributors: - ["Bruno Alano", "https://github.com/brunoalano"] filename: CMake --- CMake is a cross-platform, open-source build system. This tool will allow you to test, compile and create packages of your source code. The problem that CMake tries to solve is the problem of Makefiles and Autoconfigure on cross-platforms (different make interpreters have different command) and the ease-of-use on linking 3rd party libraries. CMake is an extensible, open-source system that manages the build process in an operating system and compiler-independent manner. Unlike many cross-platform systems, CMake is designed to be used in conjunction with the native build environment. Simple configuration files placed in each source directory (called CMakeLists.txt files) are used to generate standard build files (e.g., makefiles on Unix and projects/workspaces in Windows MSVC) which are used in the usual way. ```cmake # In CMake, this is a comment # To run our code, we will use these steps: # - mkdir build && cd build # - cmake .. # - make # # With those steps, we will follow the best practice to compile into a subdir # and the second line will request to CMake to generate a new OS-dependent # Makefile. Finally, run the native Make command. #------------------------------------------------------------------------------ # Basic #------------------------------------------------------------------------------ # # The CMake file MUST be named as "CMakeLists.txt". # Setup the minimum version required of CMake to generate the Makefile cmake_minimum_required (VERSION 2.8) # Raises a FATAL_ERROR if version < 2.8 cmake_minimum_required (VERSION 2.8 FATAL_ERROR) # We setup the name for our project. After we do that, this will change some # directories naming convention generated by CMake. We can send the LANG of # code as second param project (learncmake C) # Set the project source dir (just convention) set( LEARN_CMAKE_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR} ) set( LEARN_CMAKE_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR} ) # It's useful to setup the current version of our code in the build system # using a `semver` style set (LEARN_CMAKE_VERSION_MAJOR 1) set (LEARN_CMAKE_VERSION_MINOR 0) set (LEARN_CMAKE_VERSION_PATCH 0) # Send the variables (version number) to source code header configure_file ( "${PROJECT_SOURCE_DIR}/TutorialConfig.h.in" "${PROJECT_BINARY_DIR}/TutorialConfig.h" ) # Include Directories # In GCC, this will invoke the "-I" command include_directories( include ) # Where are the additional libraries installed? Note: provide includes # path here, subsequent checks will resolve everything else set( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/CMake/modules/" ) # Conditions if ( CONDITION ) # Output! # Incidental information message(STATUS "My message") # CMake Warning, continue processing message(WARNING "My message") # CMake Warning (dev), continue processing message(AUTHOR_WARNING "My message") # CMake Error, continue processing, but skip generation message(SEND_ERROR "My message") # CMake Error, stop processing and generation message(FATAL_ERROR "My message") endif() if( CONDITION ) elseif( CONDITION ) else( CONDITION ) endif( CONDITION ) # Loops foreach(loop_var arg1 arg2 ...) COMMAND1(ARGS ...) COMMAND2(ARGS ...) ... endforeach(loop_var) foreach(loop_var RANGE total) foreach(loop_var RANGE start stop [step]) foreach(loop_var IN [LISTS [list1 [...]]] [ITEMS [item1 [...]]]) while(condition) COMMAND1(ARGS ...) COMMAND2(ARGS ...) ... endwhile(condition) # Logic Operations if(FALSE AND (FALSE OR TRUE)) message("Don't display!") endif() # Set a normal, cache, or environment variable to a given value. # If the PARENT_SCOPE option is given the variable will be set in the scope # above the current scope. # `set( ... [PARENT_SCOPE])` # How to reference variables inside quoted and unquoted arguments # A variable reference is replaced by the value of the variable, or by the # empty string if the variable is not set ${variable_name} # Lists # Setup the list of source files set( LEARN_CMAKE_SOURCES src/main.c src/imagem.c src/pather.c ) # Calls the compiler # # ${PROJECT_NAME} refers to Learn_CMake add_executable( ${PROJECT_NAME} ${LEARN_CMAKE_SOURCES} ) # Link the libraries target_link_libraries( ${PROJECT_NAME} ${LIBS} m ) # Where are the additional libraries installed? Note: provide includes # path here, subsequent checks will resolve everything else set( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/CMake/modules/" ) # Compiler Condition (gcc ; g++) if ( "${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" ) message( STATUS "Setting the flags for ${CMAKE_C_COMPILER_ID} compiler" ) add_definitions( --std=c99 ) endif() # Check for OS if( UNIX ) set( LEARN_CMAKE_DEFINITIONS "${LEARN_CMAKE_DEFINITIONS} -Wall -Wextra -Werror -Wno-deprecated-declarations -Wno-unused-parameter -Wno-comment" ) endif() ``` ### More Resources + [cmake tutorial](https://cmake.org/cmake-tutorial/) + [cmake documentation](https://cmake.org/documentation/) + [mastering cmake](http://amzn.com/1930934319/) --- language: coffeescript contributors: - ["Tenor Biel", "http://github.com/L8D"] - ["Xavier Yao", "http://github.com/xavieryao"] filename: coffeescript.coffee --- CoffeeScript is a little language that compiles one-to-one into the equivalent JavaScript, and there is no interpretation at runtime. As one of the successors to JavaScript, CoffeeScript tries its best to output readable, pretty-printed and smooth-running JavaScript code, which works well in every JavaScript runtime. It also attempts to try and make JavaScript more in line with the trends of many modern languages. See also [the CoffeeScript website](http://coffeescript.org/), which has a complete tutorial on CoffeeScript. ```coffeescript # Comments are similar to Ruby and Python, using the hash symbol `#` ### Block comments are like these, and they translate directly to '/ *'s and '* /'s for the resulting JavaScript code. You should understand most of JavaScript semantics before continuing. ### # Assignment: number = 42 #=> var number = 42; opposite = true #=> var opposite = true; # Conditions: number = -42 if opposite #=> if(opposite) { number = -42; } # Functions: square = (x) -> x * x #=> var square = function(x) { return x * x; } fill = (container, liquid = "coffee") -> "Filling the #{container} with #{liquid}..." #=>var fill; # #fill = function(container, liquid) { # if (liquid == null) { # liquid = "coffee"; # } # return "Filling the " + container + " with " + liquid + "..."; #}; # Ranges: list = [1..5] #=> var list = [1, 2, 3, 4, 5]; # Objects: math = root: Math.sqrt square: square cube: (x) -> x * square x #=> var math = { # "root": Math.sqrt, # "square": square, # "cube": function(x) { return x * square(x); } # }; # Splats: race = (winner, runners...) -> print winner, runners #=>race = function() { # var runners, winner; # winner = arguments[0], runners = 2 <= arguments.length ? __slice.call(arguments, 1) : []; # return print(winner, runners); # }; # Existence: alert "I knew it!" if elvis? #=> if(typeof elvis !== "undefined" && elvis !== null) { alert("I knew it!"); } # Array comprehensions: cubes = (math.cube num for num in list) #=>cubes = (function() { # var _i, _len, _results; # _results = []; # for (_i = 0, _len = list.length; _i < _len; _i++) { # num = list[_i]; # _results.push(math.cube(num)); # } # return _results; # })(); foods = ['broccoli', 'spinach', 'chocolate'] eat food for food in foods when food isnt 'chocolate' #=>foods = ['broccoli', 'spinach', 'chocolate']; # #for (_k = 0, _len2 = foods.length; _k < _len2; _k++) { # food = foods[_k]; # if (food !== 'chocolate') { # eat(food); # } #} ``` ## Additional resources - [Smooth CoffeeScript](http://autotelicum.github.io/Smooth-CoffeeScript/) - [CoffeeScript Ristretto](https://leanpub.com/coffeescript-ristretto/read) --- language: coldfusion filename: learncoldfusion.cfm contributors: - ["Wayne Boka", "http://wboka.github.io"] - ["Kevin Morris", "https://twitter.com/kevinmorris"] --- ColdFusion is a scripting language for web development. [Read more here.](http://www.adobe.com/products/coldfusion-family.html) ### CFML _**C**old**F**usion **M**arkup **L**anguage_ ColdFusion started as a tag-based language. Almost all functionality is available using tags. ```cfm HTML tags have been provided for output readability " --->

Simple Variables

Set myVariable to "myValue"

Set myNumber to 3.14

Display myVariable: #myVariable#

Display myNumber: #myNumber#


Complex Variables

Set myArray1 to an array of 1 dimension using literal or bracket notation

Set myArray2 to an array of 1 dimension using function notation

Contents of myArray1

Contents of myArray2

Operators

Arithmetic

1 + 1 = #1 + 1#

10 - 7 = #10 - 7#

15 * 10 = #15 * 10#

100 / 5 = #100 / 5#

120 % 5 = #120 % 5#

120 mod 5 = #120 mod 5#


Comparison

Standard Notation

Is 1 eq 1? #1 eq 1#

Is 15 neq 1? #15 neq 1#

Is 10 gt 8? #10 gt 8#

Is 1 lt 2? #1 lt 2#

Is 10 gte 5? #10 gte 5#

Is 1 lte 5? #1 lte 5#

Alternative Notation

Is 1 == 1? #1 eq 1#

Is 15 != 1? #15 neq 1#

Is 10 > 8? #10 gt 8#

Is 1 < 2? #1 lt 2#

Is 10 >= 5? #10 gte 5#

Is 1 <= 5? #1 lte 5#


Control Structures

Condition to test for: "#myCondition#"

#myCondition#. We're testing. #myCondition#. Proceed Carefully!!! myCondition is unknown

Loops

For Loop

Index equals #i#

For Each Loop (Complex Variables)

Set myArray3 to [5, 15, 99, 45, 100]

Index equals #i#

Set myArray4 to ["Alpha", "Bravo", "Charlie", "Delta", "Echo"]

Index equals #s#

Switch Statement

Set myArray5 to [5, 15, 99, 45, 100]

#i# is a multiple of 5.

#i# is ninety-nine.

#i# is not 5, 15, 45, or 99.


Converting types

Value As Boolean As number As date-time As string
"Yes" TRUE 1 Error "Yes"
"No" FALSE 0 Error "No"
TRUE TRUE 1 Error "Yes"
FALSE FALSE 0 Error "No"
Number True if Number is not 0; False otherwise. Number See "Date-time values" earlier in this chapter. String representation of the number (for example, "8").
String If "Yes", True
If "No", False
If it can be converted to 0, False
If it can be converted to any other number, True
If it represents a number (for example, "1,000" or "12.36E-12"), it is converted to the corresponding number. If it represents a date-time (see next column), it is converted to the numeric value of the corresponding date-time object.
If it is an ODBC date, time, or timestamp (for example "{ts '2001-06-14 11:30:13'}", or if it is expressed in a standard U.S. date or time format, including the use of full or abbreviated month names, it is converted to the corresponding date-time value.
Days of the week or unusual punctuation result in an error.
Dashes, forward-slashes, and spaces are generally allowed.
String
Date Error The numeric value of the date-time object. Date An ODBC timestamp.

Components

Code for reference (Functions must return something to support IE) ``` ```cfs sayHello()

#sayHello()#

getHello()

#getHello()#

getWorld()

#getWorld()#

setHello("Hola")

#setHello("Hola")#

setWorld("mundo")

#setWorld("mundo")#

sayHello()

#sayHello()#

getHello()

#getHello()#

getWorld()

#getWorld()#

``` ### CFScript _**C**old**F**usion **S**cript_ In recent years, the ColdFusion language has added script syntax to mirror tag functionality. When using an up-to-date CF server, almost all functionality is available using scrypt syntax. ## Further Reading The links provided here below are just to get an understanding of the topic, feel free to Google and find specific examples. 1. [Coldfusion Reference From Adobe](https://helpx.adobe.com/coldfusion/cfml-reference/topics.html) 2. [Open Source Documentation](http://cfdocs.org/) --- language: "Common Lisp" filename: commonlisp.lisp contributors: - ["Paul Nathan", "https://github.com/pnathan"] --- ANSI Common Lisp is a general purpose, multi-paradigm programming language suited for a wide variety of industry applications. It is frequently referred to as a programmable programming language. The classic starting point is [Practical Common Lisp and freely available.](http://www.gigamonkeys.com/book/) Another popular and recent book is [Land of Lisp](http://landoflisp.com/). ```common_lisp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; 0. Syntax ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; General form. ;; Lisp has two fundamental pieces of syntax: the ATOM and the ;; S-expression. Typically, grouped S-expressions are called `forms`. 10 ; an atom; it evaluates to itself :THING ;Another atom; evaluating to the symbol :thing. t ; another atom, denoting true. (+ 1 2 3 4) ; an s-expression '(4 :foo t) ;another one ;;; Comments ;; Single line comments start with a semicolon; use two for normal ;; comments, three for section comments, and four for file-level ;; comments. #| Block comments can span multiple lines and... #| they can be nested! |# |# ;;; Environment. ;; A variety of implementations exist; most are ;; standard-conformant. CLISP is a good starting one. ;; Libraries are managed through Quicklisp.org's Quicklisp system. ;; Common Lisp is usually developed with a text editor and a REPL ;; (Read Evaluate Print Loop) running at the same time. The REPL ;; allows for interactive exploration of the program as it is "live" ;; in the system. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; 1. Primitive Datatypes and Operators ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Symbols 'foo ; => FOO Notice that the symbol is upper-cased automatically. ;; Intern manually creates a symbol from a string. (intern "AAAA") ; => AAAA (intern "aaa") ; => |aaa| ;;; Numbers 9999999999999999999999 ; integers #b111 ; binary => 7 #o111 ; octal => 73 #x111 ; hexadecimal => 273 3.14159s0 ; single 3.14159d0 ; double 1/2 ; ratios #C(1 2) ; complex numbers ;; Function application is written (f x y z ...) ;; where f is a function and x, y, z, ... are operands ;; If you want to create a literal list of data, use ' to stop it from ;; being evaluated - literally, "quote" the data. '(+ 1 2) ; => (+ 1 2) ;; You can also call a function manually: (funcall #'+ 1 2 3) ; => 6 ;; Some arithmetic operations (+ 1 1) ; => 2 (- 8 1) ; => 7 (* 10 2) ; => 20 (expt 2 3) ; => 8 (mod 5 2) ; => 1 (/ 35 5) ; => 7 (/ 1 3) ; => 1/3 (+ #C(1 2) #C(6 -4)) ; => #C(7 -2) ;;; Booleans t ; for true (any not-nil value is true) nil ; for false - and the empty list (not nil) ; => t (and 0 t) ; => t (or 0 nil) ; => 0 ;;; Characters #\A ; => #\A #\λ ; => #\GREEK_SMALL_LETTER_LAMDA #\u03BB ; => #\GREEK_SMALL_LETTER_LAMDA ;;; Strings are fixed-length arrays of characters. "Hello, world!" "Benjamin \"Bugsy\" Siegel" ; backslash is an escaping character ;; Strings can be concatenated too! (concatenate 'string "Hello " "world!") ; => "Hello world!" ;; A string can be treated like a sequence of characters (elt "Apple" 0) ; => #\A ;; format can be used to format strings: (format nil "~a can be ~a" "strings" "formatted") ;; Printing is pretty easy; ~% is the format specifier for newline. (format t "Common Lisp is groovy. Dude.~%") ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; 2. Variables ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; You can create a global (dynamically scoped) using defparameter ;; a variable name can use any character except: ()",'`;#|\ ;; Dynamically scoped variables should have earmuffs in their name! (defparameter *some-var* 5) *some-var* ; => 5 ;; You can also use unicode characters. (defparameter *AΛB* nil) ;; Accessing a previously unbound variable is an ;; undefined behavior (but possible). Don't do it. ;; Local binding: `me` is bound to "dance with you" only within the ;; (let ...). Let always returns the value of the last `form` in the ;; let form. (let ((me "dance with you")) me) ;; => "dance with you" ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; 3. Structs and Collections ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Structs (defstruct dog name breed age) (defparameter *rover* (make-dog :name "rover" :breed "collie" :age 5)) *rover* ; => #S(DOG :NAME "rover" :BREED "collie" :AGE 5) (dog-p *rover*) ; => true #| -p signifies "predicate". It's used to check if *rover* is an instance of dog. |# (dog-name *rover*) ; => "rover" ;; Dog-p, make-dog, and dog-name are all created by defstruct! ;;; Pairs ;; `cons' constructs pairs, `car' and `cdr' extract the first ;; and second elements (cons 'SUBJECT 'VERB) ; => '(SUBJECT . VERB) (car (cons 'SUBJECT 'VERB)) ; => SUBJECT (cdr (cons 'SUBJECT 'VERB)) ; => VERB ;;; Lists ;; Lists are linked-list data structures, made of `cons' pairs and end ;; with a `nil' (or '()) to mark the end of the list (cons 1 (cons 2 (cons 3 nil))) ; => '(1 2 3) ;; `list' is a convenience variadic constructor for lists (list 1 2 3) ; => '(1 2 3) ;; and a quote can also be used for a literal list value '(1 2 3) ; => '(1 2 3) ;; Can still use `cons' to add an item to the beginning of a list (cons 4 '(1 2 3)) ; => '(4 1 2 3) ;; Use `append' to - surprisingly - append lists together (append '(1 2) '(3 4)) ; => '(1 2 3 4) ;; Or use concatenate - (concatenate 'list '(1 2) '(3 4)) ;; Lists are a very central type, so there is a wide variety of functionality for ;; them, a few examples: (mapcar #'1+ '(1 2 3)) ; => '(2 3 4) (mapcar #'+ '(1 2 3) '(10 20 30)) ; => '(11 22 33) (remove-if-not #'evenp '(1 2 3 4)) ; => '(2 4) (every #'evenp '(1 2 3 4)) ; => nil (some #'oddp '(1 2 3 4)) ; => T (butlast '(subject verb object)) ; => (SUBJECT VERB) ;;; Vectors ;; Vector's literals are fixed-length arrays #(1 2 3) ; => #(1 2 3) ;; Use concatenate to add vectors together (concatenate 'vector #(1 2 3) #(4 5 6)) ; => #(1 2 3 4 5 6) ;;; Arrays ;; Both vectors and strings are special-cases of arrays. ;; 2D arrays (make-array (list 2 2)) ;; (make-array '(2 2)) works as well. ; => #2A((0 0) (0 0)) (make-array (list 2 2 2)) ; => #3A(((0 0) (0 0)) ((0 0) (0 0))) ;; Caution- the default initial values are ;; implementation-defined. Here's how to define them: (make-array '(2) :initial-element 'unset) ; => #(UNSET UNSET) ;; And, to access the element at 1,1,1 - (aref (make-array (list 2 2 2)) 1 1 1) ; => 0 ;;; Adjustable vectors ;; Adjustable vectors have the same printed representation ;; as fixed-length vector's literals. (defparameter *adjvec* (make-array '(3) :initial-contents '(1 2 3) :adjustable t :fill-pointer t)) *adjvec* ; => #(1 2 3) ;; Adding new element: (vector-push-extend 4 *adjvec*) ; => 3 *adjvec* ; => #(1 2 3 4) ;;; Naively, sets are just lists: (set-difference '(1 2 3 4) '(4 5 6 7)) ; => (3 2 1) (intersection '(1 2 3 4) '(4 5 6 7)) ; => 4 (union '(1 2 3 4) '(4 5 6 7)) ; => (3 2 1 4 5 6 7) (adjoin 4 '(1 2 3 4)) ; => (1 2 3 4) ;; But you'll want to use a better data structure than a linked list ;; for performant work! ;;; Dictionaries are implemented as hash tables. ;; Create a hash table (defparameter *m* (make-hash-table)) ;; set a value (setf (gethash 'a *m*) 1) ;; Retrieve a value (gethash 'a *m*) ; => 1, t ;; Detail - Common Lisp has multiple return values possible. gethash ;; returns t in the second value if anything was found, and nil if ;; not. ;; Retrieving a non-present value returns nil (gethash 'd *m*) ;=> nil, nil ;; You can provide a default value for missing keys (gethash 'd *m* :not-found) ; => :NOT-FOUND ;; Let's handle the multiple return values here in code. (multiple-value-bind (a b) (gethash 'd *m*) (list a b)) ; => (NIL NIL) (multiple-value-bind (a b) (gethash 'a *m*) (list a b)) ; => (1 T) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; 3. Functions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Use `lambda' to create anonymous functions. ;; A function always returns the value of its last expression. ;; The exact printable representation of a function will vary... (lambda () "Hello World") ; => # ;; Use funcall to call lambda functions (funcall (lambda () "Hello World")) ; => "Hello World" ;; Or Apply (apply (lambda () "Hello World") nil) ; => "Hello World" ;; De-anonymize the function (defun hello-world () "Hello World") (hello-world) ; => "Hello World" ;; The () in the above is the list of arguments for the function (defun hello (name) (format nil "Hello, ~a" name)) (hello "Steve") ; => "Hello, Steve" ;; Functions can have optional arguments; they default to nil (defun hello (name &optional from) (if from (format t "Hello, ~a, from ~a" name from) (format t "Hello, ~a" name))) (hello "Jim" "Alpacas") ;; => Hello, Jim, from Alpacas ;; And the defaults can be set... (defun hello (name &optional (from "The world")) (format t "Hello, ~a, from ~a" name from)) (hello "Steve") ; => Hello, Steve, from The world (hello "Steve" "the alpacas") ; => Hello, Steve, from the alpacas ;; And of course, keywords are allowed as well... usually more ;; flexible than &optional. (defun generalized-greeter (name &key (from "the world") (honorific "Mx")) (format t "Hello, ~a ~a, from ~a" honorific name from)) (generalized-greeter "Jim") ; => Hello, Mx Jim, from the world (generalized-greeter "Jim" :from "the alpacas you met last summer" :honorific "Mr") ; => Hello, Mr Jim, from the alpacas you met last summer ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; 4. Equality ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Common Lisp has a sophisticated equality system. A couple are covered here. ;; for numbers use `=' (= 3 3.0) ; => t (= 2 1) ; => nil ;; for object identity (approximately) use `eql` (eql 3 3) ; => t (eql 3 3.0) ; => nil (eql (list 3) (list 3)) ; => nil ;; for lists, strings, and bit-vectors use `equal' (equal (list 'a 'b) (list 'a 'b)) ; => t (equal (list 'a 'b) (list 'b 'a)) ; => nil ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; 5. Control Flow ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Conditionals (if t ; test expression "this is true" ; then expression "this is false") ; else expression ; => "this is true" ;; In conditionals, all non-nil values are treated as true (member 'Groucho '(Harpo Groucho Zeppo)) ; => '(GROUCHO ZEPPO) (if (member 'Groucho '(Harpo Groucho Zeppo)) 'yep 'nope) ; => 'YEP ;; `cond' chains a series of tests to select a result (cond ((> 2 2) (error "wrong!")) ((< 2 2) (error "wrong again!")) (t 'ok)) ; => 'OK ;; Typecase switches on the type of the value (typecase 1 (string :string) (integer :int)) ; => :int ;;; Iteration ;; Of course recursion is supported: (defun walker (n) (if (zerop n) :walked (walker (- n 1)))) (walker 5) ; => :walked ;; Most of the time, we use DOLIST or LOOP (dolist (i '(1 2 3 4)) (format t "~a" i)) ; => 1234 (loop for i from 0 below 10 collect i) ; => (0 1 2 3 4 5 6 7 8 9) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; 6. Mutation ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Use `setf' to assign a new value to an existing variable. This was ;; demonstrated earlier in the hash table example. (let ((variable 10)) (setf variable 2)) ; => 2 ;; Good Lisp style is to minimize destructive functions and to avoid ;; mutation when reasonable. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; 7. Classes and Objects ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; No more Animal classes, let's have Human-Powered Mechanical ;; Conveyances. (defclass human-powered-conveyance () ((velocity :accessor velocity :initarg :velocity) (average-efficiency :accessor average-efficiency :initarg :average-efficiency)) (:documentation "A human powered conveyance")) ;; defclass, followed by name, followed by the superclass list, ;; followed by slot list, followed by optional qualities such as ;; :documentation. ;; When no superclass list is set, the empty list defaults to the ;; standard-object class. This *can* be changed, but not until you ;; know what you're doing. Look up the Art of the Metaobject Protocol ;; for more information. (defclass bicycle (human-powered-conveyance) ((wheel-size :accessor wheel-size :initarg :wheel-size :documentation "Diameter of the wheel.") (height :accessor height :initarg :height))) (defclass recumbent (bicycle) ((chain-type :accessor chain-type :initarg :chain-type))) (defclass unicycle (human-powered-conveyance) nil) (defclass canoe (human-powered-conveyance) ((number-of-rowers :accessor number-of-rowers :initarg :number-of-rowers))) ;; Calling DESCRIBE on the human-powered-conveyance class in the REPL gives: (describe 'human-powered-conveyance) ; COMMON-LISP-USER::HUMAN-POWERED-CONVEYANCE ; [symbol] ; ; HUMAN-POWERED-CONVEYANCE names the standard-class #: ; Documentation: ; A human powered conveyance ; Direct superclasses: STANDARD-OBJECT ; Direct subclasses: UNICYCLE, BICYCLE, CANOE ; Not yet finalized. ; Direct slots: ; VELOCITY ; Readers: VELOCITY ; Writers: (SETF VELOCITY) ; AVERAGE-EFFICIENCY ; Readers: AVERAGE-EFFICIENCY ; Writers: (SETF AVERAGE-EFFICIENCY) ;; Note the reflective behavior available to you! Common Lisp is ;; designed to be an interactive system ;; To define a method, let's find out what our circumference of the ;; bike wheel turns out to be using the equation: C = d * pi (defmethod circumference ((object bicycle)) (* pi (wheel-size object))) ;; pi is defined in Lisp already for us! ;; Let's suppose we find out that the efficiency value of the number ;; of rowers in a canoe is roughly logarithmic. This should probably be set ;; in the constructor/initializer. ;; Here's how to initialize your instance after Common Lisp gets done ;; constructing it: (defmethod initialize-instance :after ((object canoe) &rest args) (setf (average-efficiency object) (log (1+ (number-of-rowers object))))) ;; Then to construct an instance and check the average efficiency... (average-efficiency (make-instance 'canoe :number-of-rowers 15)) ; => 2.7725887 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; 8. Macros ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Macros let you extend the syntax of the language ;; Common Lisp doesn't come with a WHILE loop- let's add one. ;; If we obey our assembler instincts, we wind up with: (defmacro while (condition &body body) "While `condition` is true, `body` is executed. `condition` is tested prior to each execution of `body`" (let ((block-name (gensym)) (done (gensym))) `(tagbody ,block-name (unless ,condition (go ,done)) (progn ,@body) (go ,block-name) ,done))) ;; Let's look at the high-level version of this: (defmacro while (condition &body body) "While `condition` is true, `body` is executed. `condition` is tested prior to each execution of `body`" `(loop while ,condition do (progn ,@body))) ;; However, with a modern compiler, this is not required; the LOOP ;; form compiles equally well and is easier to read. ;; Note that ``` is used, as well as `,` and `@`. ``` is a quote-type operator ;; known as quasiquote; it allows the use of `,` . `,` allows "unquoting" ;; variables. @ interpolates lists. ;; Gensym creates a unique symbol guaranteed to not exist elsewhere in ;; the system. This is because macros are expanded at compile time and ;; variables declared in the macro can collide with variables used in ;; regular code. ;; See Practical Common Lisp for more information on macros. ``` ## Further Reading * [Keep moving on to the Practical Common Lisp book.](http://www.gigamonkeys.com/book/) * [A Gentle Introduction to...](https://www.cs.cmu.edu/~dst/LispBook/book.pdf) ## Extra Info * [CLiki](http://www.cliki.net/) * [common-lisp.net](https://common-lisp.net/) * [Awesome Common Lisp](https://github.com/CodyReichert/awesome-cl) ## Credits. Lots of thanks to the Scheme people for rolling up a great starting point which could be easily moved to Common Lisp. - [Paul Khuong](https://github.com/pkhuong) for some great reviewing. --- category: tool tool: compojure contributors: - ["Adam Bard", "http://adambard.com/"] filename: learncompojure.clj --- ## Getting Started with Compojure Compojure is a DSL for *quickly* creating *performant* web applications in Clojure with minimal effort: ```clojure (ns myapp.core (:require [compojure.core :refer :all] [org.httpkit.server :refer [run-server]])) ; httpkit is a server (defroutes myapp (GET "/" [] "Hello World")) (defn -main [] (run-server myapp {:port 5000})) ``` **Step 1:** Create a project with [Leiningen](http://leiningen.org/): ``` lein new myapp ``` **Step 2:** Put the above code in `src/myapp/core.clj` **Step 3:** Add some dependencies to `project.clj`: ``` [compojure "1.1.8"] [http-kit "2.1.16"] ``` **Step 4:** Run: ``` lein run -m myapp.core ``` View at: Compojure apps will run on any ring-compatible server, but we recommend [http-kit](http://http-kit.org/) for its performance and [massive concurrency](http://http-kit.org/600k-concurrent-connection-http-kit.html). ### Routes In compojure, each route is an HTTP method paired with a URL-matching pattern, an argument list, and a body. ```clojure (defroutes myapp (GET "/" [] "Show something") (POST "/" [] "Create something") (PUT "/" [] "Replace something") (PATCH "/" [] "Modify Something") (DELETE "/" [] "Annihilate something") (OPTIONS "/" [] "Appease something") (HEAD "/" [] "Preview something")) ``` Compojure route definitions are just functions which [accept request maps and return response maps](https://github.com/mmcgrana/ring/blob/master/SPEC): ```clojure (myapp {:uri "/" :request-method :post}) ; => {:status 200 ; :headers {"Content-Type" "text/html; charset=utf-8} ; :body "Create Something"} ``` The body may be a function, which must accept the request as a parameter: ```clojure (defroutes myapp (GET "/" [] (fn [req] "Do something with req"))) ``` Or, you can just use the request directly: ```clojure (defroutes myapp (GET "/" req "Do something with req")) ``` Route patterns may include named parameters: ```clojure (defroutes myapp (GET "/hello/:name" [name] (str "Hello " name))) ``` You can adjust what each parameter matches by supplying a regex: ```clojure (defroutes myapp (GET ["/file/:name.:ext" :name #".*", :ext #".*"] [name ext] (str "File: " name ext))) ``` ### Middleware Clojure uses [Ring](https://github.com/ring-clojure/ring) for routing. Handlers are just functions that accept a request map and return a response map (Compojure will turn strings into 200 responses for you). You can easily write middleware that wraps all or part of your application to modify requests or responses: ```clojure (defroutes myapp (GET "/" req (str "Hello World v" (:app-version req)))) (defn wrap-version [handler] (fn [request] (handler (assoc request :app-version "1.0.1")))) (defn -main [] (run-server (wrap-version myapp) {:port 5000})) ``` [Ring-Defaults](https://github.com/ring-clojure/ring-defaults) provides some handy middlewares for sites and apis, so add it to your dependencies: ``` [ring/ring-defaults "0.1.1"] ``` Then, you can import it in your ns: ``` (ns myapp.core (:require [compojure.core :refer :all] [ring.middleware.defaults :refer :all] [org.httpkit.server :refer [run-server]])) ``` And use `wrap-defaults` to add the `site-defaults` middleware to your app: ``` (defn -main [] (run-server (wrap-defaults myapp site-defaults) {:port 5000})) ``` Now, your handlers may utilize query parameters: ```clojure (defroutes myapp (GET "/posts" req (let [title (get (:params req) :title) author (get (:params req) :author)] (str "Title: " title ", Author: " author)))) ``` Or, for POST and PUT requests, form parameters as well ```clojure (defroutes myapp (POST "/posts" req (let [title (get (:params req) :title) author (get (:params req) :author)] (str "Title: " title ", Author: " author)))) ``` ### Return values The return value of a route block determines the response body passed on to the HTTP client, or at least the next middleware in the ring stack. Most commonly, this is a string, as in the above examples. But, you may also return a [response map](https://github.com/mmcgrana/ring/blob/master/SPEC): ```clojure (defroutes myapp (GET "/" [] {:status 200 :body "Hello World"}) (GET "/is-403" [] {:status 403 :body ""}) (GET "/is-json" [] {:status 200 :headers {"Content-Type" "application/json"} :body "{}"})) ``` ### Static Files To serve up static files, use `compojure.route.resources`. Resources will be served from your project's `resources/` folder. ```clojure (require '[compojure.route :as route]) (defroutes myapp (GET "/") (route/resources "/")) ; Serve static resources at the root path (myapp {:uri "/js/script.js" :request-method :get}) ; => Contents of resources/public/js/script.js ``` ### Views / Templates To use templating with Compojure, you'll need a template library. Here are a few: #### [Stencil](https://github.com/davidsantiago/stencil) [Stencil](https://github.com/davidsantiago/stencil) is a [Mustache](http://mustache.github.com/) template library: ```clojure (require '[stencil.core :refer [render-string]]) (defroutes myapp (GET "/hello/:name" [name] (render-string "Hello {{name}}" {:name name}))) ``` You can easily read in templates from your resources directory. Here's a helper function ```clojure (require 'clojure.java.io) (defn read-template [filename] (slurp (clojure.java.io/resource filename))) (defroutes myapp (GET "/hello/:name" [name] (render-string (read-template "templates/hello.html") {:name name}))) ``` #### [Selmer](https://github.com/yogthos/Selmer) [Selmer](https://github.com/yogthos/Selmer) is a Django and Jinja2-inspired templating language: ```clojure (require '[selmer.parser :refer [render-file]]) (defroutes myapp (GET "/hello/:name" [name] (render-file "templates/hello.html" {:name name}))) ``` #### [Hiccup](https://github.com/weavejester/hiccup) [Hiccup](https://github.com/weavejester/hiccup) is a library for representing HTML as Clojure code ```clojure (require '[hiccup.core :as hiccup]) (defroutes myapp (GET "/hello/:name" [name] (hiccup/html [:html [:body [:h1 {:class "title"} (str "Hello " name)]]]))) ``` #### [Markdown](https://github.com/yogthos/markdown-clj) [Markdown-clj](https://github.com/yogthos/markdown-clj) is a Markdown implementation. ```clojure (require '[markdown.core :refer [md-to-html-string]]) (defroutes myapp (GET "/hello/:name" [name] (md-to-html-string "## Hello, world"))) ``` Further reading: * [Official Compojure Documentation](https://github.com/weavejester/compojure/wiki) * [Clojure for the Brave and True](http://www.braveclojure.com/) # Contributing All contributions are welcome, from the tiniest typo to a brand new article. Translations in all languages are welcome (or, for that matter, original articles in any language). Send a pull request or open an issue any time of day or night. **Please prepend the tag `[language/lang-code]` to your issues and pull requests.** For example, `[python/en]` for English Python. This will help everyone pick out things they care about. We're happy for any contribution in any form, but if you're making more than one major change (i.e. translations for two different languages) it would be super cool of you to make a separate pull request for each one so that someone can review them more effectively and/or individually. ## Style Guidelines - **Keep lines of under 80 chars** + Try to keep **line length in code blocks to 80 characters or fewer**. + Otherwise, the text will overflow and look odd. - **Prefer example to exposition** + Try to use as few words as possible. + Code examples are preferred over exposition in all cases. - **Eschew surplusage** + We welcome newcomers, but the target audience for this site is programmers with some experience. + Try to avoid explaining basic concepts except for those specific to the language in question. + Keep articles succinct and scannable. We all know how to use Google here. - **Use UTF-8** + For translations (or EN articles with non-ASCII characters) please make sure your file is UTF-8 encoded. + Try to leave out the byte-order-mark at the start of the file. (`:set nobomb` in Vim) + You can check if the file contains a BOM on Linux/Unix systems by running `file language.html.markdown` You will see this if it uses a BOM: `UTF-8 Unicode (with BOM) text`. ### Header configuration The actual site uses Middleman to generate HTML files from these Markdown ones. Middleman, or at least the custom scripts underpinning the site, requires that some key information be defined in the header. The following fields are necessary for English articles about programming languages: - **language** The *programming language* in question - **contributors** A list of [author, URL] lists to credit Other fields: - **filename**: The filename for this article's code. It will be fetched, mashed together, and made downloadable. + For non-English articles, *filename* should have a language-specific suffix. - **lang**: For translations, the human language this article is in. For categorization, mostly. Here's an example header for an Esperanto translation of Ruby: ```yaml --- language: ruby filename: learnruby-epo.ruby contributors: - ["Doktor Esperanto", "http://example.com/"] - ["Someone else", "http://someoneelseswebsite.com/"] lang: ep-ep --- ``` --- language: crystal filename: learncrystal.cr contributors: - ["Vitalii Elenhaupt", "http://veelenga.com"] - ["Arnaud Fernandés", "https://github.com/TechMagister/"] --- ```crystal # This is a comment # Everything is an object nil.class #=> Nil 100.class #=> Int32 true.class #=> Bool # Falsey values are: nil, false and null pointers !nil #=> true : Bool !false #=> true : Bool !0 #=> false : Bool # Integers 1.class #=> Int32 # Four signed integer types 1_i8.class #=> Int8 1_i16.class #=> Int16 1_i32.class #=> Int32 1_i64.class #=> Int64 # Four unsigned integer types 1_u8.class #=> UInt8 1_u16.class #=> UInt16 1_u32.class #=> UInt32 1_u64.class #=> UInt64 2147483648.class #=> Int64 9223372036854775808.class #=> UInt64 # Binary numbers 0b1101 #=> 13 : Int32 # Octal numbers 0o123 #=> 83 : Int32 # Hexadecimal numbers 0xFE012D #=> 16646445 : Int32 0xfe012d #=> 16646445 : Int32 # Floats 1.0.class #=> Float64 # There are two floating point types 1.0_f32.class #=> Float32 1_f32.class #=> Float32 1e10.class #=> Float64 1.5e10.class #=> Float64 1.5e-7.class #=> Float64 # Chars 'a'.class #=> Char # Octal codepoint '\101' #=> 'A' : Char # Unicode codepoint '\u0041' #=> 'A' : Char # Strings "s".class #=> String # Strings are immutable s = "hello, " #=> "hello, " : String s.object_id #=> 134667712 : UInt64 s += "Crystal" #=> "hello, Crystal" : String s.object_id #=> 142528472 : UInt64 # Supports interpolation "sum = #{1 + 2}" #=> "sum = 3" : String # Multiline string "This is multiline string" # String with double quotes %(hello "world") #=> "hello \"world\"" # Symbols # Immutable, reusable constants represented internally as Int32 integer value. # They're often used instead of strings to efficiently convey specific, # meaningful values :symbol.class #=> Symbol sentence = :question? # :"question?" : Symbol sentence == :question? #=> true : Bool sentence == :exclamation! #=> false : Bool sentence == "question?" #=> false : Bool # Arrays [1, 2, 3].class #=> Array(Int32) [1, "hello", 'x'].class #=> Array(Int32 | String | Char) # Empty arrays should specify a type [] # Syntax error: for empty arrays use '[] of ElementType' [] of Int32 #=> [] : Array(Int32) Array(Int32).new #=> [] : Array(Int32) # Arrays can be indexed array = [1, 2, 3, 4, 5] #=> [1, 2, 3, 4, 5] : Array(Int32) array[0] #=> 1 : Int32 array[10] # raises IndexError array[-6] # raises IndexError array[10]? #=> nil : (Int32 | Nil) array[-6]? #=> nil : (Int32 | Nil) # From the end array[-1] #=> 5 # With a start index and size array[2, 3] #=> [3, 4, 5] # Or with range array[1..3] #=> [2, 3, 4] # Add to an array array << 6 #=> [1, 2, 3, 4, 5, 6] # Remove from the end of the array array.pop #=> 6 array #=> [1, 2, 3, 4, 5] # Remove from the beginning of the array array.shift #=> 1 array #=> [2, 3, 4, 5] # Check if an item exists in an array array.includes? 3 #=> true # Special syntax for an array of string and an array of symbols %w(one two three) #=> ["one", "two", "three"] : Array(String) %i(one two three) #=> [:one, :two, :three] : Array(Symbol) # There is a special array syntax with other types too, as long as # they define a .new and a #<< method set = Set{1, 2, 3} #=> [1, 2, 3] set.class #=> Set(Int32) # The above is equivalent to set = Set(typeof(1, 2, 3)).new set << 1 set << 2 set << 3 # Hashes {1 => 2, 3 => 4}.class #=> Hash(Int32, Int32) {1 => 2, 'a' => 3}.class #=> Hash(Int32 | Char, Int32) # Empty hashes should specify a type {} # Syntax error {} of Int32 => Int32 # {} Hash(Int32, Int32).new # {} # Hashes can be quickly looked up by key hash = {"color" => "green", "number" => 5} hash["color"] #=> "green" hash["no_such_key"] #=> Missing hash key: "no_such_key" (KeyError) hash["no_such_key"]? #=> nil # Check existence of keys hash hash.has_key? "color" #=> true # Special notation for symbol and string keys {key1: 'a', key2: 'b'} # {:key1 => 'a', :key2 => 'b'} {"key1": 'a', "key2": 'b'} # {"key1" => 'a', "key2" => 'b'} # Special hash literal syntax with other types too, as long as # they define a .new and a #[]= methods class MyType def []=(key, value) puts "do stuff" end end MyType{"foo" => "bar"} # The above is equivalent to tmp = MyType.new tmp["foo"] = "bar" tmp # Ranges 1..10 #=> Range(Int32, Int32) Range.new(1, 10).class #=> Range(Int32, Int32) # Can be inclusive or exclusive (3..5).to_a #=> [3, 4, 5] (3...5).to_a #=> [3, 4] # Check whether range includes the given value or not (1..8).includes? 2 #=> true # Tuples are a fixed-size, immutable, stack-allocated sequence of values of # possibly different types. {1, "hello", 'x'}.class #=> Tuple(Int32, String, Char) # Access tuple's value by its index tuple = {:key1, :key2} tuple[1] #=> :key2 tuple[2] #=> syntax error : Index out of bound # Can be expanded into multiple variables a, b, c = {:a, 'b', "c"} a #=> :a b #=> 'b' c #=> "c" # Procs represent a function pointer with an optional context (the closure data) # It is typically created with a proc litteral proc = ->(x : Int32) { x.to_s } proc.class # Proc(Int32, String) # Or using the new method Proc(Int32, String).new { |x| x.to_s } # Invoke proc with call method proc.call 10 #=> "10" # Control statements if true "if statement" elsif false "else-if, optional" else "else, also optional" end puts "if as a suffix" if true # If as an expression a = if 2 > 1 3 else 4 end a #=> 3 # Ternary if a = 1 > 2 ? 3 : 4 #=> 4 # Case statement cmd = "move" action = case cmd when "create" "Creating..." when "copy" "Copying..." when "move" "Moving..." when "delete" "Deleting..." end action #=> "Moving..." # Loops index = 0 while index <= 3 puts "Index: #{index}" index += 1 end # Index: 0 # Index: 1 # Index: 2 # Index: 3 index = 0 until index > 3 puts "Index: #{index}" index += 1 end # Index: 0 # Index: 1 # Index: 2 # Index: 3 # But the preferable way is to use each (1..3).each do |index| puts "Index: #{index}" end # Index: 0 # Index: 1 # Index: 2 # Index: 3 # Variable's type depends on the type of the expression # in control statements if a < 3 a = "hello" else a = true end typeof a #=> (Bool | String) if a && b # here both a and b are guaranteed not to be Nil end if a.is_a? String a.class #=> String end # Functions def double(x) x * 2 end # Functions (and all blocks) implicitly return the value of the last statement double(2) #=> 4 # Parentheses are optional where the call is unambiguous double 3 #=> 6 double double 3 #=> 12 def sum(x, y) x + y end # Method arguments are separated by a comma sum 3, 4 #=> 7 sum sum(3, 4), 5 #=> 12 # yield # All methods have an implicit, optional block parameter # it can be called with the 'yield' keyword def surround puts '{' yield puts '}' end surround { puts "hello world" } # { # hello world # } # You can pass a block to a function # "&" marks a reference to a passed block def guests(&block) block.call "some_argument" end # You can pass a list of arguments, which will be converted into an array # That's what splat operator ("*") is for def guests(*array) array.each { |guest| puts guest } end # If a method returns an array, you can use destructuring assignment def foods ["pancake", "sandwich", "quesadilla"] end breakfast, lunch, dinner = foods breakfast #=> "pancake" dinner #=> "quesadilla" # By convention, all methods that return booleans end with a question mark 5.even? # false 5.odd? # true # And if a method ends with an exclamation mark, it does something destructive # like mutate the receiver. Some methods have a ! version to make a change, and # a non-! version to just return a new changed version company_name = "Dunder Mifflin" company_name.gsub "Dunder", "Donald" #=> "Donald Mifflin" company_name #=> "Dunder Mifflin" company_name.gsub! "Dunder", "Donald" company_name #=> "Donald Mifflin" # Define a class with the class keyword class Human # A class variable. It is shared by all instances of this class. @@species = "H. sapiens" # type of name is String @name : String # Basic initializer # Assign the argument to the "name" instance variable for the instance # If no age given, we will fall back to the default in the arguments list. def initialize(@name, @age = 0) end # Basic setter method def name=(name) @name = name end # Basic getter method def name @name end # The above functionality can be encapsulated using the attr_accessor method as follows property :name # Getter/setter methods can also be created individually like this getter :name setter :name # A class method uses self to distinguish from instance methods. # It can only be called on the class, not an instance. def self.say(msg) puts msg end def species @@species end end # Instantiate a class jim = Human.new("Jim Halpert") dwight = Human.new("Dwight K. Schrute") # Let's call a couple of methods jim.species #=> "H. sapiens" jim.name #=> "Jim Halpert" jim.name = "Jim Halpert II" #=> "Jim Halpert II" jim.name #=> "Jim Halpert II" dwight.species #=> "H. sapiens" dwight.name #=> "Dwight K. Schrute" # Call the class method Human.say("Hi") #=> print Hi and returns nil # Variables that start with @ have instance scope class TestClass @var = "I'm an instance var" end # Variables that start with @@ have class scope class TestClass @@var = "I'm a class var" end # Variables that start with a capital letter are constants Var = "I'm a constant" Var = "can't be updated" # Already initialized constant Var # Class is also an object in crystal. So class can have instance variables. # Class variable is shared among the class and all of its descendants. # base class class Human @@foo = 0 def self.foo @@foo end def self.foo=(value) @@foo = value end end # derived class class Worker < Human end Human.foo #=> 0 Worker.foo #=> 0 Human.foo = 2 #=> 2 Worker.foo #=> 0 Worker.foo = 3 #=> 3 Human.foo #=> 2 Worker.foo #=> 3 module ModuleExample def foo "foo" end end # Including modules binds their methods to the class instances # Extending modules binds their methods to the class itself class Person include ModuleExample end class Book extend ModuleExample end Person.foo # => undefined method 'foo' for Person:Class Person.new.foo # => 'foo' Book.foo # => 'foo' Book.new.foo # => undefined method 'foo' for Book # Exception handling # Define new exception class MyException < Exception end # Define another exception class MyAnotherException < Exception; end ex = begin raise MyException.new rescue ex1 : IndexError "ex1" rescue ex2 : MyException | MyAnotherException "ex2" rescue ex3 : Exception "ex3" rescue ex4 # catch any kind of exception "ex4" end ex #=> "ex2" ``` ## Additional resources - [Official Documentation](http://crystal-lang.org/) --- language: brainfuck contributors: - ["Prajit Ramachandran", "http://prajitr.github.io/"] - ["Mathias Bynens", "http://mathiasbynens.be/"] translators: - ["Vojta Svoboda", "https://github.com/vojtasvoboda/"] filename: learnbrainfuck-cz.bf lang: cs-cz --- Brainfuck (psaný bez kapitálek s vyjímkou začátku věty) je extrémně minimální Turingovsky kompletní (ekvivalentní) programovací jazyk a má pouze 8 příkazů. Můžete si ho vyzkoušet přímo v prohlížeči s [brainfuck-visualizer](http://fatiherikli.github.io/brainfuck-visualizer/). ``` Jakýkoliv znak mimo "><+-.,[]" (bez uvozovek) je ignorován. Brainfuck je reprezentován jako pole, které má 30.000 buněk s počátkem v nule a datovým ukazatelem na aktuální buňce. Můžeme využít těchto osm příkazů: + : Přičte k aktuální buňce jedničku. - : Odečte od aktuální buňky jedničku. > : Posune datový ukazatel na další buňku, která je napravo. < : Posune datový ukazatel na předchozí buňku, která je nalevo. . : Vytiskne ASCII hodnotu aktuální buňky (například 65 = 'A'). , : Načte jeden znak do aktuální buňky. [ : Pokud je hodnota aktuální buňky nulová, přeskočí na buňku odpovídající ] . Jinak skočí na další instrukci. ] : Pokud je hodnota aktuální buňky nulova, přeskočí na další instrukci. Jinak skočí zpět na instrukci odpovídající [ . [ a ] tak tvoří 'while' smyčku a tyto symboly musí tak být v páru. Pojďme se mrknout na některé brainfuck programy. ++++++ [ > ++++++++++ < - ] > +++++ . Tento program vypíše písmeno 'A' (v ASCII je to číslo 65). Nejdříve navýší buňku #1 na hodnotu 6. Buňka #1 bude použita pro smyčku. Potom program vstoupí do smyčky ([) a sníží hodnotu buňky #1 o jedničku. Ve smyčce zvýší hodnotu buňky #2 desetkrát, vrátí ze zpět na buňku #1 a sníží její hodnotu o jedničku. Toto se stane šestkrát (je potřeba šestkrát snížit hodnotu buňky #1, aby byla nulová a program přeskočil na konec cyklu označený znakem ]. Na konci smyčky, kdy jsme na buňce #1 (která má hodnotu 0), tak má buňka #2 hodnotu 60. Přesuneme se na buňku #2 a pětkrát zvýšíme její hodnotu o jedničku na hodnotu 65. Na konci vypíšeme hodnotu buňky #2 - 65, což je v ASCII znak 'A' na terminálu. , [ > + < - ] > . Tento program přečte znak z uživatelského vstupu a zkopíruje ho do buňky #1. Poté začne smyčka - přesun na buňku #2, zvýšení hodnoty buňky #2 o jedničku, přesun zpět na buňku #1 a snížení její hodnoty o jedničku. Takto smyčka pokračuje do té doby, než je buňka #1 nulová a buňka #2 nabyde původní hodnotu buňky #1. Protože jsme na buňce #1, přesuneme se na buňku #2 a vytiskneme její hodnotu v ASCII. Je dobré vědět, že mezery jsou v programu uvedené pouze z důvodu čitelnosti. Program je možné klidně zapsat i takto: ,[>+<-]>. Nyní se podívejte na tento program a zkuste zjistit co dělá: ,>,< [ > [ >+ >+ << -] >> [- << + >>] <<< -] >> Tento program vezme dvě čísla ze vstupu a vynásobí je. Program nejdříve načte dvě vstupní hodnoty. Poté začíná smyčka řízená hodnotou v buňce #1 - přesun na buňku #2 a start druhé vnořené smyčky, která je řízená hodnotou v buňce #2 a zvyšuje hodnotu v buňce #3. Nicméně je zde problém kdy na konci vnitřní smyčky je v buňce #2 nula a smyčka by tak znovu napokračovala. Vyřešíme to tak, že zvyšujeme o jedničku i buňku #4 a její hodnotu poté překopírujeme do buňky #2. Na konci programu je v buňce #3 výsledek. ``` A to je brainbuck. Zase tak složitý není, co? Zkuste si nyní napsat nějaký vlastní brainfuck program a nebo interpretr v jiném jazyce, což není zase tak složité, ale pokud jste opravdový masochista, zkuste si naprogramovat interpretr jazyka brainfuck v jazyce... brainfuck :) --- language: css contributors: - ["Mohammad Valipour", "https://github.com/mvalipour"] - ["Marco Scannadinari", "https://github.com/marcoms"] - ["Geoffrey Liu", "https://github.com/g-liu"] - ["Connor Shea", "https://github.com/connorshea"] - ["Deepanshu Utkarsh", "https://github.com/duci9y"] translators: - ["Michal Martinek", "https://github.com/MichalMartinek"] lang: cs-cz filename: learncss-cz.css --- V ranných dobách webu se nevyskytovaly žádné vizuální elementy, pouze čistý text, ale s vývojem webových browserů se staly stránky plné grafických prvků běžné. A právě proto vzniklo CSS, aby oddělilo obsah (HTML) od vzhledu webové stránky. Pomocí CSS můžete označit různé elementy na HTML stránce a přiřadit jim různé vzhledové vlastnosti. Tento návod byl napsán pro CSS 2, avšak CSS 3 se stalo velmi oblíbené a v dnešní době už běžné. **POZNÁMKA** Protože CSS produkuje vizuální výsledky, je nutné k jeho naučení všechno zkoušet třeba na [dabbletu](http://dabblet.com/). Tento článek se zaměřuje hlavně na syntaxi a poskytue také pár obecných tipů. ```css /* komentáře jsou ohraničeny lomítkem s hvězdičkou, přesně jako tyto dva řádky, v CSS není nic jako jednořádkový komentář, pouze tenhle zápis */ /* ################ ## SELEKTORY ################ */ /* Selektor se používá pro vybrání elementu na stránce: selektor { vlastnost: hodnota; /* více vlastností... }*/ /* Toto je náš element:
*/ /* Můžeme vybrat tento element třeba podle jeho třídy */ .trida1 { } /* nebo obou tříd! */ .trida1.trida2 { } /* nebo jeho jména */ div { } /* nebo jeho id */ #nejakeID { } /* nebo podle toho, že má atribut! */ [attr] { font-size:smaller; } /* nebo že argument nabývá specifické hodnoty*/ [attr='hodnota'] { font-size:smaller; } /* začíná nějakou hodnotou (CSS 3) */ [attr^='ho'] { font-size:smaller; } /* nebo končí něčím (CSS 3) */ [attr$='ta'] { font-size:smaller; } /* nebo obsahuje nějakou hodnotu, která je v atributu oddělená mezerami */ [otherAttr~='co'] { } [otherAttr~='neco'] { } /* nebo obsahuje hodnotu oddělenou pomlčkou - "-" (U+002D) */ [otherAttr|='cs'] { font-size:smaller; } /* Můžeme spojit různé selektory, abychom získali specifičtější selektor. Pozor, nedávejte mezi ně mezery! */ div.nejaka-trida[attr$='ta'] { } /* Můžeme vybrat element, který je potomek jineho */ div.vnejsi-element > .jmeno-tridy { } /* nebo zanořen ještě hlouběji. Potomci jsou přímo pod vnější třídou, pouze 1 úroveň pod rodičem. Tento selektor bude fungovat na jakékoliv úrovni pod rodičem */ div.rodic .jmeno-tridy { } /* Varování: stejný selektor bez mezery má úplně jiný význam Vzpomínáte si jaký? */ div.rodic.jmeno-tridy { } /* Možná budete chtít vybrat element, který leží přímo vedle */ .jsem-primo-pred + .timto-elementem { } /* nebo kdekoliv na stejné úrovni stromu */ .jsem-kdekoliv-pred ~ .timto-elementem { } /* Existují selektory nazvané pseudo třídy, kterými můžeme vybrat elementy, když jsou v určitém stavu */ /* na příklad, když kurzor najede na element */ selektor:hover { } /* nebo již navštívený odkaz */ selektor:visited { } /* nebo nebyl navštíven */ selektor:link { } /* nebo když je vybrán, např kliknutím do inputu*/ selektor:focus { } /* element, ktery je prvni potomek rodiče */ selektor:first-child {} /* element, který je poslední potomek rodiče */ selektor:last-child {} /* Stejně jako pseudo třídy, umožňují pseudo elementy stylizovat určité části dokumentu */ /* odpovídá virtuálnímu prvnímu potomku */ selektor::before {} /* odpovídá virtuálnímu poslednímu potomku */ selektor::after {} /* Na vhodném místě, může být použitá hvězdička jako žolík, který vybere každý element */ * { } /* všechny elementy */ .rodic * { } /* všechny vnořené elementy */ .rodic > * { } /* všichni potomci */ /* #################### ## VLASTNOSTI #################### */ selektor { /* Jednotky délky můžou být relativní nebo absolutní */ /* Relativní jednotky */ width: 50%; /* počet procent šířky rodičovského elementu */ font-size: 2em; /* násobek puvodní velikosti fontu elementu */ font-size: 2rem; /* nebo kořenového elementu */ font-size: 2vw; /* násobek 1% šířky zařízení (viewport) (CSS 3) */ font-size: 2vh; /* nebo jeho výšky */ font-size: 2vmin; /* násobek 1% výšky nebo šířky, dle toho, co je menší */ font-size: 2vmax; /* nebo větší */ /* Absolutní jednotky */ width: 200px; /* pixely */ font-size: 20pt; /* body */ width: 5cm; /* centimetry */ min-width: 50mm; /* milimetry */ max-width: 5in; /* palce */ /* Barvy */ color: #F6E; /* krátký hexadecimální formát */ color: #FF66EE; /* dlouhý hexadecimální formát */ color: tomato; /* pojmenovaná barva */ color: rgb(255, 255, 255); /* hodnoty rgb */ color: rgb(10%, 20%, 50%); /* procenta rgb */ color: rgba(255, 0, 0, 0.3); /* hodnoty rgba (CSS 3) Poznámka: 0 < a < 1 */ color: transparent; /* ekvivalentní jako nastavení alfy 0 */ color: hsl(0, 100%, 50%); /* procenta hsl (CSS 3) */ color: hsla(0, 100%, 50%, 0.3); /* procenta hsl s alfou */ /* Obrázky jako pozadí elementu */ background-image: url(/cesta/k/obrazku.jpg); /* uvozovky jsou dobrovolné */ /* Fonty */ font-family: Arial; /* když název fontu obsahuje mezeru, tak musí být v uvozovkách */ font-family: "Courier New"; /* když se první nenaleze, použije se další atd. */ font-family: "Courier New", Trebuchet, Arial, sans-serif; } ``` ## Použití Uložte CSS soubor s příponou `.css`. ```xml
``` ## Priorita nebo kaskáda Element může být vybrán více selektory a jeho vlastnosti můžou být nastaveny více než jednou. V těchto případech, má jedno zadání vlastnosti prioritu před druhým. Obecně platí, že více specifické selektory mají přednost před těmi méně specifickými. Tento proces se nazývá kaskáda, proto i název kaskádové styly(Cascading Style Sheets). Máme následující CSS ```css /* A */ p.trida1[attr='hodnota'] /* B */ p.trida1 { } /* C */ p.trida2 { } /* D */ p { } /* E */ p { vlastnost: hodnota !important; } ``` a tento element ```xml

``` Priorita stylu je následující. Pamatujte, priorita pro každou **vlastnost**, ne pro celý blok. * `E` má nejvyšší prioritu kvůli slůvku `!important`. Je doporučováno se úplně vyhnout jeho použití. * `F` je další, kvůli stylu zadanému přimo do elementu * `A` je další, protože je více specifické, než cokoliv dalšího. Má 3 selektory: jméno elementu `p`, jeho třídu `trida1`, atribut `attr='hodnota'`. * `C` je další, i když je stejně specifický jako `B`, protože je uveden až po něm. * `B` je další * `D` je poslední ## Kompatibilita Většina z možností v CSS 2 (a spousta v CSS 3) je dostupná napříč všemi browsery a zařízeními. Ale pořád je dobrá praxe, zkontrolovat dostupnost, před užitím nové vlastnosti/fičury. ## Zdroje * Přehled dostupnosti [CanIUse](http://caniuse.com). * CSS hřiště [Dabblet](http://dabblet.com/). * [Mozilla Developer Network - CSS dokumentace](https://developer.mozilla.org/en-US/docs/Web/CSS) * [Codrops](http://tympanus.net/codrops/css_reference/) ## Další čtení * [Pochopení priority v CSS: specifičnost, děditelnost a kaskáda](http://www.vanseodesign.com/css/css-specificity-inheritance-cascaade/) * [Vybírání elementů pomocí atributů](https://css-tricks.com/almanac/selectors/a/attribute/) * [QuirksMode CSS](http://www.quirksmode.org/css/) * [Z-Index - překrývání obsahu](https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Understanding_z_index/The_stacking_context) * [SASS](http://sass-lang.com/) a [LESS](http://lesscss.org/) pro CSS pre-processing * [CSS-Triky](https://css-tricks.com) --- language: Elm contributors: - ["Max Goldstein", "http://maxgoldste.in/"] translators: - ["Robin Pokorný", "http://robinpokorny.com/"] filename: learnelm-cz.elm lang: cs-cz --- Elm je funkcionální reaktivní jazyk, který se kompiluje do (klientského) JavaScriptu. Elm je silně typovaný, díky tomu je překladač schopen zachytit většinu chyb okamžitě a vypsat snadno srozumitelná chybová hlášení. Elm se hodí k tvorbě webových uživatelských rozhraní a her. ```haskell -- Jednořádkové komentáře začínají dvěma pomlčkami. {- Víceřádkové komentáře mohou být takto uzavřeny do bloku. {- Mohou být i zanořeny. -} -} {-- Základy --} -- Aritmetika 1 + 1 -- 2 8 - 1 -- 7 10 * 2 -- 20 -- Každé číslo bez desetinné tečky je typu Int nebo Float. 33 / 2 -- 16.5 s reálným dělením 33 // 2 -- 16 s celočíselným dělením -- Umocňování 5 ^ 2 -- 25 -- Pravdivostní proměnné not True -- False not False -- True 1 == 1 -- True 1 /= 1 -- False 1 < 10 -- True -- Řetězce a znaky "Toto je textový řetězec, protože používá dvojité uvozovky." 'a' -- znak v jednoduchých uvozovkách -- Řetězce lze spojovat. "Ahoj " ++ "světe!" -- "Ahoj světe!" {-- Seznamy (List), n-tice (Tuple) a Záznamy (Record) --} -- Každá položka seznamu musí být stejného typu. ["příliš", "žluťoučký", "kůň", "úpěl"] [1, 2, 3, 4, 5] -- Druhý příklad lze zapsat také pomocí dvou teček. List.range 1 5 -- Spojovat seznamy lze stejně jako řetězce. List.range 1 5 ++ List.range 6 10 == List.range 1 10 -- True -- K přidání položky do seznamu použijte funkci "cons". 0 :: List.range 1 5 -- [0, 1, 2, 3, 4, 5] -- Funkce "head" pro získání první položky seznamu i funkce "tail" pro získání následujích položek -- vrací typ Maybe. Místo zjišťování, jestli nějaká položka není null, -- se s chybějcími hodnotami vypořádáme explicitně. List.head (List.range 1 5) -- Just 1 List.tail (List.range 1 5) -- Just [2, 3, 4, 5] List.head [] -- Nothing -- List.nazevFunkce odkazuje na funkci, která žije v modulu List. -- Každý prvek v n-tici může být jiného typu, ale n-tice má pevný počet prvků. ("elm", 42) -- K získání hodnot z dvojice použijte funkce first a second. -- (Toto je pouze zkratka. Brzy si ukážeme, jak na to "správně".) fst ("elm", 42) -- "elm" snd ("elm", 42) -- 42 -- Prázná n-tice, neboli "unit", se občas používá jako zástupný symbol. -- Je to jediná hodnota svého typu, který se také nazývá "Unit". () -- Záznamy jsou podobné n-ticím, ale prvky jsou pojmenovány. Na pořadí nezáleží. -- Povšimněte si, že hodnoty vlastností se přiřazují rovnítky, ne dvojtečkami. { x = 3, y = 7 } -- K hodnotám se přistupuje pomocí tečky a názvu vlastnosti. { x = 3, y = 7 }.x -- 3 -- Nebo využitím přístupové funkce, což je jen tečka a název vlastnosti. .y { x = 3, y = 7 } -- 7 -- Změna hodnoty vlastnosti v záznamu. (Záznam tuto vlastnost už musí mít.) { osoba | jmeno = "Jiří" } -- Změna více vlastností s využitím aktuálních hodnot. { hmotnyBod | poloha = hmotnyBod.poloha + hmotnyBod.rychlost, rychlost = hmotnyBod.rychlost + hmotnyBod.zrychleni } {-- Řídicí struktury --} -- Podmínky vždy musí mít větev "else" a obě větve musí být stejného typu. if powerLevel > 9000 then "PÁNI!" else "hmm" -- Podmínky lze skládat za sebe. if n < 0 then "n je záporné" else if n > 0 then "n je kladné" else "n je nula" -- Použíjte příkaz "case" k nalezení shody vzoru a různých možností. case seznam of [] -> "odpovídá práznému seznamu" [x]-> "odpovídá seznamu o právě jedné položce, " ++ toString x x::xs -> "odpovídá seznamu o alespoň jedné položce, jehož prvním prvkem je " ++ toString x -- Shody se vyhodnocují v zapsaném pořadí. Kdybychom umístili [x] poslední, nikdy by nenastala shoda, -- protože x::xs také odpovídá (xs by byl prázdný seznam). Shody "nepropadají". -- Překladač vždy upozorní na chybějící nebo přebývající větve. -- Větvení typu Maybe. case List.head seznam of Just x -> "První položka je " ++ toString x Nothing -> "Seznam byl prázdný." {-- Funkce --} -- Syntaxe funkcí je v Elmu velmi úsporná, založená spíše na mezerách -- než na závorkách. Neexistuje tu klíčové slovo "return". -- Funkci definujeme jejím jménem, parametry, rovnítkem a tělem. vynasob a b = a * b -- Funkci voláme předáním parametrů (bez oddělujících čárek). vynasob 7 6 -- 42 -- Částečně aplikované funkci předáme pouze některé parametry. -- Poté zvolíme nové jméno. zdvoj = vynasob 2 -- Konstanty jsou podobné, ale nepřijímají žádné parametry. odpoved = 42 -- Předejte funkci jako parametr jiným funkcím. List.map zdvoj (List.range 1 4) -- [2, 4, 6, 8] -- Nebo použijte anonymní funkci. List.map (\a -> a * 2) (List.range 1 4) -- [2, 4, 6, 8] -- V definici funkce lze zapsat vzor, může-li nastat pouze jeden případ. -- Tato funkce přijímá jednu dvojici místo dvou parametrů. obsah (sirka, delka) = sirka * delka obsah (6, 7) -- 42 -- Složenými závorkami vytvořte vzor pro názvy vlastností v záznamu. -- Použijte "let" k definici lokálních proměnných. objem {sirka, delka, hloubka} = let obsah = sirka * delka in obsah * hloubka objem { sirka = 3, delka = 2, hloubka = 7 } -- 42 -- Funkce mohou být rekurzivní. fib n = if n < 2 then 1 else fib (n - 1) + fib (n - 2) List.map fib (List.range 0 8) -- [1, 1, 2, 3, 5, 8, 13, 21, 34] -- Jiná rekurzivní funkce (v praxi použijte List.length). delkaSeznamu seznam = case seznam of [] -> 0 x::xs -> 1 + delkaSeznamu xs -- Funkce se volají před jakýmkoli infixovým operátorem. Závorky určují prioritu. cos (degrees 30) ^ 2 + sin (degrees 30) ^ 2 -- 1 -- Nejprve se aplikuje "degrees" na číslo 30, výsledek je pak předán trigonometrickým -- funkcím, které jsou následně umocněny na druhou, na závěr proběhne sčítání. {-- Typy a typové anotace --} -- Překladač odvodí typ každé hodnoty ve vašem programu. -- Typy vždy začínají velkým písmenem. Čtete x : T jako "x je typu T". -- Některé běžné typy, které můžete videt v Elmovém REPLu. 5 : Int 6.7 : Float "ahoj" : String True : Bool -- Funkce mají také typy. Čtěte "->" jako "vrací". -- O typu na konci uvažujte jako návratovém typu, o ostatních jako typech argumentů. not : Bool -> Bool round : Float -> Int -- Když definujete hodnotu, je dobrým zvykem zapsat nad ni její typ. -- Anotace je formou dokumentace, která je ověřována překladačem. zdvoj : Int -> Int zdvoj x = x * 2 -- Funkce jako parametr je uzavřena v závorkách. -- Typy s malým počátečním písmenem jsou typové proměnné: -- mohou být libovolného typu, ale v každém volání musí být stejné. List.map : (a -> b) -> List a -> List b -- "List tečka map je typu a-vrací-b, vrací seznam-položek-typu-a, vrací seznam-položek-typu-b." -- Existují tři speciální typové proměnné: -- číslo (number), porovnatelné (comparable), and spojitelné (appendable). -- Čísla dovolují použít aritmetiku na Int a Float. -- Porovnatelné dovolují uspořádat čísla a řetězce, např. a < b. -- Spojitelné lze zřetězit pomocí a ++ b. {-- Typové aliasy a výčtové typy --} -- Pro záznamy a n-tice již typy automaticky existují. -- (Povšimněte si, že typ vlatnosti záznamu přiřazujeme dvojtečkou a hodnotu rovnítkem.) pocatek : { x : Float, y : Float, z : Float } pocatek = { x = 0, y = 0, z = 0 } -- Stávajícím typům lze dávat jména využitím aliasů. type alias Bod3D = { x : Float, y : Float, z : Float } -- Alias pro záznam funguje také jako jeho konstruktor. jinyPocatek : Bod3D jinyPocatek = Bod3D 0 0 0 -- Jedná se stále o stejný typ, lze je tedy porovnat. pocatek == jinyPocatek -- True -- Oproti tomu výčtový (union) typ definuje zcela nový typ. -- Výčtový typ se takto jmenuje, protože může být jedním z několika vybraných možností. -- Každá možnost je reprezentována jako "tag". type Smer = Sever | Jih | Vychod | Zapad -- Tagy mohou obsahovat další hodnoty známých typů. Lze využít i rekurze. type IntStrom = Vrchol | Uzel Int IntStrom IntStrom -- "Vrchol" i "Uzel" jsou tagy. Vše, co následuje za tagem, je typ. -- Tagy lze použít jako hodnoty funkcí. koren : IntStrom koren = Vrchol 7 List List -- Výčtové typy (a typové aliasy) mohou obsahovat typové proměnné. type Strom a = Vrchol | Uzel a (Strom a) (Strom a) -- "Typ strom-prvků-a je vrchol, nebo uzel obsahující a, strom-prvků-a a strom-prvků-a." -- Vzory se shodují s tagy. Tagy s velkým počátečním písmenem odpovídají přesně. -- Proměnné malým písmem odpovídají čemukoli. Podtržítko také odpovídá čemukoli, -- ale určuje, že tuto hodnotu dále nechceme používat. nejviceVlevo : Strom a -> Maybe a nejviceVlevo strom = case strom of Vrchol -> Nothing Uzel x Vrchol _ -> Just x Uzel _ podstrom _ -> nejviceVlevo podstrom -- To je víceméně vše o jazyku samotném. -- Podívejme se nyní, jak organizovat a spouštět náš kód. {-- Moduly a importování --} -- Standardní knihovny jsou organizovány do modulů, stejně jako knihovny třetích stran, -- které můžete využívat. Ve větších projektech můžete definovat vlastní moduly. -- Vložte toto na začátek souboru. Pokud nic neuvedete, předpokládá se "Main". module Jmeno where -- Výchozím chováním je, že se exportuje vše. -- Případně můžete definovat exportované vlastnosti explicitně. module Jmeno (MujTyp, mojeHodnota) where -- Běžný návrhový vzor je expotovat pouze výčtový typ bez jeho tagů. -- Tento vzor je znám jako krycí typ a často se využívá v knihovnách. -- Z jiných modulů lze importovat kód a použít jej v aktuálním modulu. -- Nasledující umístí Dict do aktuálního scope, takže lze volat Dict.insert. import Dict -- Importuje modul Dict a typ Dict, takže v anotacích není nutné psát Dict.Dict. -- Stále lze volat Dict.insert. import Dict exposing (Dict) -- Přejmenování importu. import Graphics.Collage as C {-- Porty --} -- Port oznamuje, že budete komunikovat s vnějším světem. -- Porty jsou dovoleny pouze v modulu Main. -- Příchozí port je jen typová anotace. port idKlienta : Int -- Odchozí port má definici. port objednavkaKlienta : List String port objednavkaKlienta = ["Knihy", "Potraviny", "Nábytek"] -- Nebudeme zacházet do detailů, ale v JavaScriptu se dají nastavit -- callbacky pro zasílání na příchozí porty a čtení z odchozích portů. {-- Nástroje pro příkazovou řádku --} -- Kompilace souboru. $ elm make MujSoubor.elm -- Při prvním spuštění nainstaluje Elm standardní knihovny a vytvoří soubor -- elm-package.json, kde jsou uloženy informace o vašem projektu. -- Elm reactor je server, který překládá a spouští vaše soubory. -- Kliknutím na klíč vedle názvu souboru spustíte debugger s cestovám v čase! $ elm reactor -- Zkoušejte si jednoduché příkazy v Read-Eval-Print Loop. $ elm repl -- Balíčky jsou určeny uživatelským jménem na GitHubu a názvem repozitáře. -- Nainstalujte nový balíček a uložte jej v souboru elm-package.json. $ elm package install evancz/elm-lang/html -- Porovnejte změny mezi verzemi jednoho balíčku. $ elm package diff elm-lang/html 1.1.0 2.0.0 -- Správce balíčků v Elmu vyžaduje sémantické verzování, -- takže minor verze nikdy nerozbije váš build. ``` Jazyk Elm je překvapivě malý. Nyní se můžete podívat do skoro jakéhokoli zdrojového kódu v Elmu a budete mít zběžnou představu o jeho fungování. Ovšem možnosti, jak psát kód, který je odolný vůči chybám a snadno se refaktoruje, jsou neomezené! Zde jsou některé užitečné zdroje (v angličtině). * [Hlavní stránka Elmu](http://elm-lang.org/). Obsahuje: * Odkazy na [instalátory](http://elm-lang.org/install) * [Documentaci](http://elm-lang.org/docs), včetně [popisu syntaxe](http://elm-lang.org/docs/syntax) * Spoustu nápomocných [příkladů](http://elm-lang.org/examples) * Documentace pro [standardní knihovny Elmu](http://package.elm-lang.org/packages/elm-lang/core/latest/). Povšimněte si: * [Základy](http://package.elm-lang.org/packages/elm-lang/core/latest/Basics), které jsou automaticky importovány * Typ [Maybe](http://package.elm-lang.org/packages/elm-lang/core/latest/Maybe) a jeho bratranec typ [Result](http://package.elm-lang.org/packages/elm-lang/core/latest/Result), které se běžně používají pro chybějící hodnoty a ošetření chyb. * Datové struktury jako [List](http://package.elm-lang.org/packages/elm-lang/core/latest/List), [Array](http://package.elm-lang.org/packages/elm-lang/core/latest/Array), [Dict](http://package.elm-lang.org/packages/elm-lang/core/latest/Dict) a [Set](http://package.elm-lang.org/packages/elm-lang/core/latest/Set) * JSON [enkódování](http://package.elm-lang.org/packages/elm-lang/core/latest/Json-Encode) a [dekódování](http://package.elm-lang.org/packages/elm-lang/core/latest/Json-Decode) * [Architektura Elmu](https://github.com/evancz/elm-architecture-tutorial#the-elm-architecture). Esej od tvůrce Elmu s příklady, jak organizovat kód do komponent. * [Elm mailing list](https://groups.google.com/forum/#!forum/elm-discuss). Všichni jsou přátelští a nápomocní. * [Scope v Elmu](https://github.com/elm-guides/elm-for-js/blob/master/Scope.md#scope-in-elm) a [Jak číst typové anotace](https://github.com/elm-guides/elm-for-js/blob/master/How%20to%20Read%20a%20Type%20Annotation.md#how-to-read-a-type-annotation). Další komunitní návody o základech Elmu, psáno pro JavaScriptové vývojáře. Běžte si zkusit něco napsat v Elmu! --- name: Go category: language language: Go filename: learngo-cs.go lang: cs-cz contributors: - ["Sonia Keys", "https://github.com/soniakeys"] - ["Christopher Bess", "https://github.com/cbess"] - ["Jesse Johnson", "https://github.com/holocronweaver"] - ["Quint Guvernator", "https://github.com/qguv"] - ["Jose Donizetti", "https://github.com/josedonizetti"] - ["Alexej Friesen", "https://github.com/heyalexej"] - ["Clayton Walker", "https://github.com/cwalk"] translators: - ["Ondra Linek", "https://github.com/defectus/"] --- Jazyk Go byl vytvořen, jelikož bylo potřeba dokončit práci. Není to poslední trend ve světě počítačové vědy, ale je to nejrychlejší a nejnovější způsob, jak řešit realné problémy. Go používá známé koncepty imperativních jazyků se statickým typováním. Rychle se kompiluje a také rychle běží. Přidává snadno pochopitelnou podporu konkurenčnosti, což umožňuje využít výhody multi-core procesorů a jazyk také obsahuje utility, které pomáhají se škálovatelným programováním. Go má již v základu vynikající knihovnu a je s ním spojená nadšená komunita. ```go // Jednořádkový komentář /* Několika řádkový komentář */ // Každý zdroják začíná deklarací balíčku (package) // Main je vyhrazené jméno, které označuje spustitelný soubor, // narozdíl od knihovny package main // Importní deklarace říkají, které knihovny budou použity v tomto souboru. import ( "fmt" // Obsahuje formátovací funkce a tisk na konzolu "io/ioutil" // Vstupně/výstupní funkce m "math" // Odkaz na knihovnu math (matematické funkce) pod zkratkou m "net/http" // Podpora http protokolu, klient i server. "strconv" // Konverze řetězců, např. na čísla a zpět. ) // Definice funkce. Funkce main je zvláštní, je to vstupní bod do programu. // Ať se vám to líbí, nebo ne, Go používá složené závorky func main() { // Println vypisuje na stdout. // Musí být kvalifikováno jménem svého balíčko, ftm. fmt.Println("Hello world!") // Zavoláme další funkci svetPoHello() } // Funkce mají své parametry v závorkách // Pokud funkce nemá parametry, tak musíme stejně závorky uvést. func svetPoHello() { var x int // Deklarace proměnné. Proměnné musí být před použitím deklarované x = 3 // Přiřazení hodnoty do proměnné // Existuje "krátká" deklarace := kde se typ proměnné odvodí, // proměnná vytvoří a přiřadí se jí hodnota y := 4 sum, prod := naucSeNasobit(x, y) // Funkce mohou vracet více hodnot fmt.Println("sum:", sum, "prod:", prod) // Jednoduchý výstup naucSeTypy() // < y minut je za námi, je čas učit se víc! } /* <- začátek mnohořádkového komentáře Funkce mohou mít parametry a (několik) návratových hodnot. V tomto případě jsou `x`, `y` parametry a `sum`, `prod` jsou návratové hodnoty. Všiměte si, že `x` a `sum` jsou typu `int`. */ func naucSeNasobit(x, y int) (sum, prod int) { return x + y, x * y // Vracíme dvě hodnoty } // zabudované typy a literáty. func naucSeTypy() { // Krátká deklarace většinou funguje str := "Learn Go!" // typ řetězec. s2 := `"surový" literát řetězce může obsahovat nové řádky` // Opět typ řetězec. // Můžeme použít ne ASCII znaky, Go používá UTF-8. g := 'Σ' // type runa, což je alias na int32 a ukládá se do něj znak UTF-8 f := 3.14195 // float64, je IEEE-754 64-bit číslem s plovoucí čárkou. c := 3 + 4i // complex128, interně uložené jako dva float64. // takhle vypadá var s inicializací var u uint = 7 // Číslo bez znaménka, jehož velikost záleží na implementaci, // stejně jako int var pi float32 = 22. / 7 // takto se převádí typy za pomoci krátké syntaxe n := byte('\n') // byte je jiné jméno pro uint8. // Pole mají fixní délku, které se určuje v době kompilace. var a4 [4]int // Pole 4 intů, všechny nastaveny na 0. a3 := [...]int{3, 1, 5} // Pole nastaveno na tři hodnoty // elementy mají hodntu 3, 1 a 5 // Slicy mají dynamickou velikost. Pole i slacy mají své výhody, // ale většinou se používají slicy. s3 := []int{4, 5, 9} // Podobně jako a3, ale není tu výpustka. s4 := make([]int, 4) // Alokuj slice 4 intů, všechny nastaveny na 0. var d2 [][]float64 // Deklarace slicu, nic se nealokuje. bs := []byte("a slice") // Přetypování na slice // Protože jsou dynamické, můžeme ke slicům přidávat za běhu // Přidat ke slicu můžeme pomocí zabudované funkce append(). // Prvním parametrem je slice, návratová hodnota je aktualizovaný slice. s := []int{1, 2, 3} // Výsledkem je slice se 3 elementy. s = append(s, 4, 5, 6) // Přidány další 3 elementy. Slice má teď velikost 6. fmt.Println(s) // Slice má hodnoty [1 2 3 4 5 6] // Pokud chceme k poli přičíst jiné pole, můžeme předat referenci na slice, // nebo jeho literát a přidat výpustku, čímž se slicu "rozbalí" a přidá se k // původnímu slicu. s = append(s, []int{7, 8, 9}...) // druhým parametrem je literát slicu. fmt.Println(s) // slice má teď hodnoty [1 2 3 4 5 6 7 8 9] p, q := naucSePraciSPameti() // Deklarujeme p a q jako typ pointer na int. fmt.Println(*p, *q) // * dereferencuje pointer. Tím se vypíší dva inty. // Mapy jsou dynamické rostoucí asociativní pole, jako hashmapa, nebo slovník // (dictionary) v jiných jazycích m := map[string]int{"tri": 3, "ctyri": 4} m["jedna"] = 1 // Napoužité proměnné jsou v Go chybou. // Použijte podtržítko, abychom proměnno "použili". _, _, _, _, _, _, _, _, _, _ = str, s2, g, f, u, pi, n, a3, s4, bs // Výpis promenné se počítá jako použití. fmt.Println(s, c, a4, s3, d2, m) naucSeVetveníProgramu() // Zpátky do běhu. } // narozdíl od jiných jazyků, v Go je možné mít pojmenované návratové hodnoty. // Tak můžeme vracet hodnoty z mnoha míst funkce, aniž bychom uváděli hodnoty v // return. func naucSePojmenovaneNavraty(x, y int) (z int) { z = x * y return // z je zde implicitní, jelikož bylo pojmenováno. } // Go má garbage collector. Používá pointery, ale neumožňuje jejich aritmetiku. // Můžete tedy udělat chybu použitím nil odkazu, ale ne jeho posunutím. func naucSePraciSPameti() (p, q *int) { // Pojmenované parametry p a q mají typ odkaz na int. p = new(int) // Zabudované funkce new alokuje paměť. // Alokované místo pro int má hodnotu 0 a p už není nil. s := make([]int, 20) // Alokujeme paměť pro 20 intů. s[3] = 7 // Jednu z nich nastavíme. r := -2 // Deklarujeme další lokální proměnnou. return &s[3], &r // a vezmeme si jejich odkaz pomocí &. } func narocnyVypocet() float64 { return m.Exp(10) } func naucSeVetveníProgramu() { // Výraz if vyžaduje složené závorky, ale podmínka nemusí být v závorkách. if true { fmt.Println("říkal jsme ti to") } // Formátování je standardizované pomocí utility "go fmt". if false { // posměšek. } else { // úšklebek. } // Použij switch, když chceš zřetězit if. x := 42.0 switch x { case 0: case 1: case 42: // jednotlivé case nepropadávají. není potřeba "break" case 43: // nedosažitelné, jelikož už bylo ošetřeno. default: // implicitní větev je nepovinná. } // Stejně jako if, for (smyčka) nepoužívá závorky. // Proměnné definované ve for jsou lokální vůči smyčce. for x := 0; x < 3; x++ { // ++ je výrazem. fmt.Println("iterace", x) } // zde je x == 42. // For je jediná smyčka v Go, ale má několik tvarů. for { // Nekonečná smyčka break // Dělám si legraci continue // Sem se nedostaneme } // Můžete použít klíčové slovo range pro iteraci nad mapami, poli, slicy, // řetězci a kanály. // range vrací jednu (kanál) nebo dvě hodnoty (pole, slice, řetězec a mapa). for key, value := range map[string]int{"jedna": 1, "dva": 2, "tri": 3} { // pro každý pár (klíč a hodnota) je vypiš fmt.Printf("klíč=%s, hodnota=%d\n", key, value) } // stejně jako for, := v podmínce if přiřazuje hodnotu // nejříve nastavíme y a pak otestujeme, jestli je y větší než x. if y := narocnyVypocet(); y > x { x = y } // Funkční literáty jsou tzv. uzávěry (closure) xBig := func() bool { return x > 10000 // odkazuje na x deklarované ve příkladu použití switch } x = 99999 fmt.Println("xBig:", xBig()) // true x = 1.3e3 // To udělá z x == 1300 fmt.Println("xBig:", xBig()) // teď už false. // Dále je možné funkční literáty definovat a volat na místě jako parametr // funkce, dokavaď: // a) funkční literát je okamžitě volán pomocí (), // b) výsledek se shoduje s očekávaným typem. fmt.Println("Sečte + vynásobí dvě čísla: ", func(a, b int) int { return (a + b) * 2 }(10, 2)) // Voláno s parametry 10 a 2 // => Sečti a vynásob dvě čísla. 24 // Když to potřebujete, tak to milujete goto miluji miluji: naučteSeFunkčníFactory() // funkce vracející funkce je zábava(3)(3) naučteSeDefer() // malá zajížďka k důležitému klíčovému slovu. naučteSeInterfacy() // Přichází dobré věci! } func naučteSeFunkčníFactory() { // Následující dvě varianty jsou stejné, ale ta druhá je praktičtější fmt.Println(větaFactory("létní")("Hezký", "den!")) d := větaFactory("letní") fmt.Println(d("Hezký", "den!")) fmt.Println(d("Líný", "odpoledne!")) } // Dekorátory jsou běžné v jiných jazycích. To samé můžete udělat v Go // pomocí parameterizovatelných funkčních literátů. func větaFactory(můjŘetězec string) func(před, po string) string { return func(před, po string) string { return fmt.Sprintf("%s %s %s", před, můjŘetězec, po) // nový řetězec } } func naučteSeDefer() (ok bool) { // Odloží (defer) příkazy na okamžik těsně před opuštěním funkce. // tedy poslední se provede první defer fmt.Println("odložené příkazy jsou zpravovaná v LIFO pořadí.") defer fmt.Println("\nProto je tato řádka vytištěna první") // Defer se běžně používá k zavírání souborů a tím se zajistí, že soubor // bude po ukončení funkce zavřen. return true } // definuje typ interfacu s jednou metodou String() type Stringer interface { String() string } // Definuje pár jako strukturu se dvěma poli typu int x a y. type pár struct { x, y int } // Definuje method pár. Pár tedy implementuje interface Stringer. func (p pár) String() string { // p je tu nazýváno "Receiver" - přijímač // Sprintf je další veřejná funkce z balíčku fmt. // Pomocí tečky přistupujeme k polím proměnné p return fmt.Sprintf("(%d, %d)", p.x, p.y) } func naučteSeInterfacy() { // Složené závorky jsou "strukturální literáty. Vyhodnotí a inicializuje // strukturu. Syntaxe := deklaruje a inicializuje strukturu. p := pár{3, 4} fmt.Println(p.String()) // Volá metodu String na p typu pár. var i Stringer // Deklaruje i jako proměnné typu Stringer. i = p // Toto je možné, jelikož oba implementují Stringer // zavolá metodu String(( typu Stringer a vytiskne to samé jako předchozí. fmt.Println(i.String()) // Funkce ve balíčku fmt volají metodu String, když zjišťují, jak se má typ // vytisknout. fmt.Println(p) // Vytiskne to samé, jelikož Println volá String(). fmt.Println(i) // Ten samý výstup. naučSeVariabilníParametry("super", "učit se", "tady!") } // Funcke mohou mít proměnlivé množství parametrů. func naučSeVariabilníParametry(mojeŘetězce ...interface{}) { // Iterujeme přes všechny parametry // Potržítku tu slouží k ignorování indexu v poli. for _, param := range mojeŘetězce { fmt.Println("parameter:", param) } // Použít variadický parametr jako variadický parametr, nikoliv pole. fmt.Println("parametery:", fmt.Sprintln(mojeŘetězce...)) naučSeOšetřovatChyby() } func naučSeOšetřovatChyby() { // ", ok" je metodou na zjištění, jestli něco fungovalo, nebo ne. m := map[int]string{3: "tri", 4: "ctyri"} if x, ok := m[1]; !ok { // ok bude false, jelikož 1 není v mapě. fmt.Println("není tu jedna") } else { fmt.Print(x) // x by bylo tou hodnotou, pokud by bylo v mapě. } // hodnota error není jen znamením OK, ale může říct více o chybě. if _, err := strconv.Atoi("ne-int"); err != nil { // _ hodnotu zahodíme // vytiskne 'strconv.ParseInt: parsing "non-int": invalid syntax' fmt.Println(err) } // Znovu si povíme o interfacech, zatím se podíváme na naučSeKonkurenčnost() } // c je kanál, způsob, jak bezpečně komunikovat v konkurenčním prostředí. func zvyš(i int, c chan int) { c <- i + 1 // <- znamená "pošli" a posílá data do kanálu na levé straně. } // Použijeme funkci zvyš a konkurečně budeme zvyšovat čísla. func naučSeKonkurenčnost() { // funkci make jsme již použili na slicy. make alokuje a inicializuje slidy, // mapy a kanály. c := make(chan int) // nastartuj tři konkurenční go-rutiny. Čísla se budou zvyšovat // pravděpodobně paralelně pokud je počítač takto nakonfigurován. // Všechny tři zapisují do toho samého kanálu. go zvyš(0, c) // go je výraz pro start nové go-rutiny. go zvyš(10, c) go zvyš(-805, c) // Přečteme si tři výsledky a vytiskeneme je.. // Nemůžeme říct, v jakém pořadí výsledky přijdou! fmt.Println(<-c, <-c, <-c) // pokud je kanál na pravo, jedná se o "přijmi". cs := make(chan string) // Další kanál, tentokrát pro řetězce. ccs := make(chan chan string) // Kanál kanálu řetězců. go func() { c <- 84 }() // Start nové go-rutiny na posílání hodnot. go func() { cs <- "wordy" }() // To samé s cs. // Select má syntaxi jako switch, ale vztahuje se k operacím nad kanály. // Náhodně vybere jeden case, který je připraven na komunikaci. select { case i := <-c: // Přijatá hodnota může být přiřazena proměnné. fmt.Printf("je to typ %T", i) case <-cs: // nebo může být zahozena fmt.Println("je to řetězec") case <-ccs: // prázdný kanál, nepřipraven ke komunikaci. fmt.Println("to se nestane.") } // V tomto okamžiku máme hodnotu buď z kanálu c nabo cs. Jedna nebo druhá // nastartovaná go-rutina skončila a další zůstane blokovaná. naučSeProgramovatWeb() // Go to umí. A vy to chcete taky. } // jen jedna funkce z balíčku http spustí web server. func naučSeProgramovatWeb() { // První parametr ListenAndServe je TCP adresa, kde poslouchat. // Druhý parametr je handler, implementující interace http.Handler. go func() { err := http.ListenAndServe(":8080", pár{}) fmt.Println(err) // neignoruj chyby }() requestServer() } // Umožní typ pár stát se http tím, že implementuje její jedinou metodu // ServeHTTP. func (p pár) ServeHTTP(w http.ResponseWriter, r *http.Request) { // Servíruj data metodou http.ResponseWriter w.Write([]byte("Naučil ses Go za y minut!")) } func requestServer() { resp, err := http.Get("http://localhost:8080") fmt.Println(err) defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) fmt.Printf("\nWebserver řekl: `%s`", string(body)) } ``` ## Kam dále Vše hlavní o Go se nachází na [oficiálních stránkách go](http://golang.org/). Tam najdete tutoriály, interaktivní konzolu a mnoho materiálu ke čtení. Kromě úvodu, [dokumenty](https://golang.org/doc/) tam obsahují jak psát čistý kód v Go popis balíčků (package), dokumentaci příkazové řádky a historii releasů. Také doporučujeme přečíst si definici jazyka. Je čtivá a překvapivě krátká. Tedy alespoň proti jiným současným jazyků. Pokud si chcete pohrát s Go, tak navštivte [hřiště Go](https://play.golang.org/p/r46YvCu-XX). Můžete tam spouštět programy s prohlížeče. Také můžete [https://play.golang.org](https://play.golang.org) použít jako [REPL](https://en.wikipedia.org/wiki/Read-eval-print_loop), kde si v rychlosti vyzkoušíte věci, bez instalace Go. Na vašem knižním seznamu, by neměly chybět [zdrojáky stadardní knihovny](http://golang.org/src/pkg/). Důkladně popisuje a dokumentuje Go, styl zápisu Go a Go idiomy. Pokud kliknete na [dokumentaci](http://golang.org/pkg/) tak se podíváte na dokumentaci. Dalším dobrým zdrojem informací je [Go v ukázkách](https://gobyexample.com/). Go mobile přidává podporu pro Android a iOS. Můžete s ním psát nativní mobilní aplikace nebo knihovny, které půjdou spustit přes Javu (pro Android), nebo Objective-C (pro iOS). Navštivte [web Go Mobile](https://github.com/golang/go/wiki/Mobile) pro více informací. --- language: Hack filename: learnhack-cs.hh contributors: - ["Stephen Holdaway", "https://github.com/stecman"] translators: - ["Vojta Svoboda", "https://github.com/vojtasvoboda/"] lang: cs-cz --- Hack je nadmnožinou PHP a běží v rámci virtuálního stroje zvaného HHVM. Hack dokáže skoro plně spolupracovat s existujícím PHP a přidává několik vylepšení, které známe ze staticky typovaných jazyků. Níže jsou popsané pouze vlastnosti jazyka Hack. Detaily ohledně jazyka PHP a jeho syntaxe pak najdete na těchto stránkách v samostatném [článku o PHP](http://learnxinyminutes.com/docs/php/). ```php id = $id; } } // Stručné anonymní funkce (lambda funkce) $multiplier = 5; array_map($y ==> $y * $multiplier, [1, 2, 3]); // Generika (generické funkce) class Box { protected T $data; public function __construct(T $data) { $this->data = $data; } public function getData(): T { return $this->data; } } function openBox(Box $box) : int { return $box->getData(); } // Tvary // // Hack zavádí koncept tvaru pro definování strukturovaných polí s garantovanou // typovou kontrolou pro klíče. type Point2D = shape('x' => int, 'y' => int); function distance(Point2D $a, Point2D $b) : float { return sqrt(pow($b['x'] - $a['x'], 2) + pow($b['y'] - $a['y'], 2)); } distance( shape('x' => -1, 'y' => 5), shape('x' => 2, 'y' => 50) ); // Type aliasing // // Hack přidává několik vylepšení pro lepší čitelnost komplexních typů newtype VectorArray = array>; // Množina obsahující čísla newtype Point = (int, int); function addPoints(Point $p1, Point $p2) : Point { return tuple($p1[0] + $p2[0], $p1[1] + $p2[1]); } addPoints( tuple(1, 2), tuple(5, 6) ); // Výčtový typ enum RoadType : int { Road = 0; Street = 1; Avenue = 2; Boulevard = 3; } function getRoadType() : RoadType { return RoadType::Avenue; } // Automatické nastavení proměnných třídy // // Aby se nemuseli definovat proměnné třídy a její konstruktor, // který pouze nastavuje třídní proměnné, můžeme v Hacku vše // definovat najednou. class ArgumentPromotion { public function __construct(public string $name, protected int $age, private bool $isAwesome) {} } // Takto by to vypadalo bez automatického nastavení proměnných class WithoutArugmentPromotion { public string $name; protected int $age; private bool $isAwesome; public function __construct(string $name, int $age, bool $isAwesome) { $this->name = $name; $this->age = $age; $this->isAwesome = $isAwesome; } } // Ko-operativní multi-tasking // // Nová klíčová slova "async" and "await" mohou být použité pro spuštění mutli-taskingu // Tato vlastnost ovšem zahrnuje vícevláknové zpracování, pouze povolí řízení přenosu async function cooperativePrint(int $start, int $end) : Awaitable { for ($i = $start; $i <= $end; $i++) { echo "$i "; // Dává ostatním úlohám šanci něco udělat await RescheduleWaitHandle::create(RescheduleWaitHandle::QUEUE_DEFAULT, 0); } } // Toto vypíše "1 4 7 2 5 8 3 6 9" AwaitAllWaitHandle::fromArray([ cooperativePrint(1, 3), cooperativePrint(4, 6), cooperativePrint(7, 9) ])->getWaitHandle()->join(); // Atributy // // Atributy jsou určitou formou metadat pro funkce. Hack přidává některé vestavěné // atributy které aktivnují uživatečné chování funkcí. // Speciální atribut __Memoize způsobí, že výsledek funkce je uložen do cache <<__Memoize>> function doExpensiveTask() : ?string { return file_get_contents('http://example.com'); } // Tělo funkce je v tomto případě vykonáno pouze jednou: doExpensiveTask(); doExpensiveTask(); // Speciální atribut __ConsistentConstruct signalizuje typové kontrole Hacku, že // zápis __construct bude stejný pro všechny podtřídy. <<__ConsistentConstruct>> class ConsistentFoo { public function __construct(int $x, float $y) { // ... } public function someMethod() { // ... } } class ConsistentBar extends ConsistentFoo { public function __construct(int $x, float $y) { // Typová kontrola Hacku zajistí volání konstruktoru rodičovské třídy parent::__construct($x, $y); // ... } // Anotace __Override je volitelný signál pro typovou kontrolu Hacku, že // tato metoda přetěžuje metodu rodičovské třídy, nebo traitu. Bez uvedení // této anotace vyhodí typová kontrola chybu. <<__Override>> public function someMethod() { // ... } } class InvalidFooSubclass extends ConsistentFoo { // Nedodržení zápisu dle rodičovského konstruktoru způsobí syntaktickou chybu: // // "Tento objekt je typu ConsistentBaz a není kompatibilní v tímto objektem, // který je typu ConsistentFoo protože některé jeho metody nejsou kompatibilní." // public function __construct(float $x) { // ... } // Použitím anotace __Override na nepřetíženou metodu způsobí chybu typové kontroly: // // "InvalidFooSubclass::otherMethod() je označená jako přetížená, ale nebyla nalezena // taková rodičovská metoda, nebo rodič kterého přetěžujete není zapsán v > public function otherMethod() { // ... } } // Traity mohou implementovat rozhraní, což standardní PHP neumí interface KittenInterface { public function play() : void; } trait CatTrait implements KittenInterface { public function play() : void { // ... } } class Samuel { use CatTrait; } $cat = new Samuel(); $cat instanceof KittenInterface === true; // True ``` ## Více informací Pro více informací navštivte [referenční příručku jazyka Hack](http://docs.hhvm.com/manual/en/hacklangref.php), kde se dozvíte více detailu a vylepšení, které jazyk Hack přidává do PHP, a nebo navštivte [oficiální stránky jazyka Hack](http://hacklang.org/) pro obecné informace. Pro instrukce k instalaci jazyka Hack navštivte [oficiální HHVM stránky](http://hhvm.com/). Pro více informací ohledně zpětné kompatibility s PHP navštivte článek o [nepodporovaných PHP vlastnostech Hacku](http://docs.hhvm.com/manual/en/hack.unsupported.php). --- language: javascript contributors: - ["Adam Brenecki", "http://adam.brenecki.id.au"] - ["Ariel Krakowski", "http://www.learneroo.com"] translators: - ["Michal Martinek", "https://github.com/MichalMartinek"] lang: cs-cz filename: javascript-cz.js --- JavaScript byl vytvořen Brendan Eichem v roce 1995 pro Netscape. Byl původně zamýšlen jako jednoduchý skriptovací jazyk pro webové stránky, jako doplněk Javy, která byla zamýšlena pro více komplexní webové aplikace, ale jeho úzké propojení s webovými stránkami a vestavěná podpora v prohlížečích způsobila, že se stala více běžná ve webovém frontendu než Java. JavaScript není omezen pouze na webové prohlížeče, např. projekt Node.js, který zprostředkovává samostatně běžící prostředí V8 JavaScriptového enginu z Google Chrome se stává více a více oblíbený pro serverovou část webových aplikací. Zpětná vazba je velmi ceněná. Autora článku můžete kontaktovat (anglicky) na [@adambrenecki](https://twitter.com/adambrenecki), nebo [adam@brenecki.id.au](mailto:adam@brenecki.id.au), nebo mě, jakožto překladatele, na [martinek@ludis.me](mailto:martinek@ludis.me). ```js // Komentáře jsou jako v zayku C. Jednořádkové komentáře začínájí dvojitým lomítkem, /* a víceřádkové komentáře začínají lomítkem s hvězdičkou a končí hvězdičkou s lomítkem */ // Vyrazu můžou být spuštěny pomocí ; delejNeco(); // ... ale nemusí, středníky jsou automaticky vloženy kdekoliv, // kde končí řádka, kromě pár speciálních případů delejNeco() // Protože tyto případy můžou způsobit neočekávané výsledky, budeme // středníky v našem návodu používat. ///////////////////////////////// // 1. Čísla, řetězce a operátory // JavaScript má jeden číselný typ (čímž je 64-bitový IEEE 754 double). // Double má 52-bit přesnost, což je dostatečně přesné pro ukládání celých čísel // do 9✕10¹⁵. 3; // = 3 1.5; // = 1.5 // Základní matematické operace fungují, jak byste očekávali 1 + 1; // = 2 0.1 + 0.2; // = 0.30000000000000004 8 - 1; // = 7 10 * 2; // = 20 35 / 5; // = 7 // Včetně dělení 5 / 2; // = 2.5 // A také dělení modulo 10 % 2; // = 0 30 % 4; // = 2 18.5 % 7; // = 4.5 // Bitové operace také fungují; když provádíte bitové operace, desetinné číslo // (float) se převede na celé číslo (int) se znaménkem *do* 32 bitů 1 << 2; // = 4 // Přednost se vynucuje závorkami. (1 + 3) * 2; // = 8 // Existují 3 hodnoty mimo obor reálných čísel Infinity; // + nekonečno; výsledek např. 1/0 -Infinity; // - nekonečno; výsledek např. -1/0 NaN; // výsledek např. 0/0, znamená, že výsledek není číslo ('Not a Number') // Také existují hodnoty typu bool true; // pravda false; // nepravda // Řetězce znaků jsou obaleny ' nebo ". 'abc'; "Ahoj světe!"; // Negace se tvoří pomocí ! !true; // = false !false; // = true // Rovnost se porovnává === 1 === 1; // = true 2 === 1; // = false // Nerovnost zase pomocí !== 1 !== 1; // = false 2 !== 1; // = true // Další srovnávání 1 < 10; // = true 1 > 10; // = false 2 <= 2; // = true 2 >= 2; // = true // Řetězce znaků se spojují pomocí + "Ahoj " + "světe!"; // = "Ahoj světe!" // ... což funguje nejenom s řetězci "1, 2, " + 3; // = "1, 2, 3" "Ahoj " + ["světe", "!"] // = "Ahoj světe,!" // a porovnávají se pomocí < nebo > "a" < "b"; // = true // Rovnost s převodem typů se dělá pomocí == ... "5" == 5; // = true null == undefined; // = true // ...dokud nepoužijete === "5" === 5; // = false null === undefined; // = false // ...což může občas způsobit divné chování... 13 + !0; // 14 "13" + !0; // '13true' // Můžeme přistupovat k jednotlivým znakům v řetězci pomocí charAt` "Toto je řetězec".charAt(0); // = 'T' // ...nebo použít `substring` k získání podřetězce "Ahoj světe".substring(0, 4); // = "Ahoj" // `length` znamená délka a je to vlastnost, takže nepoužívejte () "Ahoj".length; // = 4 // Existují také typy `null` a `undefined`. null; // značí, že žádnou hodnotu undefined; // značí, že hodnota nebyla definovaná (ikdyž // `undefined` je hodnota sama o sobě) // false, null, undefined, NaN, 0 and "" vrací nepravdu (false). Všechno ostatní // vrací pravdu (true).. // Všimněte si, že 0 vrací nepravdu, ale "0" vrací pravdu, ikdyž 0 == "0" // vrací pravdu /////////////////////////////////// // 2. Proměnné, pole a objekty // Proměnné jsou deklarovány pomocí slůvka `var`. JavaScript je dynamicky // typovaný, takže nemusíme specifikovat typ. K přiřazení hodnoty se používá // znak `=`. var promenna = 5; // když vynecháte slůvko 'var' nedostanete chybovou hlášku... jinaPromenna = 10; // ...ale vaše proměnná bude vytvořena globálně, bude vytvořena v globálním // oblasti působnosti, ne jenom v lokálním tam, kde jste ji vytvořili // Proměnné vytvořené bez přiřazení obsahují hodnotu undefined. var dalsiPromenna; // = undefined // Pokud chcete vytvořit několik proměnných najednou, můžete je oddělit čárkou var someFourthVar = 2, someFifthVar = 4; // Existuje kratší forma pro matematické operace na proměnné promenna += 5; // se provede stejně jako promenna = promenna + 5; // promenna je ted 10 promenna *= 10; // teď je promenna rovna 100 // a tohle je způsob, jak přičítat a odečítat 1 promenna++; // teď je promenna 101 promenna--; // zpět na 100 // Pole jsou uspořádané seznamy hodnot jakéhokoliv typu var mojePole = ["Ahoj", 45, true]; // Jednotlivé hodnoty jsou přístupné přes hranaté závorky. // Členové pole se začínají počítat na nule. myArray[1]; // = 45 // Pole je proměnlivé délky a členové se můžou měnit myArray.push("Světe"); myArray.length; // = 4 // Přidání/změna na specifickém indexu myArray[3] = "Hello"; // JavaScriptové objekty jsou stejné jako asociativní pole v jinných programovacích // jazycích: je to neuspořádaná množina páru hodnot - klíč:hodnota. var mujObjekt = {klic1: "Ahoj", klic2: "světe"}; // Klíče jsou řetězce, ale nejsou povinné uvozovky, pokud jsou validní // JavaScriptové identifikátory. Hodnoty můžou být jakéhokoliv typu- var mujObjekt = {klic: "mojeHodnota", "muj jiny klic": 4}; // K hodnotám můžeme přistupovat opět pomocí hranatých závorek myObj["muj jiny klic"]; // = 4 // ... nebo pokud je klíč platným identifikátorem, můžeme přistupovat k // hodnotám i přes tečku mujObjekt.klic; // = "mojeHodnota" // Objekty jsou měnitelné, můžeme upravit hodnoty, nebo přidat nové klíče. myObj.mujDalsiKlic = true; // Pokud se snažíte přistoupit ke klíči, který není nastaven, dostanete undefined myObj.dalsiKlic; // = undefined /////////////////////////////////// // 3. Řízení toku programu // Syntaxe pro tuto sekci je prakticky stejná jako pro Javu // `if` (když) funguje, jak byste čekali. var pocet = 1; if (pocet == 3){ // provede, když se pocet rovná 3 } else if (pocet == 4){ // provede, když se pocet rovná 4 } else { // provede, když je pocet cokoliv jinného } // Stejně tak cyklus while while (true){ // nekonečný cyklus } // Do-while cyklus je stejný jako while, akorát se vždy provede aspoň jednou var vstup; do { vstup = nactiVstup(); } while (!jeValidni(vstup)) // Cyklus for je stejný jako v Javě nebo jazyku C // inicializace; podmínka pro pokračování; iterace. for (var i = 0; i < 3; i++){ // provede třikrát } // Cyklus For-in iteruje přes každo vlastnost prototypu var popis = ""; var osoba = {prijmeni:"Paul", jmeno:"Ken", vek:18}; for (var x in osoba){ popis += osoba[x] + " "; } //Když chcete iterovat přes vlastnosti, které jsou přímo na objektu a nejsou //zděněné z prototypů, kontrolujte vlastnosti přes hasOwnProperty() var popis = ""; var osoba = {prijmeni:"Jan", jmeno:"Novák", vek:18}; for (var x in osoba){ if (osoba.hasOwnProperty(x)){ popis += osoba[x] + " "; } } // for-in by neměl být použit pro pole, pokud záleží na pořadí indexů. // Neexistuje jistota, že for-in je vrátí ve správném pořadí. // && je logické a, || je logické nebo if (dum.velikost == "velký" && dum.barva == "modrá"){ dum.obsahuje = "medvěd"; } if (barva == "červená" || barva == "modrá"){ // barva je červená nebo modtrá } // && a || jsou praktické i pro nastavení základních hodnot var jmeno = nejakeJmeno || "default"; // `switch` zkoumá přesnou rovnost (===) // Používejte 'break;' po každé možnosti, jinak se provede i možnost za ní. znamka = 'B'; switch (znamka) { case 'A': console.log("Výborná práce"); break; case 'B': console.log("Dobrá práce"); break; case 'C': console.log("Dokážeš to i lépe"); break; default: console.log("Ale ne"); break; } //////////////////////////////////////////////////////// // 4. Funckce, Oblast platnosti (scope) a Vnitřní funkce // JavaScriptové funkce jsou definovány slůvkem `function`. function funkce(text){ return text.toUpperCase(); } funkce("něco"); // = "NĚCO" // Dávejte si pozor na to, že hodnota k vrácení musí začínat na stejné řádce // jako slůvko return, jinak se vrátí 'undefined', kvůli automatickému vkládání // středníků. Platí to zejména pro Allmanův styl zápisu. function funkce() { return // <- zde je automaticky vložen středník { tohleJe: "vlastnost objektu" } } funkce(); // = undefined // JavaScriptové funkce jsou objekty, takže můžou být přiřazeny různým proměnným // a předány dalším funkcím jako argumenty, na příklad: function funkce(){ // tento kód bude zavolán za 5 vteřin } setTimeout(funkce, 5000); // Poznámka: setTimeout není část JS jazyka, ale funkce poskytována // prohlížeči a NodeJS // Další funkce poskytovaná prohlížeči je je setInterval function myFunction(){ // tento kód bude volán každých 5 vteřin } setInterval(myFunction, 5000); // Objekty funkcí nemusíme ani deklarovat pomocí jména, můžeme je napsat jako // ananymní funkci přímo vloženou jako argument setTimeout(function(){ // tento kód bude zavolán za 5 vteřin }, 5000); // JavaScript má oblast platnosti funkce, funkce ho mají, ale jiné bloky ne if (true){ var i = 5; } i; // = 5 - ne undefined, jak byste očekávali v jazyku, kde mají bloky svůj // rámec působnosti // Toto je běžný model,který chrání před únikem dočasných proměnných do //globální oblasti (function(){ var docasna = 5; // Můžeme přistupovat k globálního oblasti přes přiřazování globalním // objektům. Ve webovém prohlížeči je to vždy 'window`. Globální objekt // může mít v jiných prostředích jako Node.js jinné jméno. window.trvala = 10; })(); docasna; // způsobí ReferenceError trvala; // = 10 // Jedna z nejvice mocných vlastnosti JavaScriptu je vnitřní funkce. Je to funkce // definovaná v jinné funkci, vnitřní funkce má přístup ke všem proměnným ve // vnější funkci, dokonce i poté, co funkce skončí function ahojPoPetiVterinach(jmeno){ var prompt = "Ahoj, " + jmeno + "!"; // Vnitřní funkce je dána do lokální oblasti platnosti, jako kdyby byla // deklarovaná slůvkem 'var' function vnitrni(){ alert(prompt); } setTimeout(vnitrni, 5000); // setTimeout je asynchronní, takže funkce ahojPoPetiVterinach se ukončí // okamžitě, ale setTimeout zavolá funkci vnitrni až poté. Avšak protože // vnitrni je definována přes ahojPoPetiVterinach, má pořád přístup k // proměnné prompt, když je konečně zavolána. } ahojPoPetiVterinach("Adam"); // otevře popup s "Ahoj, Adam!" za 5s /////////////////////////////////////////////////// // 5. Více o objektech, konstuktorech a prototypech // Objekty můžou obsahovat funkce var mujObjekt = { mojeFunkce: function(){ return "Ahoj světe!"; } }; mujObjekt.mojeFunkce(); // = "Ahoj světe!" // Když jsou funkce z objektu zavolány, můžou přistupovat k objektu přes slůvko // 'this'' var mujObjekt = { text: "Ahoj světe!", mojeFunkce: function(){ return this.text; } }; mujObjekt.mojeFunkce(); // = "Ahoj světe!" // Slůvko this je nastaveno k tomu, kde je voláno, ne k tomu, kde je definováno // Takže naše funkce nebude fungovat, když nebude v kontextu objektu. var mojeFunkce = mujObjekt.mojeFunkce; mojeFunkce(); // = undefined // Opačně, funkce může být přiřazena objektu a může přistupovat k objektu přes // this, i když nebyla přímo v definici- var mojeDalsiFunkce = function(){ return this.text.toUpperCase(); } mujObjekt.mojeDalsiFunkce = mojeDalsiFunkce; mujObjekt.mojeDalsiFunkce(); // = "AHOJ SVĚTE!" // Můžeme také specifikovat, v jakém kontextu má být funkce volána pomocí // `call` nebo `apply`. var dalsiFunkce = function(s){ return this.text + s; } dalsiFunkce.call(mujObjekt, " A ahoj měsíci!"); // = "Ahoj světe! A ahoj měsíci!" // Funkce `apply`je velmi podobná, akorát bere jako druhý argument pole argumentů dalsiFunkce.apply(mujObjekt, [" A ahoj slunce!"]); // = "Ahoj světe! A ahoj slunce!" // To je praktické, když pracujete s funkcí, která bere sekvenci argumentů a // chcete předat pole. Math.min(42, 6, 27); // = 6 Math.min([42, 6, 27]); // = NaN Math.min.apply(Math, [42, 6, 27]); // = 6 // Ale `call` a `apply` jsou pouze dočasné. Pokud je chcete připojit trvale // použijte `bind`. var pripojenaFunkce = dalsiFunkce.bind(mujObjekt); pripojenaFunkce(" A ahoj Saturne!"); // = "Ahoj světe! A ahoj Saturne!" // `bind` může být použito čatečně částečně i k používání var nasobeni = function(a, b){ return a * b; } var zdvojeni = nasobeni.bind(this, 2); zdvojeni(8); // = 16 // Když zavoláte funkci se slůvkem 'new', vytvoří se nový objekt a // a udělá se dostupný funkcím skrz slůvko 'this'. Funkcím volaným takto se říká // konstruktory var MujKonstruktor = function(){ this.mojeCislo = 5; } mujObjekt = new MujKonstruktor(); // = {mojeCislo: 5} mujObjekt.mojeCislo; // = 5 // Každý JsavaScriptový objekt má prototyp. Když budete přistupovat k vlasnosti // objektu, který neexistuje na objektu, tak se JS koukne do prototypu. // Některé JS implementace vám umožní přistupovat k prototypu přes magickou // vlastnost '__proto__'. I když je toto užitečné k vysvětlování prototypů, není // to součást standardu, ke standartní způsobu k používání prototypu se dostaneme // později. var mujObjekt = { mujText: "Ahoj svete!" }; var mujPrototyp = { smyslZivota: 42, mojeFunkce: function(){ return this.mujText.toLowerCase() } }; mujObjekt.__proto__ = mujPrototyp; mujObjekt.smyslZivota; // = 42 // Toto funguje i pro funkce mujObjekt.mojeFunkce(); // = "Ahoj světe!" // Samozřejmě, pokud není vlastnost na vašem prototypu, tak se hledá na // prototypu od prototypu atd. mujPrototyp.__proto__ = { mujBoolean: true }; mujObjekt.mujBoolean; // = true // Zde neni žádné kopírování; každý objekt ukládá referenci na svůj prototyp // Toto znamená, že můžeme měnit prototyp a změny se projeví všude mujPrototyp.smyslZivota = 43; mujObjekt.smyslZivota // = 43 // Zmínili jsme již předtím, že '__proto__' není ve standardu a není cesta, jak // měnit prototyp existujícího objektu. Avšak existují možnosti, jak vytvořit // nový objekt s daným prototypem // První je Object.create, což je nedávný přídavek do JS a není dostupný zatím // ve všech implementacích. var mujObjekt = Object.create(mujPrototyp); mujObjekt.smyslZivota // = 43 // Druhý způsob, který funguje všude je pomocí konstuktoru. Konstruktor má // vlastnost jménem prototype. Toto *není* prototyp samotného konstruktoru, ale // prototyp nového objektu. MujKonstruktor.prototype = { mojeCislo: 5, ziskejMojeCislo: function(){ return this.mojeCislo; } }; var mujObjekt2 = new MujKonstruktor(); mujObjekt2.ziskejMojeCislo(); // = 5 mujObjekt2.mojeCislo = 6 mujObjekt2.ziskejMojeCislo(); // = 6 // Vestavěnné typy jako čísla nebo řetězce mají také konstruktory, které vytváří // ekvivalentní obalovací objekty (wrappery). var mojeCislo = 12; var mojeCisloObj = new Number(12); mojeCislo == mojeCisloObj; // = true // Avšak nejsou úplně přesně stejné typeof mojeCislo; // = 'number' typeof mojeCisloObj; // = 'object' mojeCislo === mojeCisloObj; // = false if (0){ // Tento kód se nespustí, protože 0 je nepravdivá (false) } if (new Number(0)){ // Tento kód se spustí, protože obalená čísla jsou objekty, // a objekty jsou vždy pravdivé } // Avšak, obalovací objekty a normální vestavěnné typy sdílejí prototyp, takže // můžete přidat funkcionalitu k řetězci String.prototype.prvniZnak = function(){ return this.charAt(0); } "abc".prvniZnak(); // = "a" // Tento fakt je často používán v polyfillech, což je implementace novějších // vlastností JavaScriptu do starších variant, takže je můžete používat třeba // ve starých prohlížečích // Pro příkklad, zmínili jsme, že Object.create není dostupný ve všech // implementacích, můžeme si avšak přidat pomocí polyfillu if (Object.create === undefined){ // nebudeme ho přepisovat, když existuje Object.create = function(proto){ // vytvoříme dočasný konstruktor var Constructor = function(){}; Constructor.prototype = proto; // ten použijeme k vytvoření nového s prototypem return new Constructor(); } } ``` ## Kam dál [Mozilla Developer Network](https://developer.mozilla.org/en-US/docs/Web/JavaScript) obsahuje perfektní dokumentaci pro JavaScript, který je používaný v prohlížečích. Navíc je to i wiki, takže jakmile se naučíte více, můžete pomoci ostatním, tím, že přispějete svými znalostmi. MDN's [A re-introduction to JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript) pojednává o konceptech vysvětlených zde v mnohem větší hloubce. Tento návod pokrývá hlavně JavaScript sám o sobě. Pokud se chcete naučit více, jak se používá na webových stránkách, začněte tím, že se kouknete na [DOM](https://developer.mozilla.org/en-US/docs/Using_the_W3C_DOM_Level_1_Core) [Learn Javascript by Example and with Challenges](http://www.learneroo.com/modules/64/nodes/350) je varianta tohoto návodu i s úkoly- [JavaScript Garden](http://bonsaiden.github.io/JavaScript-Garden/) je sbírka příkladů těch nejvíce nepředvídatelných částí tohoto jazyka. [JavaScript: The Definitive Guide](http://www.amazon.com/gp/product/0596805527/) je klasická výuková kniha. Jako dodatek k přímým autorům tohoto článku, některý obsah byl přizpůsoben z Pythoního tutoriálu od Louie Dinh na této stráce, a z [JS Tutorial](https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript) z Mozilla Developer Network. --- language: json contributors: - ["Anna Harren", "https://github.com/iirelu"] - ["Marco Scannadinari", "https://github.com/marcoms"] translators: - ["Vojta Svoboda", "https://github.com/vojtasvoboda/"] filename: learnjson-cz.json lang: cs-cz --- JSON je exterémně jednoduchý datově nezávislý formát a bude asi jeden z nejjednodušších 'Learn X in Y Minutes' ze všech. JSON nemá ve své nejzákladnější podobě žádné komentáře, ale většina parserů umí pracovat s komentáři ve stylu jazyka C (`//`, `/* */`). Pro tyto účely však budeme používat 100% validní JSON bez komentářů. Pojďme se podívat na syntaxi formátu JSON: ```json { "klic": "value", "hodnoty": "Musí být vždy uvozený v dvojitých uvozovkách", "cisla": 0, "retezce": "Hellø, wørld. Všechny unicode znaky jsou povolené, společně s \"escapováním\".", "pravdivostni_hodnota": true, "prazdna_hodnota": null, "velke_cislo": 1.2e+100, "objekt": { "komentar": "Most of your structure will come from objects.", "pole": [0, 1, 2, 3, "Pole nemusí být pouze homogenní.", 5], "jiny_objekt": { "comment": "Je povolené jakkoli hluboké zanoření." } }, "cokoli": [ { "zdroje_drasliku": ["banány"] }, [ [1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, "neo"], [0, 0, 0, 1] ] ], "alternativni_styl_zapisu": { "komentar": "Mrkni se na toto!" , "pozice_carky": "Na pozici čárky nezáleží - pokud je před hodnotou, ať už je kdekoli, tak je validní." , "dalsi_komentar": "To je skvělé." }, "to_bylo_rychle": "A tím jsme hotový. Nyní již víte vše, co může formát JSON nabídnout!" } ``` --- language: markdown lang: cs-cz contributors: - ["Dan Turkel", "http://danturkel.com/"] translators: - ["Michal Martinek", "https://github.com/MichalMartinek"] filename: markdown-cz.md lang: cs-cz --- Markdown byl vytvořen Johnem Gruberem v roce 2004. Je zamýšlen jako lehce čitelná a psatelná syntaxe, která je jednoduše převeditelná do HTML (a dnes i do mnoha dalších formátů) ```markdown # Toto je

## Toto je

### Toto je

#### Toto je

##### Toto je

###### Toto je
Toto je h1 ========== Toto je h2 ---------- *Tento text je kurzívou;* _Stejně jako tento._ **Tento text je tučně** __Stejně jako tento.__ ***Tento text je obojí*** **_Jako tento!_** *__A tento!__* ~~Tento text je prošktrnutý.~~ Toto je odstavec. Píši odstavec, není to zábava? Teď jsem v odstavci 2. Jsem pořád v odstavci 2! Toto je odstavec 3. Tento odstavec končí dvěma mezerami. Nad tímto odstavcem je
! > Toto je bloková citace. Můžete dokonce > manuálně rozdělit řádky, a před každý vložit >, nebo nechat vaše řádky jakkoliv dlouhé, ať se zarovnají sami. > Nedělá to rozdíl, dokud začínáte vždy znakem >. > Můžu použít více než jednu >> odsazení? > Jak je to úhledné, že? * Položka * Položka * Jinná položka nebo + Položka + Položka + Další položka nebo - Položka - Položka - Další položka 1. Položka jedna 2. Položka dvě 3. Položka tři 1. Položka jedna 1. Položka dvě 1. Položka tři 1. Položka jedna 2. Položka dvě 3. Položka tři * Podpoložka * Podpoložka 4. Položka čtyři Boxy níže bez 'x' jsou nezašktrnuté checkboxy. - [ ] První úkol - [ ] Druhý úkol Tento box bude zašktrnutý - [x] Tento úkol byl dokončen Toto je kód Stejně jako toto moje_pole.each do |i| puts i end Jan nevědel, jak se dělá `go_to()` funkce! \`\`\`ruby def neco puts "Ahoj světe!" end \`\`\` *** --- - - - **************** [Klikni na mě!](http://test.com/) [Klikni na mě!](http://test.com/ "Odkaz na Test.com") [Jdi na hudbu](/hudba/). [Klikni na tento odkaz][link1] pro více informací! [Taky zkontrolujte tento odkaz][neco], když chcete. [link1]: http://test.com/ "Cool!" [neco]: http://neco.czz/ "Dobře!" [Toto][] je odkaz.. [toto]: http://totojelink.cz/ ![Toto je atribut alt pro obrázek](http://imgur.com/myimage.jpg "Nepovinný titulek") ![Toto je atribut alt][mujobrazek] [mujobrazek]: relativni/cesta/obrazek.jpg "a toto by byl titulek" je stejná jako [http://stranka.cz/](http://stranka.cz/) Chci napsat *tento text obklopený hvězdičkami*, ale nechci aby to bylo kurzívou, tak udělám: \*tento text obklopený hvězdičkami\*. Váš počítač přestal pracovat? Zkuste Ctrl+Alt+Del | Sloupec1 | Sloupec2 | Sloupec3 | | :----------- | :------: | ------------: | | Vlevo zarovn.| Na střed | Vpravo zarovn.| | blah | blah | blah | Sloupec 1 | Sloupec2 | Sloupec3 :-- | :-: | --: Ohh toto je tak ošklivé | radši to | nedělejte ``` Pro více informací, prozkoumejte oficiální článek o syntaxi od Johna Grubera [zde](http://daringfireball.net/projects/markdown/syntax) a skvělý tahák od Adama Pritcharda [zde](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet). --- language: python3 contributors: - ["Louie Dinh", "http://pythonpracticeprojects.com"] - ["Steven Basart", "http://github.com/xksteven"] - ["Andre Polykanine", "https://github.com/Oire"] - ["Tomáš Bedřich", "http://tbedrich.cz"] translators: - ["Tomáš Bedřich", "http://tbedrich.cz"] filename: learnpython3-cz.py lang: cs-cz --- Python byl vytvořen Guidem Van Rossum v raných 90. letech. Nyní je jedním z nejpopulárnějších jazyků. Zamiloval jsem si Python pro jeho syntaktickou čistotu - je to vlastně spustitelný pseudokód. Vaše zpětná vazba je vítána! Můžete mě zastihnout na [@louiedinh](http://twitter.com/louiedinh) nebo louiedinh [at] [email od googlu] anglicky, autora českého překladu pak na [@tbedrich](http://twitter.com/tbedrich) nebo ja [at] tbedrich.cz Poznámka: Tento článek je zaměřen na Python 3. Zde se můžete [naučit starší Python 2.7](http://learnxinyminutes.com/docs/python/). ```python # Jednořádkový komentář začíná křížkem """ Víceřádkové komentáře používají tři uvozovky nebo apostrofy a jsou často využívány jako dokumentační komentáře k metodám """ #################################################### ## 1. Primitivní datové typy a operátory #################################################### # Čísla 3 # => 3 # Aritmetické operace se chovají běžným způsobem 1 + 1 # => 2 8 - 1 # => 7 10 * 2 # => 20 # Až na dělení, které vrací desetinné číslo 35 / 5 # => 7.0 # Při celočíselném dělení je desetinná část oříznuta (pro kladná i záporná čísla) 5 // 3 # => 1 5.0 // 3.0 # => 1.0 # celočíselně dělit lze i desetinným číslem -5 // 3 # => -2 -5.0 // 3.0 # => -2.0 # Pokud použijete desetinné číslo, výsledek je jím také 3 * 2.0 # => 6.0 # Modulo 7 % 3 # => 1 # Mocnění (x na y-tou) 2**4 # => 16 # Pro vynucení priority použijte závorky (1 + 3) * 2 # => 8 # Logické hodnoty True False # Negace se provádí pomocí not not True # => False not False # => True # Logické operátory # U operátorů záleží na velikosti písmen True and False # => False False or True # => True # Používání logických operátorů s čísly 0 and 2 # => 0 -5 or 0 # => -5 0 == False # => True 2 == True # => False 1 == True # => True # Rovnost je == 1 == 1 # => True 2 == 1 # => False # Nerovnost je != 1 != 1 # => False 2 != 1 # => True # Další porovnání 1 < 10 # => True 1 > 10 # => False 2 <= 2 # => True 2 >= 2 # => True # Porovnání se dají řetězit! 1 < 2 < 3 # => True 2 < 3 < 2 # => False # Řetězce používají " nebo ' a mohou obsahovat UTF8 znaky "Toto je řetězec." 'Toto je také řetězec.' # Řetězce se také dají sčítat, ale nepoužívejte to "Hello " + "world!" # => "Hello world!" # Dají se spojovat i bez '+' "Hello " "world!" # => "Hello world!" # Řetězec lze považovat za seznam znaků "Toto je řetězec"[0] # => 'T' # .format lze použít ke skládání řetězců "{} mohou být {}".format("řetězce", "skládány") # Formátovací argumenty můžete opakovat "{0} {1} stříkaček stříkalo přes {0} {1} střech".format("tři sta třicet tři", "stříbrných") # => "tři sta třicet tři stříbrných stříkaček stříkalo přes tři sta třicet tři stříbrných střech" # Pokud nechcete počítat, můžete použít pojmenované argumenty "{jmeno} si dal {jidlo}".format(jmeno="Franta", jidlo="guláš") # => "Franta si dal guláš" # Pokud zároveň potřebujete podporovat Python 2.5 a nižší, můžete použít starší způsob formátování "%s se dají %s jako v %s" % ("řetězce", "skládat", "jazyce C") # None je objekt (jinde NULL, nil, ...) None # => None # Pokud porovnáváte něco s None, nepoužívejte operátor rovnosti "==", # použijte raději operátor "is", který testuje identitu. "něco" is None # => False None is None # => True # None, 0, a prázdný řetězec/seznam/slovník se vyhodnotí jako False # Vše ostatní se vyhodnotí jako True bool(0) # => False bool("") # => False bool([]) # => False bool({}) # => False #################################################### ## 2. Proměnné a kolekce #################################################### # Python má funkci print print("Jsem 3. Python 3.") # Proměnné není třeba deklarovat před přiřazením # Konvence je používat male_pismo_s_podtrzitky nazev_promenne = 5 nazev_promenne # => 5 # Názvy proměnných mohou obsahovat i UTF8 znaky název_proměnné = 5 # Přístup k předtím nepoužité proměnné vyvolá výjimku # Odchytávání vyjímek - viz další kapitola neznama_promenna # Vyhodí NameError # Seznam se používá pro ukládání sekvencí sez = [] # Lze ho rovnou naplnit jiny_seznam = [4, 5, 6] # Na konec seznamu se přidává pomocí append sez.append(1) # sez je nyní [1] sez.append(2) # sez je nyní [1, 2] sez.append(4) # sez je nyní [1, 2, 4] sez.append(3) # sez je nyní [1, 2, 4, 3] # Z konce se odebírá se pomocí pop sez.pop() # => 3 a sez je nyní [1, 2, 4] # Vložme trojku zpátky sez.append(3) # sez je nyní znovu [1, 2, 4, 3] # Přístup k prvkům funguje jako v poli sez[0] # => 1 # Mínus počítá odzadu (-1 je poslední prvek) sez[-1] # => 3 # Přístup mimo seznam vyhodí IndexError sez[4] # Vyhodí IndexError # Pomocí řezů lze ze seznamu vybírat různé intervaly # (pro matematiky: jedná se o uzavřený/otevřený interval) sez[1:3] # => [2, 4] # Odříznutí začátku sez[2:] # => [4, 3] # Odříznutí konce sez[:3] # => [1, 2, 4] # Vybrání každého druhého prvku sez[::2] # =>[1, 4] # Vrácení seznamu v opačném pořadí sez[::-1] # => [3, 4, 2, 1] # Lze použít jakoukoliv kombinaci parametrů pro vytvoření složitějšího řezu # sez[zacatek:konec:krok] # Odebírat prvky ze seznamu lze pomocí del del sez[2] # sez je nyní [1, 2, 3] # Seznamy můžete sčítat # Hodnoty sez a jiny_seznam přitom nejsou změněny sez + jiny_seznam # => [1, 2, 3, 4, 5, 6] # Spojit seznamy lze pomocí extend sez.extend(jiny_seznam) # sez je nyní [1, 2, 3, 4, 5, 6] # Kontrola, jestli prvek v seznamu existuje, se provádí pomocí in 1 in sez # => True # Délku seznamu lze zjistit pomocí len len(sez) # => 6 # N-tice je jako seznam, ale je neměnná ntice = (1, 2, 3) ntice[0] # => 1 ntice[0] = 3 # Vyhodí TypeError # S n-ticemi lze dělat většinu operací, jako se seznamy len(ntice) # => 3 ntice + (4, 5, 6) # => (1, 2, 3, 4, 5, 6) ntice[:2] # => (1, 2) 2 in ntice # => True # N-tice (nebo seznamy) lze rozbalit do proměnných jedním přiřazením a, b, c = (1, 2, 3) # a je nyní 1, b je nyní 2 a c je nyní 3 # N-tice jsou vytvářeny automaticky, když vynecháte závorky d, e, f = 4, 5, 6 # Prohození proměnných je tak velmi snadné e, d = d, e # d je nyní 5, e je nyní 4 # Slovníky ukládají klíče a hodnoty prazdny_slovnik = {} # Lze je také rovnou naplnit slovnik = {"jedna": 1, "dva": 2, "tři": 3} # Přistupovat k hodnotám lze pomocí [] slovnik["jedna"] # => 1 # Všechny klíče dostaneme pomocí keys() jako iterovatelný objekt. Nyní ještě # potřebujeme obalit volání v list(), abychom dostali seznam. To rozebereme # později. Pozor, že jakékoliv pořadí klíčů není garantováno - může být různé. list(slovnik.keys()) # => ["dva", "jedna", "tři"] # Všechny hodnoty opět jako iterovatelný objekt získáme pomocí values(). Opět # tedy potřebujeme použít list(), abychom dostali seznam. Stejně jako # v předchozím případě, pořadí není garantováno a může být různé list(slovnik.values()) # => [3, 2, 1] # Operátorem in se lze dotázat na přítomnost klíče "jedna" in slovnik # => True 1 in slovnik # => False # Přístup k neexistujícímu klíči vyhodí KeyError slovnik["čtyři"] # Vyhodí KeyError # Metoda get() funguje podobně jako [], ale vrátí None místo vyhození KeyError slovnik.get("jedna") # => 1 slovnik.get("čtyři") # => None # Metodě get() lze předat i výchozí hodnotu místo None slovnik.get("jedna", 4) # => 1 slovnik.get("čtyři", 4) # => 4 # metoda setdefault() vloží prvek do slovníku pouze pokud tam takový klíč není slovnik.setdefault("pět", 5) # slovnik["pět"] je nastaven na 5 slovnik.setdefault("pět", 6) # slovnik["pět"] je pořád 5 # Přidání nové hodnoty do slovníku slovnik["čtyři"] = 4 # Hromadně aktualizovat nebo přidat data lze pomocí update(), parametrem je opět slovník slovnik.update({"čtyři": 4}) # slovnik je nyní {"jedna": 1, "dva": 2, "tři": 3, "čtyři": 4, "pět": 5} # Odebírat ze slovníku dle klíče lze pomocí del del slovnik["jedna"] # odebere klíč "jedna" ze slovnik # Množiny ukládají ... překvapivě množiny prazdna_mnozina = set() # Také je lze rovnou naplnit. A ano, budou se vám plést se slovníky. Bohužel. mnozina = {1, 1, 2, 2, 3, 4} # mnozina je nyní {1, 2, 3, 4} # Přidání položky do množiny mnozina.add(5) # mnozina je nyní {1, 2, 3, 4, 5} # Průnik lze udělat pomocí operátoru & jina_mnozina = {3, 4, 5, 6} mnozina & jina_mnozina # => {3, 4, 5} # Sjednocení pomocí operátoru | mnozina | jina_mnozina # => {1, 2, 3, 4, 5, 6} # Rozdíl pomocí operátoru - {1, 2, 3, 4} - {2, 3, 5} # => {1, 4} # Operátorem in se lze dotázat na přítomnost prvku v množině 2 in mnozina # => True 9 in mnozina # => False #################################################### ## 3. Řízení toku programu, cykly #################################################### # Vytvořme si proměnnou promenna = 5 # Takto vypadá podmínka. Na odsazení v Pythonu záleží! # Vypíše "proměnná je menší než 10". if promenna > 10: print("proměnná je velká jak Rusko") elif promenna < 10: # Část elif je nepovinná print("proměnná je menší než 10") else: # Část else je také nepovinná print("proměnná je právě 10") """ Smyčka for umí iterovat (nejen) přes seznamy vypíše: pes je savec kočka je savec myš je savec """ for zvire in ["pes", "kočka", "myš"]: # Můžete použít formát pro složení řetězce print("{} je savec".format(zvire)) """ range(cislo) vrací iterovatelný objekt čísel od 0 do cislo vypíše: 0 1 2 3 """ for i in range(4): print(i) """ range(spodni_limit, horni_limit) vrací iterovatelný objekt čísel mezi limity vypíše: 4 5 6 7 """ for i in range(4, 8): print(i) """ Smyčka while se opakuje, dokud je podmínka splněna. vypíše: 0 1 2 3 """ x = 0 while x < 4: print(x) x += 1 # Zkrácený zápis x = x + 1. Pozor, žádné x++ neexisuje. # Výjimky lze ošetřit pomocí bloku try/except(/else/finally) try: # Pro vyhození výjimky použijte raise raise IndexError("Přistoupil jste k neexistujícímu prvku v seznamu.") except IndexError as e: print("Nastala chyba: {}".format(e)) # Vypíše: Nastala chyba: Přistoupil jste k neexistujícímu prvku v seznamu. except (TypeError, NameError): # Více výjimek lze zachytit najednou pass # Pass znamená nedělej nic - nepříliš vhodný způsob ošetření chyb else: # Volitelný blok else musí být až za bloky except print("OK!") # Vypíše OK! v případě, že nenastala žádná výjimka finally: # Blok finally se spustí nakonec za všech okolností print("Uvolníme zdroje, uzavřeme soubory...") # Místo try/finally lze použít with pro automatické uvolnění zdrojů with open("soubor.txt") as soubor: for radka in soubor: print(radka) # Python běžně používá iterovatelné objekty, což je prakticky cokoliv, # co lze považovat za sekvenci. Například to, co vrací metoda range(), # nebo otevřený soubor, jsou iterovatelné objekty. slovnik = {"jedna": 1, "dva": 2, "tři": 3} iterovatelny_objekt = slovnik.keys() print(iterovatelny_objekt) # => dict_keys(["jedna", "dva", "tři"]). Toto je iterovatelný objekt. # Můžeme použít cyklus for na jeho projití for klic in iterovatelny_objekt: print(klic) # vypíše postupně: jedna, dva, tři # Ale nelze přistupovat k prvkům pod jejich indexem iterovatelny_objekt[1] # Vyhodí TypeError # Všechny položky iterovatelného objektu lze získat jako seznam pomocí list() list(slovnik.keys()) # => ["jedna", "dva", "tři"] # Z iterovatelného objektu lze vytvořit iterátor iterator = iter(iterovatelny_objekt) # Iterátor je objekt, který si pamatuje stav v rámci svého iterovatelného objektu # Další hodnotu dostaneme voláním next() next(iterator) # => "jedna" # Iterátor si udržuje svůj stav v mezi jednotlivými voláními next() next(iterator) # => "dva" next(iterator) # => "tři" # Jakmile interátor vrátí všechna svá data, vyhodí výjimku StopIteration next(iterator) # Vyhodí StopIteration #################################################### ## 4. Funkce #################################################### # Pro vytvoření nové funkce použijte klíčové slovo def def secist(x, y): print("x je {} a y je {}".format(x, y)) return x + y # Hodnoty se vrací pomocí return # Volání funkce s parametry secist(5, 6) # => Vypíše "x je 5 a y je 6" a vrátí 11 # Jiný způsob, jak volat funkci, je použít pojmenované argumenty secist(y=6, x=5) # Pojmenované argumenty můžete předat v libovolném pořadí # Lze definovat funkce s proměnným počtem (pozičních) argumentů def vrat_argumenty(*argumenty): return argumenty vrat_argumenty(1, 2, 3) # => (1, 2, 3) # Lze definovat také funkce s proměnným počtem pojmenovaných argumentů def vrat_pojmenovane_argumenty(**pojmenovane_argumenty): return pojmenovane_argumenty vrat_pojmenovane_argumenty(kdo="se bojí", nesmi="do lesa") # => {"kdo": "se bojí", "nesmi": "do lesa"} # Pokud chcete, lze použít obojí najednou # Konvence je používat pro tyto účely názvy *args a **kwargs def vypis_vse(*args, **kwargs): print(args, kwargs) # print() vypíše všechny své parametry oddělené mezerou vypis_vse(1, 2, a=3, b=4) # Vypíše: (1, 2) {"a": 3, "b": 4} # * nebo ** lze použít k rozbalení N-tic nebo slovníků! ntice = (1, 2, 3, 4) slovnik = {"a": 3, "b": 4} vypis_vse(ntice) # Vyhodnotí se jako vypis_vse((1, 2, 3, 4)) – jeden parametr, N-tice vypis_vse(*ntice) # Vyhodnotí se jako vypis_vse(1, 2, 3, 4) vypis_vse(**slovnik) # Vyhodnotí se jako vypis_vse(a=3, b=4) vypis_vse(*ntice, **slovnik) # Vyhodnotí se jako vypis_vse(1, 2, 3, 4, a=3, b=4) # Viditelnost proměnných - vytvořme si globální proměnnou x x = 5 def nastavX(cislo): # Lokální proměnná x překryje globální x x = cislo # => 43 print(x) # => 43 def nastavGlobalniX(cislo): global x print(x) # => 5 x = cislo # Nastaví globální proměnnou x na 6 print(x) # => 6 nastavX(43) nastavGlobalniX(6) # Funkce jsou first-class objekty def vyrobit_scitacku(pricitane_cislo): def scitacka(x): return x + pricitane_cislo return scitacka pricist_10 = vyrobit_scitacku(10) pricist_10(3) # => 13 # Klíčové slovo lambda vytvoří anonymní funkci (lambda parametr: parametr > 2)(3) # => True # Lze použít funkce map() a filter() z funkcionálního programování map(pricist_10, [1, 2, 3]) # => - iterovatelný objekt s obsahem: [11, 12, 13] filter(lambda x: x > 5, [3, 4, 5, 6, 7]) # => - iterovatelný objekt s obsahem: [6, 7] # S generátorovou notací lze dosáhnout podobných výsledků, ale vrací seznam [pricist_10(i) for i in [1, 2, 3]] # => [11, 12, 13] [x for x in [3, 4, 5, 6, 7] if x > 5] # => [6, 7] # Generátorová notace funguje i pro slovníky {x: x**2 for x in range(1, 5)} # => {1: 1, 2: 4, 3: 9, 4: 16} # A také pro množiny {pismeno for pismeno in "abeceda"} # => {"d", "a", "c", "e", "b"} #################################################### ## 5. Třídy #################################################### # Třída Clovek je potomkem (dědí od) třídy object class Clovek(object): # Atribut třídy - je sdílený všemi instancemi druh = "H. sapiens" # Toto je kostruktor. Je volán, když vytváříme instanci třídy. Dvě # podtržítka na začátku a na konci značí, že se jedná o atribut nebo # objekt využívaný Pythonem ke speciálním účelům, ale můžete sami # definovat jeho chování. Metody jako __init__, __str__, __repr__ # a další se nazývají "magické metody". Nikdy nepoužívejte toto # speciální pojmenování pro běžné metody. def __init__(self, jmeno): # Přiřazení parametru do atributu instance jmeno self.jmeno = jmeno # Metoda instance - všechny metody instance mají "self" jako první parametr def rekni(self, hlaska): return "{jmeno}: {hlaska}".format(jmeno=self.jmeno, hlaska=hlaska) # Metoda třídy - sdílená všemi instancemi # Dostává jako první parametr třídu, na které je volána @classmethod def vrat_druh(cls): return cls.druh # Statická metoda je volána bez reference na třídu nebo instanci @staticmethod def odkaslej_si(): return "*ehm*" # Vytvoření instance d = Clovek(jmeno="David") a = Clovek("Adéla") print(d.rekni("ahoj")) # Vypíše: "David: ahoj" print(a.rekni("nazdar")) # Vypíše: "Adéla: nazdar" # Volání třídní metody d.vrat_druh() # => "H. sapiens" # Změna atributu třídy Clovek.druh = "H. neanderthalensis" d.vrat_druh() # => "H. neanderthalensis" a.vrat_druh() # => "H. neanderthalensis" # Volání statické metody Clovek.odkaslej_si() # => "*ehm*" #################################################### ## 6. Moduly #################################################### # Lze importovat moduly import math print(math.sqrt(16.0)) # => 4 # Lze také importovat pouze vybrané funkce z modulu from math import ceil, floor print(ceil(3.7)) # => 4.0 print(floor(3.7)) # => 3.0 # Můžete také importovat všechny funkce z modulu, ale radši to nedělejte from math import * # Můžete si přejmenovat modul při jeho importu import math as m math.sqrt(16) == m.sqrt(16) # => True # Modul v Pythonu není nic jiného, než obyčejný soubor .py # Můžete si napsat vlastní a prostě ho importovat podle jména from muj_modul import moje_funkce # Nyní vyhodí ImportError - muj_modul neexistuje # Funkcí dir() lze zjistit, co modul obsahuje import math dir(math) #################################################### ## 7. Pokročilé #################################################### # Generátory jsou funkce, které místo return obsahují yield def nasobicka_2(sekvence): for i in sekvence: yield 2 * i # Generátor generuje hodnoty postupně, jak jsou potřeba. Místo toho, aby vrátil # celou sekvenci s prvky vynásobenými dvěma, provádí jeden výpočet v každé iteraci. # To znamená, že čísla větší než 15 se v metodě nasobicka_2 vůbec nezpracují. # Funkce range() je také generátor - vytváření seznamu 900000000 prvků by zabralo # hodně času i paměti, proto se místo toho čísla generují postupně. for i in nasobicka_2(range(900000000)): print(i) # Vypíše čísla 0, 2, 4, 6, 8, ... 30 if i >= 30: break # Dekorátory jsou funkce, které se používají pro obalení jiné funkce, čímž mohou # přidávat nebo měnit její stávající chování. Funkci dostávají jako parametr # a typicky místo ní vrací jinou, která uvnitř volá tu původní. def nekolikrat(puvodni_funkce): def opakovaci_funkce(*args, **kwargs): for i in range(3): puvodni_funkce(*args, **kwargs) return opakovaci_funkce @nekolikrat def pozdrav(jmeno): print("Měj se {}!".format(jmeno)) pozdrav("Pepo") # Vypíše 3x: Měj se Pepo! ``` ## Co dál? Spoustu odkazů na české i anglické materiály najdete na [webu české Python komunity] (http://python.cz/). Můžete také přijít na Pyvo, kde to společně probereme. --- language: sass filename: learnsass-cz.scss contributors: - ["Laura Kyle", "https://github.com/LauraNK"] - ["Sean Corrales", "https://github.com/droidenator"] translators: - ["Michal Martinek", "https://github.com/MichalMartinek"] lang: cs-cz --- Sass je rozšíření jazyka CSS, který přidává nové vlastnosti jako proměnné, zanořování, mixiny a další. Sass (a další preprocesory, jako [Less](http://lesscss.org/)) pomáhají vývojářům psát udržovatelný a neopakující (DRY) kód. Sass nabízí dvě možnosti syntaxe. SCSS, které je stejná jako CSS, akorát obsahuje nové vlastnosti Sassu. Nebo Sass, který používá odsazení místo složených závorek a středníků. Tento tutoriál bude používat syntaxi CSS. Pokud jste již obeznámeni s CSS3, budete schopni používat Sass relativně rychle. Nezprostředkovává nějaké úplně nové stylové možnosti, spíše nátroje, jak psát Vás CSS kód více efektivně, udržitelně a jednoduše. ```scss //Jednořádkové komentáře jsou ze Sassu při kompilaci vymazány /*Víceřádkové komentáře jsou naopak zachovány */ /*Proměnné ==============================*/ /* Můžete uložit CSS hodnotu (jako třeba barvu) do proměnné. Použijte symbol '$' k jejímu vytvoření. */ $hlavni-barva: #A3A4FF; $sekundarni-barva: #51527F; $body-font: 'Roboto', sans-serif; /* Můžete používat proměnné napříč vaším souborem. Teď, když chcete změnit barvu, stačí ji změnit pouze jednou.*/ body { background-color: $hlavni-barva; color: $sekundarni-barva; font-family: $body-font; } /* Toto se zkompiluje do: */ body { background-color: #A3A4FF; color: #51527F; font-family: 'Roboto', sans-serif; } /* Toto je o hodně více praktické, než měnit každý výskyt barvy. */ /*Mixiny ==============================*/ /* Pokud zjistíte, že píšete kód pro více než jeden element, můžete jej uložit do mixinu. Použijte '@mixin' direktivu, plus jméno vašeho mixinu.*/ @mixin na-stred { display: block; margin-left: auto; margin-right: auto; left: 0; right: 0; } /* Mixin vložíte pomocí '@include' a jména mixinu */ div { @include na-stred; background-color: $hlavni-barva; } /*Což se zkompiluje do: */ div { display: block; margin-left: auto; margin-right: auto; left: 0; right: 0; background-color: #A3A4FF; } /* Můžete využít mixiny i třeba pro takovéto ušetření práce: */ @mixin velikost($sirka, $vyska) { width: $sirka; height: $vyska; } /*Stačí vložit argumenty: */ .obdelnik { @include velikost(100px, 60px); } .ctverec { @include velikost(40px, 40px); } /* Toto se zkompiluje do: */ .obdelnik { width: 100px; height: 60px; } .ctverec { width: 40px; height: 40px; } /*Funkce ==============================*/ /* Sass obsahuje funkce, které vám pomůžou splnit různé úkoly. */ /* Funkce se spouštějí pomocí jejich jména, které následuje seznam argumentů uzavřený v kulatých závorkách. */ body { width: round(10.25px); } .footer { background-color: fade_out(#000000, 0.25) } /* Se zkompiluje do: */ body { width: 10px; } .footer { background-color: rgba(0, 0, 0, 0.75); } /* Můžete také definovat vlastní funkce. Funkce jsou velmi podobné mixinům. Když se snažíte vybrat mezi funkcí a mixinem, mějte na paměti, že mixiny jsou lepší pro generování CSS kódu, zatímco funkce jsou lepší pro logiku. Příklady ze sekce Matematické operátory jsou skvělí kandidáti na znovupoužitelné funkce. */ /* Tato funkce vrací poměr k velikosti rodiče v procentech. @function vypocitat-pomer($velikost, $velikost-rodice) { @return $velikost / $velikost-rodice * 100%; } $hlavni obsah: vypocitat-pomer(600px, 960px); .hlavni-obsah { width: $hlavni-obsah; } .sloupec { width: vypocitat-pomer(300px, 960px); } /* Zkompiluje do: */ .hlavni-obsah { width: 62.5%; } .sloupec { width: 31.25%; } /*Dědění ==============================*/ /*Dědění je způsob jak používat vlastnosti pro jeden selektor ve druhém. */ .oznameni { @include velikost(5em, 5em); border: 5px solid $sekundarni-barva; } .oznameni-uspech { @extend .oznameni; border-color: #22df56; } /* Zkompiluje do: */ .oznameni, .oznameni-uspech { width: 5em; height: 5em; border: 5px solid #51527F; } .oznameni-uspech { border-color: #22df56; } /* Dědění CSS výrazů je preferováno před vytvořením mixinu kvůli způsobu, jakým způsobem Sass dává dohromady třídy, které sdílejí stejný kód. Kdyby to bylo udělané pomocí mixinu, tak výška, šířka, rámeček by byl v každém výrazu, který by volal mixin. I když tohle neovlivní vaše workflow, přidá to kód navíc do souborů. */ /*Zanořování ==============================*/ /*Sass vám umožňuje zanořovat selektory do selektorů */ ul { list-style-type: none; margin-top: 2em; li { background-color: #FF0000; } } /* '&' nahradí rodičovský element. */ /* Můžete také zanořovat pseudo třídy. */ /* Pamatujte, že moc velké zanoření do hloubky snižuje čitelnost. Doporučuje se používat maximálně trojité zanoření. Na příklad: */ ul { list-style-type: none; margin-top: 2em; li { background-color: red; &:hover { background-color: blue; } a { color: white; } } } /* Zkompiluje do: */ ul { list-style-type: none; margin-top: 2em; } ul li { background-color: red; } ul li:hover { background-color: blue; } ul li a { color: white; } /*Částečné soubory a importy ==============================*/ /* Sass umožňuje vytvářet částečné soubory. Tyto soubory pomahájí udržovat váš kód modulární. Tyto soubory by měli začínat vždy '_', např. _reset.css. Částečné soubory se nepřevádí do CSS. */ /* Toto je kód, který si uložíme do souboru _reset.css */ html, body, ul, ol { margin: 0; padding: 0; } /* Sass obsahuje @import, které může být použit pro import částečných souborů. Toto se liší od klasického CSS @import, který dělá HTTP požadavek na stáhnutí souboru. Sass vezme importovaný soubor a vloží ho do kompilovaného kódu. */ @import 'reset'; body { font-size: 16px; font-family: Helvetica, Arial, Sans-serif; } /* Zkompiluje do: */ html, body, ul, ol { margin: 0; padding: 0; } body { font-size: 16px; font-family: Helvetica, Arial, Sans-serif; } /*Zástupné selektory ==============================*/ /* Zástupné selektory jsou užitečné, když vytváříte CSS výraz, ze kterého chcete později dědit. Když chcete vytvořit výraz, ze kterého je možné pouze dědit pomocí @extend, vytvořte zástupný selektor s CSS výrazem. Ten začíná symbolem '%' místo '.' nebo '#'. Tyto výrazy se neobjeví ve výsledném CSS */ %okno-obsahu { font-size: 14px; padding: 10px; color: #000; border-radius: 4px; } .okno-zpravy { @extend %okno-obsahu; background-color: #0000ff; } /* Zkompiluje do: */ .okno-zpravy { font-size: 14px; padding: 10px; color: #000; border-radius: 4px; } .okno-zpravy { background-color: #0000ff; } /*Matematické operace ==============================*/ /* Sass obsahuje následující operátory: +, -, *, /, and %. Tyto operátory můžou být velmi užitečné pro počítání hodnot přímo ve vašem souboru Sass. Níže je příklad, jak udělat jednoduchý dvousloupcový layout. */ $oblast-obsahu: 960px; $hlavni-obsah: 600px; $vedlejsi-sloupec: 300px; $obsah-velikost: $hlavni-obsah / $oblast-obsahu * 100%; $vedlejsi-sloupec-velikost: $vedlejsi-sloupec / $oblast-obsahu * 100%; $zbytek-velikost: 100% - ($main-size + $vedlejsi-sloupec-size); body { width: 100%; } .hlavni-obsah { width: $obsah-velikost; } .vedlejsi-sloupec { width: $vedlejsi-sloupec-velikost; } .zbytek { width: $zbytek-velikost; } /* Zkompiluje do: */ body { width: 100%; } .hlavni-obsah { width: 62.5%; } .vedlejsi-sloupec { width: 31.25%; } .gutter { width: 6.25%; } ``` ## SASS nebo Sass? Divili jste se někdy, jestli je Sass zkratka nebo ne? Pravděpodobně ne, ale řeknu vám to stejně. Jméno tohoto jazyka je slovo, "Sass", a ne zkratka. Protože to lidé konstatně píší jako "SASS", nazval ho autor jazyka jako "Syntactically Awesome StyleSheets" (Syntaktický úžasně styly). ## Procvičování Sassu Pokud si chcete hrát se Sassem ve vašem prohlížeči, navštivte [SassMeister](http://sassmeister.com/). Můžete používát oba dva způsoby zápisu, stačí si vybrat v nastavení SCSS nebo SASS. ## Kompatibilita Sass může být použit v jakémkoliv projektu, jakmile máte program, pomocí kterého ho zkompilujete do CSS. Pokud si chcete ověřit, že CSS, které Sass produkuje je kompatibilní s prohlížeči: [QuirksMode CSS](http://www.quirksmode.org/css/) a [CanIUse](http://caniuse.com) jsou skvělé stránky pro kontrolu kompatibility. ## Kam dál? * [Oficiální dokumentace](http://sass-lang.com/documentation/file.SASS_REFERENCE.html) * [The Sass Way](http://thesassway.com/) obsahuje tutoriál a řadu skvělých článků --- language: c# contributors: - ["Irfan Charania", "https://github.com/irfancharania"] - ["Max Yankov", "https://github.com/golergka"] - ["Melvyn Laïly", "http://x2a.yt"] - ["Shaun McCarthy", "http://www.shaunmccarthy.com"] - ["Wouter Van Schandevijl", "http://github.com/laoujin"] - ["Jo Pearce", "http://github.com/jdpearce"] - ["Chris Zimmerman", "https://github.com/chriszimmerman"] - ["Shawn McGuire", "https://github.com/bigbash"] filename: LearnCSharp.cs --- C# is an elegant and type-safe object-oriented language that enables developers to build a variety of secure and robust applications that run on the .NET Framework. [Read more here.](http://msdn.microsoft.com/en-us/library/vstudio/z1zx9t92.aspx) ```c# // Single-line comments start with // /* Multi-line comments look like this */ /// /// This is an XML documentation comment which can be used to generate external /// documentation or provide context help within an IDE /// /// This is some parameter documentation for firstParam /// Information on the returned value of a function //public void MethodOrClassOrOtherWithParsableHelp(string firstParam) {} // Specify the namespaces this source code will be using // The namespaces below are all part of the standard .NET Framework Class Library using System; using System.Collections.Generic; using System.Dynamic; using System.Linq; using System.Net; using System.Threading.Tasks; using System.IO; // But this one is not: using System.Data.Entity; // In order to be able to use it, you need to add a dll reference // This can be done with the NuGet package manager: `Install-Package EntityFramework` // Namespaces define scope to organize code into "packages" or "modules" // Using this code from another source file: using Learning.CSharp; namespace Learning.CSharp { // Each .cs file should at least contain a class with the same name as the file. // You're allowed to do otherwise, but shouldn't for sanity. public class LearnCSharp { // BASIC SYNTAX - skip to INTERESTING FEATURES if you have used Java or C++ before public static void Syntax() { // Use Console.WriteLine to print lines Console.WriteLine("Hello World"); Console.WriteLine( "Integer: " + 10 + " Double: " + 3.14 + " Boolean: " + true); // To print without a new line, use Console.Write Console.Write("Hello "); Console.Write("World"); /////////////////////////////////////////////////// // Types & Variables // // Declare a variable using /////////////////////////////////////////////////// // Sbyte - Signed 8-bit integer // (-128 <= sbyte <= 127) sbyte fooSbyte = 100; // Byte - Unsigned 8-bit integer // (0 <= byte <= 255) byte fooByte = 100; // Short - 16-bit integer // Signed - (-32,768 <= short <= 32,767) // Unsigned - (0 <= ushort <= 65,535) short fooShort = 10000; ushort fooUshort = 10000; // Integer - 32-bit integer int fooInt = 1; // (-2,147,483,648 <= int <= 2,147,483,647) uint fooUint = 1; // (0 <= uint <= 4,294,967,295) // Long - 64-bit integer long fooLong = 100000L; // (-9,223,372,036,854,775,808 <= long <= 9,223,372,036,854,775,807) ulong fooUlong = 100000L; // (0 <= ulong <= 18,446,744,073,709,551,615) // Numbers default to being int or uint depending on size. // L is used to denote that this variable value is of type long or ulong // Double - Double-precision 64-bit IEEE 754 Floating Point double fooDouble = 123.4; // Precision: 15-16 digits // Float - Single-precision 32-bit IEEE 754 Floating Point float fooFloat = 234.5f; // Precision: 7 digits // f is used to denote that this variable value is of type float // Decimal - a 128-bits data type, with more precision than other floating-point types, // suited for financial and monetary calculations decimal fooDecimal = 150.3m; // Boolean - true & false bool fooBoolean = true; // or false // Char - A single 16-bit Unicode character char fooChar = 'A'; // Strings -- unlike the previous base types which are all value types, // a string is a reference type. That is, you can set it to null string fooString = "\"escape\" quotes and add \n (new lines) and \t (tabs)"; Console.WriteLine(fooString); // You can access each character of the string with an indexer: char charFromString = fooString[1]; // => 'e' // Strings are immutable: you can't do fooString[1] = 'X'; // Compare strings with current culture, ignoring case string.Compare(fooString, "x", StringComparison.CurrentCultureIgnoreCase); // Formatting, based on sprintf string fooFs = string.Format("Check Check, {0} {1}, {0} {1:0.0}", 1, 2); // Dates & Formatting DateTime fooDate = DateTime.Now; Console.WriteLine(fooDate.ToString("hh:mm, dd MMM yyyy")); // You can split a string over two lines with the @ symbol. To escape " use "" string bazString = @"Here's some stuff on a new line! ""Wow!"", the masses cried"; // Use const or read-only to make a variable immutable // const values are calculated at compile time const int HoursWorkPerWeek = 9001; /////////////////////////////////////////////////// // Data Structures /////////////////////////////////////////////////// // Arrays - zero indexed // The array size must be decided upon declaration // The format for declaring an array is follows: // [] = new []; int[] intArray = new int[10]; // Another way to declare & initialize an array int[] y = { 9000, 1000, 1337 }; // Indexing an array - Accessing an element Console.WriteLine("intArray @ 0: " + intArray[0]); // Arrays are mutable. intArray[1] = 1; // Lists // Lists are used more frequently than arrays as they are more flexible // The format for declaring a list is follows: // List = new List(); List intList = new List(); List stringList = new List(); List z = new List { 9000, 1000, 1337 }; // initialize // The <> are for generics - Check out the cool stuff section // Lists don't default to a value; // A value must be added before accessing the index intList.Add(1); Console.WriteLine("intList @ 0: " + intList[0]); // Others data structures to check out: // Stack/Queue // Dictionary (an implementation of a hash map) // HashSet // Read-only Collections // Tuple (.Net 4+) /////////////////////////////////////// // Operators /////////////////////////////////////// Console.WriteLine("\n->Operators"); int i1 = 1, i2 = 2; // Shorthand for multiple declarations // Arithmetic is straightforward Console.WriteLine(i1 + i2 - i1 * 3 / 7); // => 3 // Modulo Console.WriteLine("11%3 = " + (11 % 3)); // => 2 // Comparison operators Console.WriteLine("3 == 2? " + (3 == 2)); // => false Console.WriteLine("3 != 2? " + (3 != 2)); // => true Console.WriteLine("3 > 2? " + (3 > 2)); // => true Console.WriteLine("3 < 2? " + (3 < 2)); // => false Console.WriteLine("2 <= 2? " + (2 <= 2)); // => true Console.WriteLine("2 >= 2? " + (2 >= 2)); // => true // Bitwise operators! /* ~ Unary bitwise complement << Signed left shift >> Signed right shift & Bitwise AND ^ Bitwise exclusive OR | Bitwise inclusive OR */ // Incrementations int i = 0; Console.WriteLine("\n->Inc/Dec-rementation"); Console.WriteLine(i++); //Prints "0", i = 1. Post-Incrementation Console.WriteLine(++i); //Prints "2", i = 2. Pre-Incrementation Console.WriteLine(i--); //Prints "2", i = 1. Post-Decrementation Console.WriteLine(--i); //Prints "0", i = 0. Pre-Decrementation /////////////////////////////////////// // Control Structures /////////////////////////////////////// Console.WriteLine("\n->Control Structures"); // If statements are c-like int j = 10; if (j == 10) { Console.WriteLine("I get printed"); } else if (j > 10) { Console.WriteLine("I don't"); } else { Console.WriteLine("I also don't"); } // Ternary operators // A simple if/else can be written as follows // ? : int toCompare = 17; string isTrue = toCompare == 17 ? "True" : "False"; // While loop int fooWhile = 0; while (fooWhile < 100) { //Iterated 100 times, fooWhile 0->99 fooWhile++; } // Do While Loop int fooDoWhile = 0; do { // Start iteration 100 times, fooDoWhile 0->99 if (false) continue; // skip the current iteration fooDoWhile++; if (fooDoWhile == 50) break; // breaks from the loop completely } while (fooDoWhile < 100); //for loop structure => for(; ; ) for (int fooFor = 0; fooFor < 10; fooFor++) { //Iterated 10 times, fooFor 0->9 } // For Each Loop // foreach loop structure => foreach( in ) // The foreach loop loops over any object implementing IEnumerable or IEnumerable // All the collection types (Array, List, Dictionary...) in the .Net framework // implement one or both of these interfaces. // (The ToCharArray() could be removed, because a string also implements IEnumerable) foreach (char character in "Hello World".ToCharArray()) { //Iterated over all the characters in the string } // Switch Case // A switch works with the byte, short, char, and int data types. // It also works with enumerated types (discussed in Enum Types), // the String class, and a few special classes that wrap // primitive types: Character, Byte, Short, and Integer. int month = 3; string monthString; switch (month) { case 1: monthString = "January"; break; case 2: monthString = "February"; break; case 3: monthString = "March"; break; // You can assign more than one case to an action // But you can't add an action without a break before another case // (if you want to do this, you would have to explicitly add a goto case x case 6: case 7: case 8: monthString = "Summer time!!"; break; default: monthString = "Some other month"; break; } /////////////////////////////////////// // Converting Data Types And Typecasting /////////////////////////////////////// // Converting data // Convert String To Integer // this will throw a FormatException on failure int.Parse("123");//returns an integer version of "123" // try parse will default to type default on failure // in this case: 0 int tryInt; if (int.TryParse("123", out tryInt)) // Function is boolean Console.WriteLine(tryInt); // 123 // Convert Integer To String // Convert class has a number of methods to facilitate conversions Convert.ToString(123); // or tryInt.ToString(); // Casting // Cast decimal 15 to a int // and then implicitly cast to long long x = (int) 15M; } /////////////////////////////////////// // CLASSES - see definitions at end of file /////////////////////////////////////// public static void Classes() { // See Declaration of objects at end of file // Use new to instantiate a class Bicycle trek = new Bicycle(); // Call object methods trek.SpeedUp(3); // You should always use setter and getter methods trek.Cadence = 100; // ToString is a convention to display the value of this Object. Console.WriteLine("trek info: " + trek.Info()); // Instantiate a new Penny Farthing PennyFarthing funbike = new PennyFarthing(1, 10); Console.WriteLine("funbike info: " + funbike.Info()); Console.Read(); } // End main method // CONSOLE ENTRY A console application must have a main method as an entry point public static void Main(string[] args) { OtherInterestingFeatures(); } // // INTERESTING FEATURES // // DEFAULT METHOD SIGNATURES public // Visibility static // Allows for direct call on class without object int // Return Type, MethodSignatures( int maxCount, // First variable, expects an int int count = 0, // will default the value to 0 if not passed in int another = 3, params string[] otherParams // captures all other parameters passed to method ) { return -1; } // Methods can have the same name, as long as the signature is unique // A method that differs only in return type is not unique public static void MethodSignatures( ref int maxCount, // Pass by reference out int count) { //the argument passed in as 'count' will hold the value of 15 outside of this function count = 15; // out param must be assigned before control leaves the method } // GENERICS // The classes for TKey and TValue is specified by the user calling this function. // This method emulates the SetDefault of Python public static TValue SetDefault( IDictionary dictionary, TKey key, TValue defaultItem) { TValue result; if (!dictionary.TryGetValue(key, out result)) return dictionary[key] = defaultItem; return result; } // You can narrow down the objects that are passed in public static void IterateAndPrint(T toPrint) where T: IEnumerable { // We can iterate, since T is a IEnumerable foreach (var item in toPrint) // Item is an int Console.WriteLine(item.ToString()); } // YIELD // Usage of the "yield" keyword indicates that the method it appears in is an Iterator // (this means you can use it in a foreach loop) public static IEnumerable YieldCounter(int limit = 10) { for (var i = 0; i < limit; i++) yield return i; } // which you would call like this : public static void PrintYieldCounterToConsole() { foreach (var counter in YieldCounter()) Console.WriteLine(counter); } // you can use more than one "yield return" in a method public static IEnumerable ManyYieldCounter() { yield return 0; yield return 1; yield return 2; yield return 3; } // you can also use "yield break" to stop the Iterator // this method would only return half of the values from 0 to limit. public static IEnumerable YieldCounterWithBreak(int limit = 10) { for (var i = 0; i < limit; i++) { if (i > limit/2) yield break; yield return i; } } public static void OtherInterestingFeatures() { // OPTIONAL PARAMETERS MethodSignatures(3, 1, 3, "Some", "Extra", "Strings"); MethodSignatures(3, another: 3); // explicitly set a parameter, skipping optional ones // BY REF AND OUT PARAMETERS int maxCount = 0, count; // ref params must have value MethodSignatures(ref maxCount, out count); // EXTENSION METHODS int i = 3; i.Print(); // Defined below // NULLABLE TYPES - great for database interaction / return values // any value type (i.e. not a class) can be made nullable by suffixing a ? // ? = int? nullable = null; // short hand for Nullable Console.WriteLine("Nullable variable: " + nullable); bool hasValue = nullable.HasValue; // true if not null // ?? is syntactic sugar for specifying default value (coalesce) // in case variable is null int notNullable = nullable ?? 0; // 0 // ?. is an operator for null-propagation - a shorthand way of checking for null nullable?.Print(); // Use the Print() extension method if nullable isn't null // IMPLICITLY TYPED VARIABLES - you can let the compiler work out what the type is: var magic = "magic is a string, at compile time, so you still get type safety"; // magic = 9; will not work as magic is a string, not an int // GENERICS // var phonebook = new Dictionary() { {"Sarah", "212 555 5555"} // Add some entries to the phone book }; // Calling SETDEFAULT defined as a generic above Console.WriteLine(SetDefault(phonebook, "Shaun", "No Phone")); // No Phone // nb, you don't need to specify the TKey and TValue since they can be // derived implicitly Console.WriteLine(SetDefault(phonebook, "Sarah", "No Phone")); // 212 555 5555 // LAMBDA EXPRESSIONS - allow you to write code in line Func square = (x) => x * x; // Last T item is the return value Console.WriteLine(square(3)); // 9 // ERROR HANDLING - coping with an uncertain world try { var funBike = PennyFarthing.CreateWithGears(6); // will no longer execute because CreateWithGears throws an exception string some = ""; if (true) some = null; some.ToLower(); // throws a NullReferenceException } catch (NotSupportedException) { Console.WriteLine("Not so much fun now!"); } catch (Exception ex) // catch all other exceptions { throw new ApplicationException("It hit the fan", ex); // throw; // A rethrow that preserves the callstack } // catch { } // catch-all without capturing the Exception finally { // executes after try or catch } // DISPOSABLE RESOURCES MANAGEMENT - let you handle unmanaged resources easily. // Most of objects that access unmanaged resources (file handle, device contexts, etc.) // implement the IDisposable interface. The using statement takes care of // cleaning those IDisposable objects for you. using (StreamWriter writer = new StreamWriter("log.txt")) { writer.WriteLine("Nothing suspicious here"); // At the end of scope, resources will be released. // Even if an exception is thrown. } // PARALLEL FRAMEWORK // http://blogs.msdn.com/b/csharpfaq/archive/2010/06/01/parallel-programming-in-net-framework-4-getting-started.aspx var words = new List {"dog", "cat", "horse", "pony"}; Parallel.ForEach(words, new ParallelOptions() { MaxDegreeOfParallelism = 4 }, word => { Console.WriteLine(word); } ); //Running this will produce different outputs //since each thread finishes at different times. //Some example outputs are: //cat dog horse pony //dog horse pony cat // DYNAMIC OBJECTS (great for working with other languages) dynamic student = new ExpandoObject(); student.FirstName = "First Name"; // No need to define class first! // You can even add methods (returns a string, and takes in a string) student.Introduce = new Func( (introduceTo) => string.Format("Hey {0}, this is {1}", student.FirstName, introduceTo)); Console.WriteLine(student.Introduce("Beth")); // IQUERYABLE - almost all collections implement this, which gives you a lot of // very useful Map / Filter / Reduce style methods var bikes = new List(); bikes.Sort(); // Sorts the array bikes.Sort((b1, b2) => b1.Wheels.CompareTo(b2.Wheels)); // Sorts based on wheels var result = bikes .Where(b => b.Wheels > 3) // Filters - chainable (returns IQueryable of previous type) .Where(b => b.IsBroken && b.HasTassles) .Select(b => b.ToString()); // Map - we only this selects, so result is a IQueryable var sum = bikes.Sum(b => b.Wheels); // Reduce - sums all the wheels in the collection // Create a list of IMPLICIT objects based on some parameters of the bike var bikeSummaries = bikes.Select(b=>new { Name = b.Name, IsAwesome = !b.IsBroken && b.HasTassles }); // Hard to show here, but you get type ahead completion since the compiler can implicitly work // out the types above! foreach (var bikeSummary in bikeSummaries.Where(b => b.IsAwesome)) Console.WriteLine(bikeSummary.Name); // ASPARALLEL // And this is where things get wicked - combine linq and parallel operations var threeWheelers = bikes.AsParallel().Where(b => b.Wheels == 3).Select(b => b.Name); // this will happen in parallel! Threads will automagically be spun up and the // results divvied amongst them! Amazing for large datasets when you have lots of // cores // LINQ - maps a store to IQueryable objects, with delayed execution // e.g. LinqToSql - maps to a database, LinqToXml maps to an xml document var db = new BikeRepository(); // execution is delayed, which is great when querying a database var filter = db.Bikes.Where(b => b.HasTassles); // no query run if (42 > 6) // You can keep adding filters, even conditionally - great for "advanced search" functionality filter = filter.Where(b => b.IsBroken); // no query run var query = filter .OrderBy(b => b.Wheels) .ThenBy(b => b.Name) .Select(b => b.Name); // still no query run // Now the query runs, but opens a reader, so only populates as you iterate through foreach (string bike in query) Console.WriteLine(result); } } // End LearnCSharp class // You can include other classes in a .cs file public static class Extensions { // EXTENSION METHODS public static void Print(this object obj) { Console.WriteLine(obj.ToString()); } } // Class Declaration Syntax: // class { // //data fields, constructors, functions all inside. // //functions are called as methods in Java. // } public class Bicycle { // Bicycle's Fields/Variables public int Cadence // Public: Can be accessed from anywhere { get // get - define a method to retrieve the property { return _cadence; } set // set - define a method to set a property { _cadence = value; // Value is the value passed in to the setter } } private int _cadence; protected virtual int Gear // Protected: Accessible from the class and subclasses { get; // creates an auto property so you don't need a member field set; } internal int Wheels // Internal: Accessible from within the assembly { get; private set; // You can set modifiers on the get/set methods } int _speed; // Everything is private by default: Only accessible from within this class. // can also use keyword private public string Name { get; set; } // Properties also have a special syntax for when you want a readonly property // that simply returns the result of an expression public string LongName => Name + " " + _speed + " speed"; // Enum is a value type that consists of a set of named constants // It is really just mapping a name to a value (an int, unless specified otherwise). // The approved types for an enum are byte, sbyte, short, ushort, int, uint, long, or ulong. // An enum can't contain the same value twice. public enum BikeBrand { AIST, BMC, Electra = 42, //you can explicitly set a value to a name Gitane // 43 } // We defined this type inside a Bicycle class, so it is a nested type // Code outside of this class should reference this type as Bicycle.Brand public BikeBrand Brand; // After declaring an enum type, we can declare the field of this type // Decorate an enum with the FlagsAttribute to indicate that multiple values can be switched on // Any class derived from Attribute can be used to decorate types, methods, parameters etc // Bitwise operators & and | can be used to perform and/or operations [Flags] public enum BikeAccessories { None = 0, Bell = 1, MudGuards = 2, // need to set the values manually! Racks = 4, Lights = 8, FullPackage = Bell | MudGuards | Racks | Lights } // Usage: aBike.Accessories.HasFlag(Bicycle.BikeAccessories.Bell) // Before .NET 4: (aBike.Accessories & Bicycle.BikeAccessories.Bell) == Bicycle.BikeAccessories.Bell public BikeAccessories Accessories { get; set; } // Static members belong to the type itself rather than specific object. // You can access them without a reference to any object: // Console.WriteLine("Bicycles created: " + Bicycle.bicyclesCreated); public static int BicyclesCreated { get; set; } // readonly values are set at run time // they can only be assigned upon declaration or in a constructor readonly bool _hasCardsInSpokes = false; // read-only private // Constructors are a way of creating classes // This is a default constructor public Bicycle() { this.Gear = 1; // you can access members of the object with the keyword this Cadence = 50; // but you don't always need it _speed = 5; Name = "Bontrager"; Brand = BikeBrand.AIST; BicyclesCreated++; } // This is a specified constructor (it contains arguments) public Bicycle(int startCadence, int startSpeed, int startGear, string name, bool hasCardsInSpokes, BikeBrand brand) : base() // calls base first { Gear = startGear; Cadence = startCadence; _speed = startSpeed; Name = name; _hasCardsInSpokes = hasCardsInSpokes; Brand = brand; } // Constructors can be chained public Bicycle(int startCadence, int startSpeed, BikeBrand brand) : this(startCadence, startSpeed, 0, "big wheels", true, brand) { } // Function Syntax: // () // classes can implement getters and setters for their fields // or they can implement properties (this is the preferred way in C#) // Method parameters can have default values. // In this case, methods can be called with these parameters omitted public void SpeedUp(int increment = 1) { _speed += increment; } public void SlowDown(int decrement = 1) { _speed -= decrement; } // properties get/set values // when only data needs to be accessed, consider using properties. // properties may have either get or set, or both private bool _hasTassles; // private variable public bool HasTassles // public accessor { get { return _hasTassles; } set { _hasTassles = value; } } // You can also define an automatic property in one line // this syntax will create a backing field automatically. // You can set an access modifier on either the getter or the setter (or both) // to restrict its access: public bool IsBroken { get; private set; } // Properties can be auto-implemented public int FrameSize { get; // you are able to specify access modifiers for either get or set // this means only Bicycle class can call set on Framesize private set; } // It's also possible to define custom Indexers on objects. // All though this is not entirely useful in this example, you // could do bicycle[0] which returns "chris" to get the first passenger or // bicycle[1] = "lisa" to set the passenger. (of this apparent quattrocycle) private string[] passengers = { "chris", "phil", "darren", "regina" }; public string this[int i] { get { return passengers[i]; } set { passengers[i] = value; } } //Method to display the attribute values of this Object. public virtual string Info() { return "Gear: " + Gear + " Cadence: " + Cadence + " Speed: " + _speed + " Name: " + Name + " Cards in Spokes: " + (_hasCardsInSpokes ? "yes" : "no") + "\n------------------------------\n" ; } // Methods can also be static. It can be useful for helper methods public static bool DidWeCreateEnoughBicycles() { // Within a static method, we only can reference static class members return BicyclesCreated > 9000; } // If your class only needs static members, consider marking the class itself as static. } // end class Bicycle // PennyFarthing is a subclass of Bicycle class PennyFarthing : Bicycle { // (Penny Farthings are those bicycles with the big front wheel. // They have no gears.) // calling parent constructor public PennyFarthing(int startCadence, int startSpeed) : base(startCadence, startSpeed, 0, "PennyFarthing", true, BikeBrand.Electra) { } protected override int Gear { get { return 0; } set { throw new InvalidOperationException("You can't change gears on a PennyFarthing"); } } public static PennyFarthing CreateWithGears(int gears) { var penny = new PennyFarthing(1, 1); penny.Gear = gears; // Oops, can't do this! return penny; } public override string Info() { string result = "PennyFarthing bicycle "; result += base.ToString(); // Calling the base version of the method return result; } } // Interfaces only contain signatures of the members, without the implementation. interface IJumpable { void Jump(int meters); // all interface members are implicitly public } interface IBreakable { bool Broken { get; } // interfaces can contain properties as well as methods & events } // Classes can inherit only one other class, but can implement any amount of interfaces, // however the base class name must be the first in the list and all interfaces follow class MountainBike : Bicycle, IJumpable, IBreakable { int damage = 0; public void Jump(int meters) { damage += meters; } public bool Broken { get { return damage > 100; } } } /// /// Used to connect to DB for LinqToSql example. /// EntityFramework Code First is awesome (similar to Ruby's ActiveRecord, but bidirectional) /// http://msdn.microsoft.com/en-us/data/jj193542.aspx /// public class BikeRepository : DbContext { public BikeRepository() : base() { } public DbSet Bikes { get; set; } } // Classes can be split across multiple .cs files // A1.cs public partial class A { public static void A1() { Console.WriteLine("Method A1 in class A"); } } // A2.cs public partial class A { public static void A2() { Console.WriteLine("Method A2 in class A"); } } // Program using the partial class "A" public class Program { static void Main() { A.A1(); A.A2(); } } // String interpolation by prefixing the string with $ // and wrapping the expression you want to interpolate with { braces } public class Rectangle { public int Length { get; set; } public int Width { get; set; } } class Program { static void Main(string[] args) { Rectangle rect = new Rectangle { Length = 5, Width = 3 }; Console.WriteLine($"The length is {rect.Length} and the width is {rect.Width}"); } } // New C# 6 features class GlassBall : IJumpable, IBreakable { // Autoproperty initializers public int Damage { get; private set; } = 0; // Autoproperty initializers on getter-only properties public string Name { get; } = "Glass ball"; // Getter-only autoproperty that is initialized in constructor public string GenieName { get; } public GlassBall(string genieName = null) { GenieName = genieName; } public void Jump(int meters) { if (meters < 0) // New nameof() expression; compiler will check that the identifier exists // nameof(x) == "x" // Prevents e.g. parameter names changing but not updated in error messages throw new ArgumentException("Cannot jump negative amount!", nameof(meters)); Damage += meters; } // Expression-bodied properties ... public bool Broken => Damage > 100; // ... and methods public override string ToString() // Interpolated string => $"{Name}. Damage taken: {Damage}"; public string SummonGenie() // Null-conditional operators // x?.y will return null immediately if x is null; y is not evaluated => GenieName?.ToUpper(); } static class MagicService { private static bool LogException(Exception ex) { /* log exception somewhere */ return false; } public static bool CastSpell(string spell) { try { // Pretend we call API here throw new MagicServiceException("Spell failed", 42); // Spell succeeded return true; } // Only catch if Code is 42 i.e. spell failed catch(MagicServiceException ex) when (ex.Code == 42) { // Spell failed return false; } // Other exceptions, or MagicServiceException where Code is not 42 catch(Exception ex) when (LogException(ex)) { // Execution never reaches this block // The stack is not unwound } return false; // Note that catching a MagicServiceException and rethrowing if Code // is not 42 or 117 is different, as then the final catch-all block // will not catch the rethrown exception } } public class MagicServiceException : Exception { public int Code { get; } public MagicServiceException(string message, int code) : base(message) { Code = code; } } public static class PragmaWarning { // Obsolete attribute [Obsolete("Use NewMethod instead", false)] public static void ObsoleteMethod() { /* obsolete code */ } public static void NewMethod() { /* new code */ } public static void Main() { ObsoleteMethod(); // CS0618: 'ObsoleteMethod is obsolete: Use NewMethod instead' #pragma warning disable CS0618 ObsoleteMethod(); // no warning #pragma warning restore CS0618 ObsoleteMethod(); // CS0618: 'ObsoleteMethod is obsolete: Use NewMethod instead' } } } // End Namespace using System; // C# 6, static using using static System.Math; namespace Learning.More.CSharp { class StaticUsing { static void Main() { // Without a static using statement.. Console.WriteLine("The square root of 4 is {}.", Math.Sqrt(4)); // With one Console.WriteLine("The square root of 4 is {}.", Sqrt(4)); } } } using System; namespace Csharp7 { //New C# 7 Feature //Install Microsoft.Net.Compilers Latest from Nuget //Install System.ValueTuple Latest from Nuget class Program { static void Main(string[] args) { //Type 1 Declaration (string FirstName, string LastName) names1 = ("Peter", "Parker"); Console.WriteLine(names1.FirstName); //Type 2 Declaration var names2 = (First:"Peter", Last:"Parker"); Console.WriteLine(names2.Last); } } } ``` ## Topics Not Covered * Attributes * async/await * Web Development * ASP.NET MVC & WebApi (new) * ASP.NET Web Forms (old) * WebMatrix (tool) * Desktop Development * Windows Presentation Foundation (WPF) (new) * Winforms (old) ## Further Reading * [DotNetPerls](http://www.dotnetperls.com) * [C# in Depth](http://manning.com/skeet2) * [Programming C#](http://shop.oreilly.com/product/0636920024064.do) * [LINQ](http://shop.oreilly.com/product/9780596519254.do) * [MSDN Library](http://msdn.microsoft.com/en-us/library/618ayhy6.aspx) * [ASP.NET MVC Tutorials](http://www.asp.net/mvc/tutorials) * [ASP.NET Web Matrix Tutorials](http://www.asp.net/web-pages/tutorials) * [ASP.NET Web Forms Tutorials](http://www.asp.net/web-forms/tutorials) * [Windows Forms Programming in C#](http://www.amazon.com/Windows-Forms-Programming-Chris-Sells/dp/0321116208) * [C# Coding Conventions](http://msdn.microsoft.com/en-us/library/vstudio/ff926074.aspx) --- language: css contributors: - ["Mohammad Valipour", "https://github.com/mvalipour"] - ["Marco Scannadinari", "https://github.com/marcoms"] - ["Geoffrey Liu", "https://github.com/g-liu"] - ["Connor Shea", "https://github.com/connorshea"] - ["Deepanshu Utkarsh", "https://github.com/duci9y"] - ["Brett Taylor", "https://github.com/glutnix"] - ["Tyler Mumford", "https://tylermumford.com"] filename: learncss.css --- Web pages are built with HTML, which specifies the content of a page. CSS (Cascading Style Sheets) is a separate language which specifies a page's **appearance**. CSS code is made of static *rules*. Each rule takes one or more *selectors* and gives specific *values* to a number of visual *properties*. Those properties are then applied to the page elements indicated by the selectors. This guide has been written with CSS 2 in mind, which is extended by the new features of CSS 3. **NOTE:** Because CSS produces visual results, in order to learn it, you need to try everything in a CSS playground like [dabblet](http://dabblet.com/). The main focus of this article is on the syntax and some general tips. ## Syntax ```css /* comments appear inside slash-asterisk, just like this line! there are no "one-line comments"; this is the only comment style */ /* #################### ## SELECTORS #################### */ /* the selector is used to target an element on a page. */ selector { property: value; /* more properties...*/ } /* Here is an example element:
*/ /* You can target it using one of its CSS classes */ .class1 { } /* or both classes! */ .class1.class2 { } /* or its name */ div { } /* or its id */ #anID { } /* or using the fact that it has an attribute! */ [attr] { font-size:smaller; } /* or that the attribute has a specific value */ [attr='value'] { font-size:smaller; } /* starts with a value (CSS 3) */ [attr^='val'] { font-size:smaller; } /* or ends with a value (CSS 3) */ [attr$='ue'] { font-size:smaller; } /* or contains a value in a space-separated list */ [otherAttr~='foo'] { } [otherAttr~='bar'] { } /* or contains a value in a dash-separated list, e.g., "-" (U+002D) */ [otherAttr|='en'] { font-size:smaller; } /* You can combine different selectors to create a more focused selector. Don't put spaces between them. */ div.some-class[attr$='ue'] { } /* You can select an element which is a child of another element */ div.some-parent > .class-name { } /* or a descendant of another element. Children are the direct descendants of their parent element, only one level down the tree. Descendants can be any level down the tree. */ div.some-parent .class-name { } /* Warning: the same selector without a space has another meaning. Can you guess what? */ div.some-parent.class-name { } /* You may also select an element based on its adjacent sibling */ .i-am-just-before + .this-element { } /* or any sibling preceding it */ .i-am-any-element-before ~ .this-element { } /* There are some selectors called pseudo classes that can be used to select an element only when it is in a particular state */ /* for example, when the cursor hovers over an element */ selector:hover { } /* or a link has been visited */ selector:visited { } /* or hasn't been visited */ selected:link { } /* or an element is in focus */ selected:focus { } /* any element that is the first child of its parent */ selector:first-child {} /* any element that is the last child of its parent */ selector:last-child {} /* Just like pseudo classes, pseudo elements allow you to style certain parts of a document */ /* matches a virtual first child of the selected element */ selector::before {} /* matches a virtual last child of the selected element */ selector::after {} /* At appropriate places, an asterisk may be used as a wildcard to select every element */ * { } /* all elements */ .parent * { } /* all descendants */ .parent > * { } /* all children */ /* #################### ## PROPERTIES #################### */ selector { /* Units of length can be absolute or relative. */ /* Relative units */ width: 50%; /* percentage of parent element width */ font-size: 2em; /* multiples of element's original font-size */ font-size: 2rem; /* or the root element's font-size */ font-size: 2vw; /* multiples of 1% of the viewport's width (CSS 3) */ font-size: 2vh; /* or its height */ font-size: 2vmin; /* whichever of a vh or a vw is smaller */ font-size: 2vmax; /* or greater */ /* Absolute units */ width: 200px; /* pixels */ font-size: 20pt; /* points */ width: 5cm; /* centimeters */ min-width: 50mm; /* millimeters */ max-width: 5in; /* inches */ /* Colors */ color: #F6E; /* short hex format */ color: #FF66EE; /* long hex format */ color: tomato; /* a named color */ color: rgb(255, 255, 255); /* as rgb values */ color: rgb(10%, 20%, 50%); /* as rgb percentages */ color: rgba(255, 0, 0, 0.3); /* as rgba values (CSS 3) Note: 0 <= a <= 1 */ color: transparent; /* equivalent to setting the alpha to 0 */ color: hsl(0, 100%, 50%); /* as hsl percentages (CSS 3) */ color: hsla(0, 100%, 50%, 0.3); /* as hsl percentages with alpha */ /* Borders */ border-width:5px; border-style:solid; border-color:red; /* similar to how background-color is set */ border: 5px solid red; /* this is a short hand approach for the same */ border-radius:20px; /* this is a CSS3 property */ /* Images as backgrounds of elements */ background-image: url(/img-path/img.jpg); /* quotes inside url() optional */ /* Fonts */ font-family: Arial; /* if the font family name has a space, it must be quoted */ font-family: "Courier New"; /* if the first one is not found, the browser uses the next, and so on */ font-family: "Courier New", Trebuchet, Arial, sans-serif; } ``` ## Usage Save a CSS stylesheet with the extension `.css`. ```html
``` ## Precedence or Cascade An element may be targeted by multiple selectors and may have a property set on it in more than once. In these cases, one of the rules takes precedence over others. Rules with a more specific selector take precedence over a less specific one, and a rule occurring later in the stylesheet overwrites a previous one (which also means that if two different linked stylesheets contain rules for an element and if the rules are of the same specificity, then order of linking would take precedence and the sheet linked latest would govern styling) . This process is called cascading, hence the name Cascading Style Sheets. Given the following CSS: ```css /* A */ p.class1[attr='value'] /* B */ p.class1 { } /* C */ p.class2 { } /* D */ p { } /* E */ p { property: value !important; } ``` and the following markup: ```html

``` The precedence of style is as follows. Remember, the precedence is for each **property**, not for the entire block. * `E` has the highest precedence because of the keyword `!important`. It is recommended that you avoid its usage. * `F` is next, because it is an inline style. * `A` is next, because it is more "specific" than anything else. It has 3 specifiers: The name of the element `p`, its class `class1`, an attribute `attr='value'`. * `C` is next, even though it has the same specificity as `B`. This is because it appears after `B`. * `B` is next. * `D` is the last one. ## Media Queries CSS Media Queries are a feature in CSS 3 which allows you to specify when certain CSS rules should be applied, such as when printed, or when on a screen with certain dimensions or pixel density. They do not add to the selector's specificity. ```css /* A rule that will be used on all devices */ h1 { font-size: 2em; color: white; background-color: black; } /* change the h1 to use less ink on a printer */ @media print { h1 { color: black; background-color: white; } } /* make the font bigger when shown on a screen at least 480px wide */ @media screen and (min-width: 480px) { h1 { font-size: 3em; font-weight: normal; } } ``` Media queries can include these features: `width`, `height`, `device-width`, `device-height`, `orientation`, `aspect-ratio`, `device-aspect-ratio`, `color`, `color-index`, `monochrome`, `resolution`, `scan`, `grid`. Most of these features can be prefixed with `min-` or `max-`. The `resolution` feature is not supported by older devices, instead use `device-pixel-ratio`. Many smartphones and tablets will attempt to render the page as if it were on a desktop unless you provide a `viewport` meta-tag. ```html ``` ## Compatibility Most of the features in CSS 2 (and many in CSS 3) are available across all browsers and devices. But it's always good practice to check before using a new feature. ## Resources * [CanIUse](http://caniuse.com) (Detailed compatibility info) * [Dabblet](http://dabblet.com/) (CSS playground) * [Mozilla Developer Network's CSS documentation](https://developer.mozilla.org/en-US/docs/Web/CSS) (Tutorials and reference) * [Codrops' CSS Reference](http://tympanus.net/codrops/css_reference/) (Reference) ## Further Reading * [Understanding Style Precedence in CSS: Specificity, Inheritance, and the Cascade](http://www.vanseodesign.com/css/css-specificity-inheritance-cascaade/) * [Selecting elements using attributes](https://css-tricks.com/almanac/selectors/a/attribute/) * [QuirksMode CSS](http://www.quirksmode.org/css/) * [Z-Index - The stacking context](https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Understanding_z_index/The_stacking_context) * [SASS](http://sass-lang.com/) and [LESS](http://lesscss.org/) for CSS pre-processing * [CSS-Tricks](https://css-tricks.com) --- language: cypher filename: LearnCypher.cql contributors: - ["Théo Gauchoux", "https://github.com/TheoGauchoux"] --- Cypher is the Neo4j’s query language to manipulate graphs easily. It reuses syntax from SQL and mixes it with kind of ascii-art to represent graphs. This tutorial assumes that you already know graph concepts like nodes and relationships. [Read more here.](https://neo4j.com/developer/cypher-query-language/) Nodes --- **Represents a record in a graph.** ```()``` It's an empty *node*, to indicate that there is a *node*, but it's not relevant for the query. ```(n)``` It's a *node* referred by the variable **n**, reusable in the query. It begins with lowercase and uses camelCase. ```(p:Person)``` You can add a *label* to your node, here **Person**. It's like a type / a class / a category. It begins with uppercase and uses camelCase. ```(p:Person:Manager)``` A node can have many *labels*. ```(p:Person {name : 'Théo Gauchoux', age : 22})``` A node can have some *properties*, here **name** and **age**. It begins with lowercase and uses camelCase. The types allowed in properties : - Numeric - Boolean - String - List of previous primitive types *Warning : there isn't datetime property in Cypher ! You can use String with a specific pattern or a Numeric from a specific date.* ```p.name``` You can access to a property with the dot style. Relationships (or Edges) --- **Connects two nodes** ```[:KNOWS]``` It's a *relationship* with the *label* **KNOWS**. It's a *label* as the node's label. It begins with uppercase and use UPPER_SNAKE_CASE. ```[k:KNOWS]``` The same *relationship*, referred by the variable **k**, reusable in the query, but it's not necessary. ```[k:KNOWS {since:2017}]``` The same *relationship*, with *properties* (like *node*), here **since**. ```[k:KNOWS*..4]``` It's a structural information to use in a *path* (seen later). Here, **\*..4** says "Match the pattern, with the relationship **k** which be repeated between 1 and 4 times. Paths --- **The way to mix nodes and relationships.** ```(a:Person)-[:KNOWS]-(b:Person)``` A path describing that **a** and **b** know each other. ```(a:Person)-[:MANAGES]->(b:Person)``` A path can be directed. This path describes that **a** is the manager of **b**. ```(a:Person)-[:KNOWS]-(b:Person)-[:KNOWS]-(c:Person)``` You can chain multiple relationships. This path describes the friend of a friend. ```(a:Person)-[:MANAGES]->(b:Person)-[:MANAGES]->(c:Person)``` A chain can also be directed. This path describes that **a** is the boss of **b** and the big boss of **c**. Patterns often used (from Neo4j doc) : ``` // Friend-of-a-friend (user)-[:KNOWS]-(friend)-[:KNOWS]-(foaf) // Shortest path path = shortestPath( (user)-[:KNOWS*..5]-(other) ) // Collaborative filtering (user)-[:PURCHASED]->(product)<-[:PURCHASED]-()-[:PURCHASED]->(otherProduct) // Tree navigation (root)<-[:PARENT*]-(leaf:Category)-[:ITEM]->(data:Product) ``` Create queries --- Create a new node ``` CREATE (a:Person {name:"Théo Gauchoux"}) RETURN a ``` *`RETURN` allows to have a result after the query. It can be multiple, as `RETURN a, b`.* Create a new relationship (with 2 new nodes) ``` CREATE (a:Person)-[k:KNOWS]-(b:Person) RETURN a,k,b ``` Match queries --- Match all nodes ``` MATCH (n) RETURN n ``` Match nodes by label ``` MATCH (a:Person) RETURN a ``` Match nodes by label and property ``` MATCH (a:Person {name:"Théo Gauchoux"}) RETURN a ``` Match nodes according to relationships (undirected) ``` MATCH (a)-[:KNOWS]-(b) RETURN a,b ``` Match nodes according to relationships (directed) ``` MATCH (a)-[:MANAGES]->(b) RETURN a,b ``` Match nodes with a `WHERE` clause ``` MATCH (p:Person {name:"Théo Gauchoux"})-[s:LIVES_IN]->(city:City) WHERE s.since = 2015 RETURN p,state ``` You can use `MATCH WHERE` clause with `CREATE` clause ``` MATCH (a), (b) WHERE a.name = "Jacquie" AND b.name = "Michel" CREATE (a)-[:KNOWS]-(b) ``` Update queries --- Update a specific property of a node ``` MATCH (p:Person) WHERE p.name = "Théo Gauchoux" SET p.age = 23 ``` Replace all properties of a node ``` MATCH (p:Person) WHERE p.name = "Théo Gauchoux" SET p = {name: "Michel", age: 23} ``` Add new property to a node ``` MATCH (p:Person) WHERE p.name = "Théo Gauchoux" SET p + = {studies: "IT Engineering"} ``` Add a label to a node ``` MATCH (p:Person) WHERE p.name = "Théo Gauchoux" SET p:Internship ``` Delete queries --- Delete a specific node (linked relationships must be deleted before) ``` MATCH (p:Person)-[relationship]-() WHERE p.name = "Théo Gauchoux" DELETE relationship, p ``` Remove a property in a specific node ``` MATCH (p:Person) WHERE p.name = "Théo Gauchoux" REMOVE p.age ``` *Pay attention to the `REMOVE`keyword, it's not `DELETE` !* Remove a label from a specific node ``` MATCH (p:Person) WHERE p.name = "Théo Gauchoux" DELETE p:Person ``` Delete entire database ``` MATCH (n) OPTIONAL MATCH (n)-[r]-() DELETE n, r ``` *Seriously, it's the `rm -rf /` of Cypher !* Other useful clauses --- ```PROFILE``` Before a query, show the execution plan of it. ```COUNT(e)``` Count entities (nodes or relationships) matching **e**. ```LIMIT x``` Limit the result to the x first results. Special hints --- - There is just single-line comments in Cypher, with double-slash : // Comments - You can execute a Cypher script stored in a **.cql** file directly in Neo4j (it's an import). However, you can't have multiple statements in this file (separated by **;**). - Use the Neo4j shell to write Cypher, it's really awesome. - The Cypher will be the standard query language for all graph databases (known as **OpenCypher**). --- language: D filename: learnd.d contributors: - ["Nick Papanastasiou", "www.nickpapanastasiou.github.io"] --- ```d // You know what's coming... module hello; import std.stdio; // args is optional void main(string[] args) { writeln("Hello, World!"); } ``` If you're like me and spend way too much time on the internet, odds are you've heard about [D](http://dlang.org/). The D programming language is a modern, general-purpose, multi-paradigm language with support for everything from low-level features to expressive high-level abstractions. D is actively developed by a large group of super-smart people and is spearheaded by [Walter Bright](https://en.wikipedia.org/wiki/Walter_Bright) and [Andrei Alexandrescu](https://en.wikipedia.org/wiki/Andrei_Alexandrescu). With all that out of the way, let's look at some examples! ```d import std.stdio; void main() { // Conditionals and loops work as expected. for(int i = 0; i < 10000; i++) { writeln(i); } // 'auto' can be used for inferring types. auto n = 1; // Numeric literals can use '_' as a digit separator for clarity. while(n < 10_000) { n += n; } do { n -= (n / 2); } while(n > 0); // For and while are nice, but in D-land we prefer 'foreach' loops. // The '..' creates a continuous range, including the first value // but excluding the last. foreach(n; 1..1_000_000) { if(n % 2 == 0) writeln(n); } // There's also 'foreach_reverse' when you want to loop backwards. foreach_reverse(n; 1..int.max) { if(n % 2 == 1) { writeln(n); } else { writeln("No!"); } } } ``` We can define new types with `struct`, `class`, `union`, and `enum`. Structs and unions are passed to functions by value (i.e. copied) and classes are passed by reference. Furthermore, we can use templates to parameterize all of these on both types and values! ```d // Here, 'T' is a type parameter. Think '' from C++/C#/Java. struct LinkedList(T) { T data = null; // Use '!' to instantiate a parameterized type. Again, think ''. LinkedList!(T)* next; } class BinTree(T) { T data = null; // If there is only one template parameter, we can omit the parentheses. BinTree!T left; BinTree!T right; } enum Day { Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, } // Use alias to create abbreviations for types. alias IntList = LinkedList!int; alias NumTree = BinTree!double; // We can create function templates as well! T max(T)(T a, T b) { if(a < b) return b; return a; } // Use the ref keyword to ensure pass by reference. That is, even if 'a' and 'b' // are value types, they will always be passed by reference to 'swap()'. void swap(T)(ref T a, ref T b) { auto temp = a; a = b; b = temp; } // With templates, we can also parameterize on values, not just types. class Matrix(uint m, uint n, T = int) { T[m] rows; T[n] columns; } auto mat = new Matrix!(3, 3); // We've defaulted type 'T' to 'int'. ``` Speaking of classes, let's talk about properties for a second. A property is roughly a function that may act like an lvalue, so we can have the syntax of POD structures (`structure.x = 7`) with the semantics of getter and setter methods (`object.setX(7)`)! ```d // Consider a class parameterized on types 'T' & 'U'. class MyClass(T, U) { T _data; U _other; } // And "getter" and "setter" methods like so: class MyClass(T, U) { T _data; U _other; // Constructors are always named 'this'. this(T t, U u) { // This will call the setter methods below. data = t; other = u; } // getters @property T data() { return _data; } @property U other() { return _other; } // setters @property void data(T t) { _data = t; } @property void other(U u) { _other = u; } } // And we use them in this manner: void main() { auto mc = new MyClass!(int, string)(7, "seven"); // Import the 'stdio' module from the standard library for writing to // console (imports can be local to a scope). import std.stdio; // Call the getters to fetch the values. writefln("Earlier: data = %d, str = %s", mc.data, mc.other); // Call the setters to assign new values. mc.data = 8; mc.other = "eight"; // Call the getters again to fetch the new values. writefln("Later: data = %d, str = %s", mc.data, mc.other); } ``` With properties, we can add any amount of logic to our getter and setter methods, and keep the clean syntax of accessing members directly! Other object-oriented goodies at our disposal include interfaces, abstract classes, and overriding methods. D does inheritance just like Java: Extend one class, implement as many interfaces as you please. We've seen D's OOP facilities, but let's switch gears. D offers functional programming with first-class functions, `pure` functions, and immutable data. In addition, all of your favorite functional algorithms (map, filter, reduce and friends) can be found in the wonderful `std.algorithm` module! ```d import std.algorithm : map, filter, reduce; import std.range : iota; // builds an end-exclusive range void main() { // We want to print the sum of a list of squares of even ints // from 1 to 100. Easy! // Just pass lambda expressions as template parameters! // You can pass any function you like, but lambdas are convenient here. auto num = iota(1, 101).filter!(x => x % 2 == 0) .map!(y => y ^^ 2) .reduce!((a, b) => a + b); writeln(num); } ``` Notice how we got to build a nice Haskellian pipeline to compute num? That's thanks to a D innovation know as Uniform Function Call Syntax (UFCS). With UFCS, we can choose whether to write a function call as a method or free function call! Walter wrote a nice article on this [here.](http://www.drdobbs.com/cpp/uniform-function-call-syntax/232700394) In short, you can call functions whose first parameter is of some type A on any expression of type A as a method. I like parallelism. Anyone else like parallelism? Sure you do. Let's do some! ```d // Let's say we want to populate a large array with the square root of all // consecutive integers starting from 1 (up until the size of the array), and we // want to do this concurrently taking advantage of as many cores as we have // available. import std.stdio; import std.parallelism : parallel; import std.math : sqrt; void main() { // Create your large array auto arr = new double[1_000_000]; // Use an index, access every array element by reference (because we're // going to change each element) and just call parallel on the array! foreach(i, ref elem; parallel(arr)) { elem = sqrt(i + 1.0); } } ``` --- language: dart filename: learndart.dart contributors: - ["Joao Pedrosa", "https://github.com/jpedrosa/"] --- 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. ```dart 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 ' "Don't can't I'm Etc" ''); } // Strings with triple single-quotes or triple double-quotes span // multiple lines and include line delimiters. example19() { print('''Example19 Example19 Don't can't I'm Etc Example19 '''); } // 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 _names; Example21() { _names = ["a", "b"]; } List get names => _names; set names(List 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 comprehensive web-site. It covers API reference, tutorials, articles and more, including a useful Try Dart online. http://www.dartlang.org/ http://try.dartlang.org/ --- language: asciidoc contributors: - ["Ryan Mavilia", "http://unoriginality.rocks/"] translators: - ["Dennis Keller", "https://github.com/denniskeller"] filename: asciidoc-de.md lang: de-de --- AsciiDoc ist eine Auszeichnungssprache ähnlich zu Markdown. Sie kann für alles verwendet werden von Büchern zu Blogs. Erfunden wurde sie 2002 von Stuart Rackham. Die Sprache ist simpel aber sie ermöglicht eine große Anzahl an Anpassungen. Kopfzeile des Dokuments Kopfzeilen sind optional und dürfen keine Leerzeilen besitzen. Sie müssen mindestens eine Leerzeile vom Inhalt versetzt sein. Nur Titel ``` = Dokumententitel Erster Satz des Dokuments. ``` Titel und Autor ``` = Dokumententitel Vorname Nachname Start des Dokuments. ``` Mehrere Autoren ``` = Dokumententitel John Doe ; Jane Doe; Black Beard Starte ein Dokument mit mehreren Autoren. ``` Revisionszeile (benötigt eine Autorzeile) ``` = Dokumententitel V1 Potato Man v1.0, 2016-01-13 Dieser Artikel über Chips wird Spaß machen. ``` Absätze ``` Du musst nichts besonderes machen für Absätze. Füge eine Leerzeile zwischen zwei Absätze, um sie zu trennen. Um eine Leerzeile zu erhalten musst du ein + ergänzen und du erhälst einen Umbruch! ``` Textformatierung ``` _Unterstriche erstellt Kursivschrift_ *Sternchen für Fett gedruckt* *_Kombinieren für extra Spaß_* `Benutze Ticks um Monospace zu signalisieren` `*Fett gedruckter Monospace*` ``` Abteilungstitel ``` = Level 0 (sollte nur in der Kopfzeile verwendet werden) == Level 1

=== Level 2

==== Level 3

===== Level 4

====== Level 5
======= Level 6 ``` Listen Um eine Aufzählung zu erstellen verwendest du Sternchen. ``` * foo * bar * baz ``` Um eine nummerierte Liste zu erstellen verwendest du Punkte. ``` . item 1 . item 2 . item 3 ``` Um Listen zu verschachteln musst du zusätzliche Sternchen und Punkte hinzufügen. Dies ist bis zu fünf Mal möglich. ``` * foo 1 ** foo 2 *** foo 3 **** foo 4 ***** foo 5 . foo 1 .. foo 2 ... foo 3 .... foo 4 ..... foo 5 ``` --- category: tool tool: bash lang: de-de contributors: - ["Max Yankov", "https://github.com/golergka"] - ["Darren Lin", "https://github.com/CogBear"] translators: - ["kultprok", "http://www.kulturproktologie.de"] filename: LearnBash-de.sh --- Bash ist der Name der Unix-Shell, die als Shell des GNU-Betriebssystems und auch als Standard-Shell von Linux und Mac OS X ausgeliefert wurde. Beinahe alle der folgenden Beispiele können als Teile eines Shell-Skripts oder direkt in der Shell ausgeführt werden. [Weitere Informationen \(Englisch\)](http://www.gnu.org/software/bash/manual/bashref.html) ```bash #!/bin/bash # Die erste Zeile des Scripts nennt sich Shebang, dies gibt dem System an, # wie das Script ausgeführt werden soll: http://de.wikipedia.org/wiki/Shebang # Du hast es bestimmt schon mitgekriegt, Kommentare fangen mit # an. Das Shebang ist auch ein Kommentar # Ein einfaches Beispiel mit hello world: echo Hello, world! # Jeder Befehl fängt auf einer neuen Zeile oder nach einem Semikolon an: echo 'Dies ist die erste Zeile'; echo 'Dies die zweite Zeile' # Variablen deklariert man so: Variable="irgendein String" # Aber nicht so: Variable = "irgendein String" # Bash wird 'Variable' für einen Befehl halten, den es ausführen soll. Es wird einen Fehler ausgeben, # weil es den Befehl nicht findet. # Und so auch nicht: Variable= 'Some string' # Bash wird 'Variable' wieder für einen Befehl halten, den es ausführen soll. Es wird einen Fehler ausgeben, # Hier wird der Teil 'Variable=' als nur für diesen einen Befehl gültige Zuweisung an die Variable gesehen. # Eine Variable wird so benutzt: echo $Variable echo "$Variable" echo ${Variable} # aber echo '$Variable' # Wenn du eine Variable selbst benutzt – ihr Werte zuweist, sie exportierst oder irgendetwas anderes –, # dann über ihren Namen ohne $. Aber wenn du ihren zugewiesenen Wert willst, dann musst du $ voranstellen. # Beachte: ' (Hochkomma) verhindert das Interpretieren der Variablen # Ersetzen von Zeichenketten in Variablen echo ${Variable/irgendein/neuer} # Ersetzt das erste Vorkommen von "irgendein" durch "neuer" # Teil einer Zeichenkette Laenge=7 echo ${Variable:0:Laenge} # Gibt nur die ersten 7 Zeichen zurück # Standardwert verwenden echo ${Foo:-"ErsatzWennLeerOderUngesetzt"} # Das funktioniert mit nicht gesetzten Variablen (Foo=) und leeren Zeichenketten (Foo="") # Die Zahl 0 (Foo=0) liefert 0. # Beachte: der wert der Variablen wird nicht geändert # Eingebaute Variable (BUILTINS): # Einige nützliche Beispiele echo "Rückgabewert des letzten Befehls: $?" echo "Die PID des skripts: $$" echo "Anzahl der Argumente beim Aufruf: $#" echo "Alle Argumente beim Aufruf: $@" echo "Die Argumente in einzelnen Variablen: $1 $2..." # Einen Wert aus der Eingabe lesen: echo "Wie heisst du?" read NAME # Wir mussten nicht mal eine neue Variable deklarieren echo Hello, $NAME! # Wir haben die übliche if-Struktur: # 'man test' liefert weitere Informationen zu Bedingungen if [ "$NAME" -ne $USER ] then echo "Dein Name ist nicht dein Login-Name" else echo "Dein Name ist dein Login-Name" fi # Es gibt auch bedingte Ausführung echo "immer ausgeführt" || echo "Nur ausgeführt wenn der erste Befehl fehlschlägt" echo "immer ausgeführt" && echo "Nur ausgeführt wenn der erste Befehl Erfolg hat" # Um && und || mit if statements zu verwenden, braucht man mehrfache Paare eckiger Klammern: if [ "$NAME" == "Steve" ] && [ "$Alter" -eq 15 ] then echo "Wird ausgeführt wenn $NAME gleich 'Steve' UND $Alter gleich 15." fi if [ "$Name" == "Daniya" ] || [ "$Name" == "Zach" ] then echo "Wird ausgeführt wenn $NAME gleich 'Daniya' ODER $NAME gleich 'Zach'." fi # Ausdrücke haben folgendes Format: echo $(( 10 + 5 )) # Anders als andere Programmiersprachen ist Bash eine Shell – es arbeitet also im Kontext von Verzeichnissen. # Du kannst alle Dateien und Verzeichnisse im aktiven Verzeichnis mit ls auflisten: ls # Diese Befehle haben Optionen, die ihre Ausführung beeinflussen: ls -l # Liste alle Dateien und Unterverzeichnisse auf einer eigenen Zeile auf # Ergebnisse eines vorangegangenen Befehls können an den nächsten Befehl als Input übergeben werden. # Der grep-Befehl filtert den Input nach dem vorgegebenen Muster. So können wir alle # txt-Dateien im aktuellen Verzeichnis auflisten: ls -l | grep "\.txt" # Ein- und Ausgabe können umgeleitet werden (stdin, stdout, and stderr). # Von stdin lesen bis "EOF" allein in einer Zeile auftaucht # und die Datei hello.py mit den Zeilen zwischen den beiden "EOF" # überschreiben: cat > hello.py << EOF #!/usr/bin/env python from __future__ import print_function import sys print("#stdout", file=sys.stdout) print("#stderr", file=sys.stderr) for line in sys.stdin: print(line, file=sys.stdout) EOF # Führe hello.py mit verschiedenen Umleitungen von # stdin, stdout und stderr aus: python hello.py < "input.in" python hello.py > "output.out" python hello.py 2> "error.err" python hello.py > "output-and-error.log" 2>&1 python hello.py > /dev/null 2>&1 # Die Fehlerausgabe würde die Datei "error.err" überschreiben (falls sie existiert) # verwende ">>" um stattdessen anzuhängen: python hello.py >> "output.out" 2>> "error.err" # Überschreibe output.out, hänge an error.err an und zähle die Zeilen beider Dateien: info bash 'Basic Shell Features' 'Redirections' > output.out 2>> error.err wc -l output.out error.err # Führe einen Befehl aus und gib dessen "file descriptor" (zB /dev/fd/123) aus # siehe: man fd echo <(echo "#helloworld") # Mehrere Arten, um output.out mit "#helloworld" zu überschreiben: cat > output.out <(echo "#helloworld") echo "#helloworld" > output.out echo "#helloworld" | cat > output.out echo "#helloworld" | tee output.out >/dev/null # Löschen der Hilfsdateien von oberhalb, mit Anzeige der Dateinamen # (mit '-i' für "interactive" erfolgt für jede Date eine Rückfrage) rm -v output.out error.err output-and-error.log # Die Ausgabe von Befehlen kann mit Hilfe von $( ) in anderen Befehlen verwendet weden: # Der folgende Befehl zeigt die Anzahl aller Dateien und Unterverzeichnisse # im aktuellen Verzeichnis an. echo "Dieser Ordner beinhaltet $(ls | wc -l) Dateien und Verzeichnisse." # Dasselbe kann man mit "backticks" `` erreichen, aber diese können # nicht verschachtelt werden. $() ist die empfohlene Methode. echo "Dieser Ordner beinhaltet `ls | wc -l` Dateien und Verzeichnisse." # Bash nutzt einen case-Ausdruck, der sich ähnlich wie switch in Java oder C++ verhält. case "$Variable" in # Liste der Fälle, die unterschieden werden sollen 0) echo "Hier ist eine Null." 1) echo "Hier ist eine Eins." *) echo "Das ist etwas anderes." esac # 'for' Schleifen iterieren über die angegebene Zahl von Argumenten: # Der Inhalt von $Variable wird dreimal ausgedruckt. for $Variable in {1..3} do echo "$Variable" done # Oder verwende die "traditionelle 'for'-Schleife": for ((a=1; a <= 3; a++)) do echo $a done # Schleifen können auch mit Dateien arbeiten: # 'cat' zeigt zuerst file1 an und dann file2 for Variable in file1 file2 do cat "$Variable" done # .. oder mit der Ausgabe eines Befehls: # Ausgabe des Inhalts jeder Datei, die von 'ls' aufgezählt wird for Output in $(ls) do cat "$Output" done # while Schleife: while [ true ] do echo "Schleifenkörper..." break done # Funktionen definieren # Definition: function foo () { echo "Argumente funktionieren wie bei skripts: $@" echo Und: $1 $2..." echo "Dies ist eine Funktion" return 0 } # oder einfacher bar () { echo "Auch so kann man Funktionen deklarieren!" return 0 } # Aufruf der Funktion: foo "My name is" $Name # Was du noch lernen könntest: # Ausgabe der letzten 10 Zeilen von file.txt tail -n 10 file.txt # Ausgabe der ersten 10 Zeilen von file.txt head -n 10 file.txt # sortierte Ausgabe von file.txt sort file.txt # Mehrfachzeilen in sortierten Dateien unterdrücken # oder (mit -d) nur diese ausgeben uniq -d file.txt # Ausgabe nur der ersten Spalte (vor dem ersten ',') cut -d ',' -f 1 file.txt # ersetze in file.txt jedes vorkommende 'gut' durch 'super' (versteht regex) sed -i 's/gut/super/g' file.txt # Ausgabe nach stdout aller Zeilen von file.txt, die auf eine regex passen # Im Beispiel: Zeilen, die mit "foo" beginnen und mit "bar" enden grep "^foo.*bar$" file.txt # Mit der Option "-c" wird stattdessen die Anzahl der gefundenen Zeilen ausgegeben grep -c "^foo.*bar$" file.txt # verwende 'fgrep' oder 'grep -F' wenn du buchstäblich nach den Zeichen # suchen willst, ohne sie als regex zu interpretieren fgrep "^foo.*bar$" file.txt # Dokumentation über die in bash eingebauten Befehle # bekommst du mit dem eingebauten Befehl 'help' help help help help for help return help source help . # Das bash-Handbuch liest du mit 'man' apropos bash man 1 bash man bash # Dann gibt es noch das 'info' System (drücke ? um Hilfe angezeigt zu bekommen) apropos info | grep '^info.*(' man info info info info 5 info # info Dokumentation über bash: info bash info bash 'Bash Features' info bash 6 info --apropos bash ``` --- language: brainfuck contributors: - ["Prajit Ramachandran", "http://prajitr.github.io/"] - ["Mathias Bynens", "http://mathiasbynens.be/"] translators: - ["urfuchs", "https://github.com/urfuchs"] filename: brainfuck-de lang: de-de --- Brainfuck ist eine extrem minimalistische Turing-vollständige Programmiersprache mit lediglich 8 Befehlen. Mit dem [brainfuck-visualizer](http://fatiherikli.github.io/brainfuck-visualizer/) kann Brainfuck im Browser ausprobiert werden. ``` Alle Zeichen außer "><+-.,[]" (ohne die Klammern) werden ignoriert. Brainfuck besteht aus einem Array mit unendlich vielen Elementen, die alle mit Null initalisiert sind und einem Datenzeiger auf das aktuelle Element. Es gibt acht Befehle: + : Erhöht den Wert an der aktuellen Stelle um Eins. - : Verringert den Wert an der aktuellen Stelle um Eins. > : Bewegt den Zeiger um eine Stelle weiter. < : Bewegt den Zeiger um eine Stelle zurück. . : Gibt den Wert der aktuellen Zelle als ASCII Wert aus (z.B. 65 = 'A'). , : Liest ein einzelnes Zeichen von der Standardeingabe und speichert dessen ASCII Wert in der aktuellen Zelle. [ : Wenn der Wert des aktuellen Elements Null ist, bewege des Zeiger hinter den zugehörigen ]-Befehl. Ansonsten, bewege den Zeiger ein Element weiter. ] : Wenn der Wert des aktuellen Elements Null ist, bewege des Zeiger um eine Stelle weiter. Ansonsten, bewege den Zeiger hinter den zugehörigen [-Befehl. [ und ] bilden eine while-Schleife. Offensichtlich müssen sie paarweise vorkommen. Schauen wir uns einige grundlegende Programme an. ++++++ [ > ++++++++++ < - ] > +++++ . Dieses Programm gibt den Buchstaben 'A' aus. Zunächst erhöht es den Wert der 1. Zelle auf 6. Diese erste Zelle wird für die Schleife verwendet. Danach beginnt das Programm die Schleife ([) und geht vor zu Zelle #2. Es erhöht den Zellwert inkrementell 10 Mal, geht dann zurück zu Zelle #1, und verringert Zelle #1. Diese Schleife wird 6 Mal durchlaufen (nach 6 Durchläufen ist der Wert der Zelle #1 auf 0 reduziert, dadurch wird die Schleife abgebrochen und das Programm hinter dem korrespondierenden ] fortgesetzt). An dieser Stelle befinden wir uns an Zelle #1, die jetzt den Wert 0 hat, während Zelle #2 den Wert 60 hat. Wir gehen vor zu Zelle #2, inkrementieren 5 Mal, bis zum Wert 65, und geben dann den Wert der Zelle #2 aus. 65 ist ein 'A' im ASCII Zeichensatz, daher wird 'A' am Terminal ausgegeben.. , [ > + < - ] > . Dieses Programm liest ein Zeichen von der Benutzereingabe und schreibt dessen Wert in Zelle #1. Danach beginnt eine Schleife. Rücke vor auf Zelle #2, erhöhe den Wert der Zelle #2, gehe zurück auf Zelle #1, verringere den Wert der Zelle #1. Dies geht solange bis Zelle #1 den Wert 0 und Zelle #2 den alten Wert aus #1 hat. Da wir am Ende der Schleife bie Zelle #1 sind, gehe vor zu Zelle #2 und gibt denb Wert als ASCII Zeichen aus. Beachte biite, dass die Leerzeichen nur aus Gründen der Lesbarkeit geschrieben werden. Man könnte genauso schreiben: ,[>+<-]>. Versuche herauszufinden, was dieses Programm macht: ,>,< [ > [ >+ >+ << -] >> [- << + >>] <<< -] >> Dieses Programm nimmt zwei Zahlen als Eingabe und multipliziert sie. Im Wesentlichen liest es zunächst zwei Werte ein. Dann beginnt die äußere Schleife mit Zelle #1 als Zähler. Danach geht das Programm zu Zelle #2 vor und startet die innere Schleife mit Zelle #2 als Zähler. Diese zählt Zelle #3 hoch. Es gibt jedoch ein Problem: Am Ende der inneren Schleife hat Zelle #2 den Wert Null. Daher würde die innere Schleife beim nächsten Durchgang nicht mehr funktionieren. Daher wird auch Zelle #4 erhöht und anschließend in Zelle #2 zurückkopiert. Am Ende steht in Zelle #3 das Ergebnis. ``` Das ist Brainfuck. Nicht so schwierig, oder? Zum Spaß kannst du dein eigenes Brainfuck Programm schreiben oder du schreibst einen Brainfuck Interpreter in einer anderen Programmiersprache. Der Interpreter lässt sich ziemlich einfach implementieren. Falls du Masochist bist, kannst du auch versuchen, einen Brainfuck Interpreter in Brainfuck zu implementieren. --- language: coffeescript contributors: - ["Tenor Biel", "http://github.com/L8D"] - ["Xavier Yao", "http://github.com/xavieryao"] translators: - ["Frederik Ring", "https://github.com/m90"] - ["Philipp Fischbeck", "https://github.com/PFischbeck"] filename: coffeescript-de.coffee lang: de-de --- CoffeeScript ist eine kleine Sprache, die eins zu eins nach JavaScript übersetzt wird - es findet keine Interpretation zur Laufzeit statt. Als Nachfolger von JavaScript konzipiert, gibt CoffeeScript sein Bestes, lesbaren, gut formatierten und sauber laufenden JavaScript-Code zu erzeugen, der in jeder JavaScript-Laufzeit einwandfrei funktioniert. Auf [der CoffeeScript Website](http://coffeescript.org/) gibt es ein ausführliches Tutorial. ``` coffeescript # CoffeeScript ist eine dieser Sprachen für "Hipster" # und folgt daher vielen Trends und Einflüssen aus modernen Sprachen. # Kommentare werden daher wie in Ruby und Python mit Hashes gekennzeichnet ### Kommentarblöcke sehen aus wie diese und werden direkt nach '/ *'s und '* /'s im erzeugten JavaScript umgewandelt. Vorweg: bevor du mit CoffeeScript anfängst, solltest du bereits einen guten Überblick über die Sprache JavaScript haben. ### # Zuweisung: number = 42 #=> var number = 42; opposite = true #=> var opposite = true; # Bedingungen: number = -42 if opposite #=> if(opposite) { number = -42; } # Funktionen: square = (x) -> x * x #=> var square = function(x) { return x * x; } fill = (container, liquid = "Kaffee") -> "#{container} wird mit #{liquid} gefüllt..." #=>var fill; # #fill = function(container, liquid) { # if (liquid == null) { # liquid = "Kaffee"; # } # return container + " wird mit " + liquid + " gefüllt..."; #}; # "Ranges": list = [1..5] #=> var list = [1, 2, 3, 4, 5]; # Objekte: math = root: Math.sqrt square: square cube: (x) -> x * square x #=> var math = { # "root": Math.sqrt, # "square": square, # "cube": function(x) { return x * square(x); } #} # "Splats": race = (winner, runners...) -> print winner, runners #=>race = function() { # var runners, winner; # winner = arguments[0], runners = 2 <= arguments.length ? __slice.call(arguments, 1) : []; # return print(winner, runners); #}; # Existenz-Operator: alert "Hab ich's nicht gesagt?" if elvis? #=> if(typeof elvis !== "undefined" && elvis !== null) { alert("Hab ich's nicht gesagt?"); } # Listen-Abstraktion: cubes = (math.cube num for num in list) #=>cubes = (function() { # var _i, _len, _results; # _results = []; # for (_i = 0, _len = list.length; _i < _len; _i++) { # num = list[_i]; # _results.push(math.cube(num)); # } # return _results; # })(); foods = ['Brokkoli', 'Spinat', 'Schokolade'] eat food for food in foods when food isnt 'Schokolade' #=>foods = ['Brokkoli', 'Spinat', 'Schokolade']; # #for (_k = 0, _len2 = foods.length; _k < _len2; _k++) { # food = foods[_k]; # if (food !== 'Schokolade') { # eat(food); # } #} ``` ## Weiterführende Links - [Smooth CoffeeScript](http://autotelicum.github.io/Smooth-CoffeeScript/) - [CoffeeScript Ristretto](https://leanpub.com/coffeescript-ristretto/read) --- language: c# contributors: - ["Irfan Charania", "https://github.com/irfancharania"] - ["Max Yankov", "https://github.com/golergka"] - ["Melvyn Laïly", "http://x2a.yt"] - ["Shaun McCarthy", "http://www.shaunmccarthy.com"] translators: - ["Frederik Ring", "https://github.com/m90"] filename: LearnCSharp-de.cs lang: de-de --- C# ist eine elegante, typsichere und objektorientierte Sprache, mit der Entwickler eine Vielzahl sicherer und robuster Anwendungen erstellen können, die im .NET Framework ausgeführt werden. [Mehr über C# erfährst du hier.](http://msdn.microsoft.com/de-de/library/vstudio/z1zx9t92.aspx) ```c# // Einzeilige Kommentare starten mit zwei Schrägstrichen: // /* Mehrzeile Kommentare wie in C Schrägstrich / Stern */ /// /// XML-Kommentare können zur automatisierten Dokumentation verwendet werden /// // Zu Beginn werden die in der Datei verwendeten Namespaces aufgeführt using System; using System.Collections.Generic; using System.Data.Entity; using System.Dynamic; using System.Linq; using System.Linq.Expressions; using System.Net; using System.Threading.Tasks; using System.IO; // definiert einen Namespace um Code in "packages" zu organisieren namespace Learning { // Jede .cs-Datei sollte zumindest eine Klasse mit dem Namen der Datei // enthalten. Das ist zwar nicht zwingend erforderlich, es anders zu // handhaben führt aber unweigerlich ins Chaos (wirklich)! public class LearnCSharp { // Zuerst erklärt dieses Tutorial die Syntax-Grundlagen, // wenn du bereits Java oder C++ programmieren kannst: // lies bei "Interessante Features" weiter! public static void Syntax() { // Mit Console.WriteLine kannst du einfachen Text ausgeben: Console.WriteLine("Hallo Welt"); Console.WriteLine( "Integer: " + 10 + " Double: " + 3.14 + " Boolean: " + true); // Console.Write erzeugt keinen Zeilenumbruch Console.Write("Hallo "); Console.Write("Welt"); /////////////////////////////////////////////////// // Typen & Variablen /////////////////////////////////////////////////// // Deklariere eine Variable mit // Sbyte - Vorzeichenbehaftete 8-Bit Ganzzahl // (-128 <= sbyte <= 127) sbyte fooSbyte = 100; // Byte - Vorzeichenlose 8-Bit Ganzzahl // (0 <= byte <= 255) byte fooByte = 100; // Short - 16-Bit Ganzzahl // Vorzeichenbehaftet - (-32,768 <= short <= 32,767) // Vorzeichenlos - (0 <= ushort <= 65,535) short fooShort = 10000; ushort fooUshort = 10000; // Integer - 32-bit Ganzzahl int fooInt = 1; // (-2,147,483,648 <= int <= 2,147,483,647) uint fooUint = 1; // (0 <= uint <= 4,294,967,295) // Long - 64-bit Ganzzahl long fooLong = 100000L; // (-9,223,372,036,854,775,808 <= long <= 9,223,372,036,854,775,807) ulong fooUlong = 100000L; // (0 <= ulong <= 18,446,744,073,709,551,615) // Ganze Zahlen werden standardmäßig - je nach Größe - als int oder // uint behandelt. Ein nachgestelltes L markiert den Wert als long // oder ulong. // Double - Double-precision 64-bit IEEE 754 Fließkommazahl double fooDouble = 123.4; // Genauigkeit: 15-16 Stellen // Float - Single-precision 32-bit IEEE 754 Fließkommazahl float fooFloat = 234.5f; // Genauigkeit: 7 Stellen // Das nachgestellte f zeigt an dass es sich um einen Wert vom Typ // float handelt // Decimal - ein 128-Bit-Datentyp mit größerer Genauigkeit als // andere Fließkommatypen, und somit bestens geeignet für // die Berechnung von Geld- und Finanzwerten decimal fooDecimal = 150.3m; // Boolean - true & false bool fooBoolean = true; // oder false // Char - Ein einzelnes 16-Bit Unicode Zeichen char fooChar = 'A'; // Strings - im Gegensatz zu allen vorhergehenden Basistypen, die // alle Werttypen sind, ist String ein Referenztyp. Strings sind // somit nullable, Werttypen sind dies nicht. string fooString = "\"maskiere\" Anführungszeichen, und füge \n (Umbrüche) und \t (Tabs) hinzu"; Console.WriteLine(fooString); // Jeder Buchstabe eines Strings kann über seinen Index // referenziert werden: char charFromString = fooString[1]; // => 'e' // Strings sind unveränderlich: // `fooString[1] = 'X';` funktioniert nicht // Ein Vergleich zweier Strings, unter Berücksichtigung der // aktuellen, sprachspezifischen Gegebenheiten (also z.B. a,ä,b,c // in deutschsprachigen Umgebungen), und ohne Beachtung von // Groß- und Kleinschreibung: string.Compare(fooString, "x", StringComparison.CurrentCultureIgnoreCase); // Formatierung, genau wie "sprintf" string fooFs = string.Format("Mikrofon Check, {0} {1}, {0} {1:0.0}", 1, 2); // Datumsangaben und Formatierung DateTime fooDate = DateTime.Now; Console.WriteLine(fooDate.ToString("hh:mm, dd MMM yyyy")); // Durch ein vorangestelltes @ lässt sich ein mehrzeiliger String // schreiben. Um " zu maskieren benutzt man "" string bazString = @"Hier geht es zur nächsten Zeile, ""Wahnsinn!"", die Massen waren kaum zu bändigen"; // Die Keywords const oder readonly kennzeichnen eine // unveränderliche Variable/Konstante. Die Werte von Konstanten // werden übrigens bereits zur Compile-Zeit berechnet. const int HOURS_I_WORK_PER_WEEK = 9001; /////////////////////////////////////////////////// // Datenstrukturen /////////////////////////////////////////////////// // Arrays - Index beginnt bei Null // Die Größe des Arrays wird bei der Deklaration festgelegt. // Die syntaktische Struktur um ein neues Array zu erzeugen sieht // folgendermaßen aus: // [] = new []; int[] intArray = new int[10]; // Arrays können auch über ein Array-Literal deklariert werden: int[] y = { 9000, 1000, 1337 }; // Indizierung eines Arrays - Zugriff auf ein bestimmtes Element Console.WriteLine("intArray @ 0: " + intArray[0]); // Arrays sind veränderbar intArray[1] = 1; // Listen // Durch ihre größere Flexibilität kommen Listen in C# weit // häufiger zum Einsatz als Arrays. Eine Liste wird so deklariert: // List = new List(); List intList = new List(); List stringList = new List(); List z = new List { 9000, 1000, 1337 }; // Die <> kennzeichnen "Generics", mehr dazu unter "Coole Sachen" // Listen haben keinen Default-Wert. // Bevor auf einen Index zugegriffen werden kann, muss dieser // auch gesetzt worden sein: intList.Add(1); Console.WriteLine("intList @ 0: " + intList[0]); // Andere interessante Datenstrukturen sind: // Stack/Queue // Dictionary (entspricht einer Hash Map) // HashSet // Read-only Collections // Tuple (.Net 4+) /////////////////////////////////////// // Operatoren /////////////////////////////////////// Console.WriteLine("\n->Operatoren"); // kurze Schreibweise um mehrere Deklarationen zusammenzufassen: // (Benutzung vom C# Styleguide aber ausdrücklich abgeraten!) int i1 = 1, i2 = 2; // Arithmetik funktioniert wie erwartet: Console.WriteLine(i1 + i2 - i1 * 3 / 7); // => 3 // Modulo Console.WriteLine("11%3 = " + (11 % 3)); // => 2 // Vergleiche Console.WriteLine("3 == 2? " + (3 == 2)); // => false Console.WriteLine("3 != 2? " + (3 != 2)); // => true Console.WriteLine("3 > 2? " + (3 > 2)); // => true Console.WriteLine("3 < 2? " + (3 < 2)); // => false Console.WriteLine("2 <= 2? " + (2 <= 2)); // => true Console.WriteLine("2 >= 2? " + (2 >= 2)); // => true // Bitweise Operatoren /* ~ Unäres bitweises NICHT << Verschieben nach links >> Verschieben nach rechts & Bitweises UND ^ Bitweises exklusives ODER | Bitweises inklusives ODER */ // Inkremente int i = 0; Console.WriteLine("\n->Inkrement / Dekrement"); Console.WriteLine(i++); //i = 1. Post-Inkrement Console.WriteLine(++i); //i = 2. Pre-Inkrement Console.WriteLine(i--); //i = 1. Post-Dekrement Console.WriteLine(--i); //i = 0. Pre-Dekrement /////////////////////////////////////// // Kontrollstrukturen /////////////////////////////////////// Console.WriteLine("\n->Kontrollstrukturen"); // If-Statements funktionieren wie in C int j = 10; if (j == 10) { Console.WriteLine("Ich werde ausgegeben"); } else if (j > 10) { Console.WriteLine("Ich nicht"); } else { Console.WriteLine("Ich leider auch nicht"); } // Ternärer Operator // Anstatt eines einfachen if/else lässt sich auch folgendes schreiben: // ? : int zumVergleich = 17; string isTrue = zumVergleich == 17 ? "Ja" : "Nein"; // while-Schleife int fooWhile = 0; while (fooWhile < 100) { // Wird 100mal wiederholt, fooWhile 0->99 fooWhile++; } // do-while-Schleife int fooDoWhile = 0; do { // Wird 100mal wiederholt, fooDoWhile 0->99 fooDoWhile++; } while (fooDoWhile < 100); //for-Schleifen => for(; ; ) for (int fooFor = 0; fooFor < 10; fooFor++) { // Wird 10mal wiederholt, fooFor 0->9 } // foreach-Schleife // Die normale Syntax für eine foreach-Schleife lautet: // foreach( in ) // foreach kann mit jedem Objekt verwendet werden das IEnumerable // oder IEnumerable implementiert. Alle Auflistungs-Typen // (Array, List, Dictionary...) im .NET Framework implementieren // eines dieser beiden Interfaces. foreach (char character in "Hallo Welt".ToCharArray()) { // Ein Durchgang für jedes Zeichen im String } // (ToCharArray() könnte man hier übrigens auch weglassen, // da String IEnumerable bereits implementiert) // Switch Struktur // Ein Switch funktioniert mit byte, short, char und int Datentypen. // Auch Aufzählungstypen können verwendet werden, genau wie // die Klasse String, und ein paar Sonderklassen, die Wrapper für // Primitives sind: Character, Byte, Short und Integer int month = 3; string monthString; switch (month) { case 1: monthString = "Januar"; break; case 2: monthString = "Februar"; break; case 3: monthString = "März"; break; // Man kann für mehrere Fälle auch das selbe Verhalten // definieren. Jeder Block muss aber mit einem break-Statement // abgeschlossen werden. Einzelne Fälle können über // `goto case x` erreicht werden case 6: case 7: case 8: monthString = "Sommer!!"; break; default: monthString = "Irgendein anderer Monat"; break; } /////////////////////////////////////// // Umwandlung von Datentypen und Typecasting /////////////////////////////////////// // Umwandlung // von String nach Integer // bei einem Fehler wirft diese Code eine Exception int.Parse("123"); //gibt die Ganzzahl 123 zurück // TryParse gibt bei einem Fehler den Default-Wert zurück // (im Fall von int: 0) int tryInt; if (int.TryParse("123", out tryInt)) // gibt true oder false zurück { Console.WriteLine(tryInt); // 123 } // von Integer nach String // Die Klasse Convert stellt Methoden zur Konvertierung von // unterschiedlichsten Daten zur Verfügung: Convert.ToString(123); // "123" // oder tryInt.ToString(); // "123" } /////////////////////////////////////// // Klassen /////////////////////////////////////// public static void Classes() { // Benutze das new-Keyword um eine Instanz einer Klasse zu erzeugen Bicycle trek = new Bicycle(); // So werden Methoden der Instanz aufgerufen trek.SpeedUp(3); // Es empfiehlt sich immer Getter und Setter zu benutzen trek.Cadence = 100; // ToString ist eine Konvention über die man üblicherweiser // Informationen über eine Instanz erhält Console.WriteLine("Infos zu trek: " + trek.ToString()); // Wir instantiieren ein neues Hochrad PennyFarthing funbike = new PennyFarthing(1, 10); Console.WriteLine("Infos zu funbike: " + funbike.ToString()); Console.Read(); } // Ende der Methode main // Main als Konsolenstartpunkt // Eine Konsolenanwendung muss eine Methode Main als Startpunkt besitzen public static void Main(string[] args) { OtherInterestingFeatures(); } /////////////////////////////////////// // Interessante Features /////////////////////////////////////// // Methodensignaturen public // Sichtbarkeit static // Erlaubt einen Zugriff auf der Klasse (nicht auf einer Instanz) int // Typ des Rückgabewerts, MethodSignatures( // Erstes Argument, erwartet int int maxCount, // setzt sich selbst auf 0 wenn kein anderer Wert übergeben wird int count = 0, int another = 3, // enthält alle weiteren der Methode übergebenen Parameter (quasi Splats) params string[] otherParams ) { return -1; } // Methoden können überladen werden, solange sie eindeutige // Signaturen haben public static void MethodSignatures(string maxCount) { } // Generische Typen // Die Typen für TKey und TValue werden erst beim Aufruf der Methode // festgelegt. Diese Methode emuliert z.B. SetDefault aus Python: public static TValue SetDefault( IDictionary dictionary, TKey key, TValue defaultItem) { TValue result; if (!dictionary.TryGetValue(key, out result)) { return dictionary[key] = defaultItem; } return result; } // Möglichen Typen lassen sich auch über ihr Interface beschränken: public static void IterateAndPrint(T toPrint) where T: IEnumerable { // Da T ein IEnumerable ist können wir foreach benutzen foreach (var item in toPrint) { // Item ist ein int Console.WriteLine(item.ToString()); } } public static void OtherInterestingFeatures() { // Optionale Parameter MethodSignatures(3, 1, 3, "Ein paar", "extra", "Strings"); // setzt explizit einen bestimmten Parameter, andere werden übersprungen MethodSignatures(3, another: 3); // Erweiterungsmethoden int i = 3; i.Print(); // Weiter unten definiert // Nullables - perfekt für die Interaktion mit // Datenbanken / Rückgabewerten // Jeder Wert (d.h. keine Klassen) kann durch das Nachstellen eines ? // nullable gemacht werden: ? = int? nullable = null; // Die explizite Langform wäre Nullable Console.WriteLine("Mein Nullable: " + nullable); bool hasValue = nullable.HasValue; // true wenn nicht null // ?? ist "syntaktischer Zucker" um einen Defaultwert für den Fall // dass die Variable null ist festzulegen. int notNullable = nullable ?? 0; // 0 // Implizit typisierte Variablen // Man kann auch den Typ einer Variable auch vom Compiler // bestimmen lassen: var magic = "magic ist zur Compile-Zeit ein String, folglich geht keine Typsicherheit verloren"; magic = 9; // funktioniert nicht da magic vom Typ String ist // Generics var phonebook = new Dictionary() { {"Resi", "08822 / 43 67"} // Fügt einen Eintrag zum Telefonbuch hinzu }; // Hier könnte man auch unser generisches SetDefault von // weiter oben benutzen: Console.WriteLine(SetDefault(phonebook, "Xaver", "kein Telefon")); // kein Telefon // TKey und TValue müssen nicht zwingend angegeben werden, da sie // auch implizit vom Compiler ermittelt werden können Console.WriteLine(SetDefault(phonebook, "Resi", "kein Telefon")); // 08822 / 43 67 // Lambdas - konzise Syntax für Inline-Funktionen Func square = (x) => x * x; // Das letzte Element vom Typ T ist der Rückgabewert Console.WriteLine(square(3)); // 9 // Disposables - einfaches Management von nicht verwalteten Ressourcen // So gut wie alle Objekte die auf nicht verwaltete Ressourcen // (Dateien, Geräte, ...) zugreifen, implementieren das Interface // IDisposable. Das using Statement stellt sicher dass die vom // IDisposable benutzten Ressourcen nach der Benutzung wieder // freigegeben werden: using (StreamWriter writer = new StreamWriter("log.txt")) { writer.WriteLine("Alles bestens!"); // Am Ende des Codeblocks werden die Ressourcen wieder // freigegeben - auch im Falle einer Exception } // Parallel Klasse // http://blogs.msdn.com/b/csharpfaq/archive/2010/06/01/parallel-programming-in-net-framework-4-getting-started.aspx var websites = new string[] { "http://www.google.com", "http://www.reddit.com", "http://www.shaunmccarthy.com" }; var responses = new Dictionary(); // Für jeden Request wird ein neuer Thread erzeugt, der nächste // Schritt wird erst nach Beendigung aller Tasks ausgeführt Parallel.ForEach(websites, // maximal 3 Threads gleichzeitig new ParallelOptions() {MaxDegreeOfParallelism = 3}, website => { // Hier folgt eine langwierige, asynchrone Operation using (var r = WebRequest.Create(new Uri(website)).GetResponse()) { responses[website] = r.ContentType; } }); // Dieser Code wird erst nach Beendigung aller Requests ausgeführt foreach (var key in responses.Keys) { Console.WriteLine("{0}:{1}", key, responses[key]); } // Dynamische Objekte (gut um mit anderen Sprachen zu arbeiten) dynamic student = new ExpandoObject(); // hier muss keine Typ angegeben werden student.FirstName = "Christian"; // Einem solchen Objekt kann man sogar Methoden zuordnen. // Das Beispiel gibt einen String zurück und erwartet einen String student.Introduce = new Func( (introduceTo) => string.Format("Hallo {0}, das ist {1}", student.FirstName, introduceTo)); Console.WriteLine(student.Introduce("Bettina")); // IQueryable - So gut wie alle Aufzählungstypen implementieren // dieses Interface, welches eine Vielzahl von funktionalen Methoden // wie Map / Filter / Reduce zur Verfügung stellt: var bikes = new List(); // sortiert die Liste bikes.Sort(); // sortiert nach Anzahl Räder bikes.Sort((b1, b2) => b1.Wheels.CompareTo(b2.Wheels)); var result = bikes // diese Filter können auch aneinandergehängt werden .Where(b => b.Wheels > 3) // (gibt ein IQueryable des vorherigen Typs zurück) .Where(b => b.IsBroken && b.HasTassles) // diese Zuordnung gibt ein IQueryable zurück .Select(b => b.ToString()); // "Reduce" - addiert alle Räder der Aufzählung zu einem Wert var sum = bikes.Sum(b => b.Wheels); // So erzeugt man ein implizit typisiertes Objekt, basierend auf // den Parametern der Elemente: var bikeSummaries = bikes.Select(b=>new { Name = b.Name, IsAwesome = !b.IsBroken && b.HasTassles }); // Auch wenn wir es hier nicht demonstrieren können: // In einer IDE wie VisualStudio kriegen wir hier sogar TypeAhead, // da der Compiler in der Lage ist, die passenden Typen zu erkennen. foreach (var bikeSummary in bikeSummaries.Where(b => b.IsAwesome)) { Console.WriteLine(bikeSummary.Name); } // AsParallel-Methode // Jetzt kommen die Schmankerl! Die AsParallel-Methode kombiniert // LINQ und parallele Operationen: var threeWheelers = bikes.AsParallel().Where(b => b.Wheels == 3).Select(b => b.Name); // Diese Berechnung passiert parallel! Benötigte Threads werden // automatisch erzeugt, und die Rechenlast unter ihnen aufgeteilt. // Ein Traum für die Verarbeitung von großen Datenmengen // auf mehreren Cores! // LINQ - bildet einen Datenspeicher auf IQueryable Objekte ab // LinqToSql beispielsweise speichert und liest aus einer // SQL-Datenbank, LinqToXml aus einem XML-Dokument. // LINQ-Operationen werden "lazy" ausgeführt. var db = new BikeRepository(); // Die verzögerte Ausführung ist optimal für Datenbankabfragen var filter = db.Bikes.Where(b => b.HasTassles); // noch keine Abfrage // Es können noch mehr Filter hinzugefügt werden (auch mit // Bedingungen) - ideal für z.B. "erweiterte Suchen" if (42 > 6) { filter = filter.Where(b => b.IsBroken); // immer noch keine Abfrage } var query = filter .OrderBy(b => b.Wheels) .ThenBy(b => b.Name) .Select(b => b.Name); // auch hier: immer noch keine Abfrage // Erst hier wird die Datenbankabfrage wirklich ausgeführt, // limitiert auf die Elemente die der foreach-Loop verwendet foreach (string bike in query) { Console.WriteLine(result); } } } // Ende der Klasse LearnCSharp // Eine .cs-Datei kann auch mehrere Klassen enthalten public static class Extensions { // Erweiterungsmethoden public static void Print(this object obj) { Console.WriteLine(obj.ToString()); } } // Syntax zur Deklaration einer Klasse: // class { // // Datenfelder, Konstruktoren und Methoden leben alle // // innerhalb dieser Deklaration // } public class Bicycle { // Felder/Variablen der Klasse "Bicycle" // Das Keyword public macht das Member von überall zugänglich public int Cadence { get // get definiert eine Methode um die Eigenschaft abzurufen { return _cadence; } set // set definiert eine Methode um die Eigenschaft zu setzen { _cadence = value; // value ist der dem Setter übergebene Wert } } private int _cadence; // Das Keyword protected macht das Member nur für die Klasse selbst // und ihre Subklassen zugänglich protected virtual int Gear { get; // erzeugt eine Eigenschaft für die kein "Zwischenwert" benötigt wird set; } // Das Keyword internal macht das Member innerhalb der Assembly zugänglich internal int Wheels { get; private set; // get/set kann auch über Keywords modifiziert werden } int _speed; // Member ohne vorangestellte Keywords sind standardmäßig // private, sie sind nur innerhalb der Klasse zugänglich. // Man kann aber natürlich auch das Keyword private benutzen. private string Name { get; set; } // Ein Enum ist ein klar definierter Satz an benannten Konstanten. // Eigentlich ordnet es diese Konstanten nur bestimmten Werten zu // (einer int-Zahl, solange nicht anders angegeben). Mögliche Typen für // die Werte eines Enums sind byte, sbyte, short, ushort, int, uint, // long, oder ulong. Alle Werte in einem Enum sind eindeutig. public enum BikeBrand { Colnago, EddyMerckx, Bianchi = 42, // so kann man den Wert explizit setzen Kynast // 43 } // Nachdem dieser Typ in der Klasse "Bicycle" definiert ist, // sollte Code ausserhalb der Klasse den Typen als Bicycle.Brand referenzieren // Nachdem das Enum deklariert ist, können wir den Typen verwenden: public BikeBrand Brand; // Als static gekennzeichnete Member gehören dem Typ selbst, // nicht seinen Instanzen. Man kann sie also ohne Referenz zu einem // Objekt benutzen // Console.WriteLine("Schon " + Bicycle.BicyclesCreated + " Fahrräder, nur für dieses Tutorial!"); static public int BicyclesCreated = 0; // readonly-Werte werden zur Laufzeit gesetzt // Ihr Wert kann nur bei ihrer Deklaration, oder in einem Konstruktor // festgelegt werden readonly bool _hasCardsInSpokes = false; // readonly und private // Konstruktoren bestimmen was bei einer Instantiierung passiert. // Das ist ein Default-Konstruktor: public Bicycle() { // Member der Klasse können über das Keyword this erreicht werden this.Gear = 1; // oft ist das aber gar nicht nötig Cadence = 50; _speed = 5; Name = "Bonanzarad"; Brand = BikeBrand.Kynast; BicyclesCreated++; } // Das ist ein spezifischer Konstruktor (d.h. er erwartet Argumente): public Bicycle(int startCadence, int startSpeed, int startGear, string name, bool hasCardsInSpokes, BikeBrand brand) : base() // ruft zuerst den "base"-Konstruktor auf { Gear = startGear; Cadence = startCadence; _speed = startSpeed; Name = name; _hasCardsInSpokes = hasCardsInSpokes; Brand = brand; } // Konstruktoren können aneinandergehängt werden: public Bicycle(int startCadence, int startSpeed, BikeBrand brand) : this(startCadence, startSpeed, 0, "richtig große Räder", true, brand) { } // Syntax für Methoden: // () // Klassen können Getter und Setter für Werte definieren, // oder diese Werte direkt als Eigenschaft implementieren // (in C# der bevorzugte Weg) // Parameter von Methoden können Default-Werte haben. // "SpeedUp" kann man also auch ohne Parameter aufrufen: public void SpeedUp(int increment = 1) { _speed += increment; } public void SlowDown(int decrement = 1) { _speed -= decrement; } // Eigenschaften mit get/set // wenn es nur um den Zugriff auf Daten geht, ist eine Eigenschaft zu // empfehlen. Diese können Getter und Setter haben, oder auch nur // einen Getter bzw. einen Setter private bool _hasTassles; // private Variable public bool HasTassles // öffentliches Interface { get { return _hasTassles; } set { _hasTassles = value; } } // Das kann man auch kürzer schreiben: // Dieser Syntax erzeugt automatisch einen hinterlegten Wert, // (entsprechend `private bool _isBroken`) der gesetzt // bzw. zurückgegeben wird: public bool IsBroken { get; private set; } public int FrameSize { get; // für Getter und Setter kann der Zugriff auch einzeln // beschränkt werden, FrameSize kann also nur von innerhalb // der Klasse "Bicycle" gesetzt werden private set; } // Diese Methode gibt eine Reihe an Informationen über das Objekt aus: public virtual string ToString() { return "Gang: " + Gear + " Kadenz: " + Cadence + " Geschwindigkeit: " + _speed + " Name: " + Name + " Hipster-Karten zwischen den Speichen: " + (_hasCardsInSpokes ? "Na klar!" : "Bloß nicht!") + "\n------------------------------\n" ; } // Auch Methoden können als static gekennzeichnet werden, nützlich // beispielsweise für Helper-Methoden public static bool DidWeCreateEnoughBicyclesYet() { // In einer statischen Methode können wir natürlich auch nur // statische Member der Klasse referenzieren return BicyclesCreated > 9000; } // Wenn eine Klasse nur statische Member enthält, kann es eine gute Idee // sein die Klasse selbst als static zu kennzeichnen } // Ende der Klasse "Bicycle" // "PennyFarthing" ist eine Unterklasse von "Bicycle" class PennyFarthing : Bicycle { // (Hochräder - englisch Penny Farthing - sind diese antiken Fahrräder // mit riesigem Vorderrad. Sie haben keine Gangschaltung.) // hier wird einfach der Elternkonstruktor aufgerufen public PennyFarthing(int startCadence, int startSpeed) : base(startCadence, startSpeed, 0, "Hochrad", true, BikeBrand.EddyMerckx) { } protected override int Gear { get { return 0; } set { throw new ArgumentException("Ein Hochrad hat keine Gangschaltung, doh!"); } } public override string ToString() { string result = "Hochrad "; result += base.ToString(); // ruft die "base"-Version der Methode auf return result; } } // Interfaces (auch Schnittstellen genant) definieren nur die Signaturen // ihrer Member, enthalten aber auf keinen Fall ihre Implementierung: interface IJumpable { // Alle Member eines Interfaces sind implizit public void Jump(int meters); } interface IBreakable { // Interfaces können Eigenschaften, Methoden und Events definieren bool Broken { get; } } // Eine Klasse kann nur von einer Klasse erben, kann aber eine beliebige // Anzahl von Interfaces implementieren class MountainBike : Bicycle, IJumpable, IBreakable { int damage = 0; public void Jump(int meters) { damage += meters; } public bool Broken { get { return damage > 100; } } } // Das hier stellt eine Datenbankverbindung für das LinqToSql-Beispiel her. // EntityFramework Code First ist großartig // (ähnlich zu Ruby's ActiveRecord, aber bidirektional) // http://msdn.microsoft.com/de-de/data/jj193542.aspx public class BikeRepository : DbSet { public BikeRepository() : base() { } public DbSet Bikes { get; set; } } } // Ende des Namespaces ``` ## In dieser Übersicht nicht enthalten sind die Themen: * Flags * Attributes * Statische Eigenschaften * Exceptions, Abstraction * ASP.NET (Web Forms/MVC/WebMatrix) * Winforms * Windows Presentation Foundation (WPF) ## Zum Weiterlesen gibt es viele gute Anlaufpunkte: * [DotNetPerls](http://www.dotnetperls.com) * [C# in Depth](http://manning.com/skeet2) * [Programming C#](http://shop.oreilly.com/product/0636920024064.do) * [LINQ](http://shop.oreilly.com/product/9780596519254.do) * [MSDN Library](http://msdn.microsoft.com/en-us/library/618ayhy6.aspx) * [ASP.NET MVC Tutorials](http://www.asp.net/mvc/tutorials) * [ASP.NET Web Matrix Tutorials](http://www.asp.net/web-pages/overview/exploring-webmatrix) * [ASP.NET Web Forms Tutorials](http://www.asp.net/web-forms/tutorials) * [Windows Forms Programming in C#](http://www.amazon.com/Windows-Forms-Programming-Chris-Sells/dp/0321116208) [C# Coding Conventions](http://msdn.microsoft.com/de-de/library/vstudio/ff926074.aspx) --- language: css contributors: - ["Mohammad Valipour", "https://github.com/mvalipour"] translators: - ["Kyr", "http://github.com/kyrami"] lang: de-de filename: learncss-de.css --- In den frühen Tagen des Internets gab es keine visuellen Elemente, alles war nur reiner Text. Aber mit der Weiterentwicklung von Browsern wurden auch vollständig visuelle Webseiten zu einem Standard. Durch Verwendung von CSS lässt sich eine strikte Trennung zwischen HTML-Code und Designelementen erreichen. Kurzgefasst, CSS ermöglicht es, verschiedene HTML-Elemente innerhalb eines Dokuments auszuwählen und ihnen visuelle Eigenschaften zu geben. CSS hat wie jede andere Sprache viele Versionen. Hier fokussieren wir uns auf CSS2.0, welche nicht die neueste, aber die am weitesten verbreitete und unterstützte Version ist. **HINWEIS:** Weil die Ausgabe von CSS visuelle Eigenschaften sind, wirst du wahrscheinlich eine CSS-Sandbox wie [dabblet](http://dabblet.com/) benutzen müssen, um die Sprache richtig zu lernen. In diesem Artikel wird am meisten auf generelle Hinweise und die Syntax geachtet. ```css /* Kommentare werden in Sternchen-Schrägstrichkombinationen gepackt (genauso wie hier!) */ /* #################### ## SELEKTOREN ####################*/ /* Eigentlich ist das grundlegende CSS-Statement sehr simpel */ selektor { eigenschaft: wert; /* mehr eigenschaften...*/ } /* Der Selektor wird dazu benutzt, ein Element auf der Seite auszuwählen. Man kann aber auch alle Elemente auf einer Seite auswählen! */ * { color:red; } /* farbe:rot */ /* Angenommen wir haben folgendes Element auf einer Seite:
*/ /* kann man es so über seine Klasse auswählen */ .eine-klasse { } /* oder über beide Klassen! */ .eine-klasse.klasse2 { } /* oder über den Namen des Tags */ div { } /* oder über seine Id */ #eineId { } /* oder darüber, dass es ein Attribut hat! */ [attr] { font-size:smaller; } /* oder auch darüber, dass das Attribut einen bestimmten Wert hat */ [attr='wert'] { font-size:smaller; } /* beginnt mit dem übergebenen Wert */ [attr^='we'] { font-size:smaller; } /* endet damit */ [attr$='rt'] { font-size:smaller; } /* oder beinhaltet einen Teil davon */ [attr~='er'] { font-size:smaller; } /* Noch wichtiger ist aber die Möglichkeit, all das miteinander kombinieren zu können - man sollte hierbei nur mit der Leerzeichensetzung vorsichtig sein, ein Leerzeichen macht es zu zwei verschiedenen Selektoren */ div.eine-klasse[attr$='rt'] { } /* so ist es richtig */ /* Man kann auch ein Element über seine Elternelemente auswählen */ /* > wählt ein direktes Kind aus */ div.ein-elternteil > .klassen-name {} /* Mit einem Leerzeichen getrennt kann man alle Elternelemente ansprechen */ /* Das folgende heißt also, dass jedes Element mit der Klasse 'klassen-name' und dem Elternteil IN JEDER TIEFE ausgewählt wird */ div.ein-elternteil .klassen-name {} /* Achtung: das selbe ohne das Leerzeichen hat eine andere Bedeutung, kannst du mir sagen, was? */ div.ein-elternteil.klassen-name {} /* Man kann ein Element auch nach seinem direkten Nachbarelement auswählen */ .ich-bin-vorher + .dieses-element { } /* Oder über jedes Geschwisterelement davor */ .ich-kann-jeder-davor-sein ~ .dieses-element {} /* Mit Pseudoklassen lassen sich Elemente anhand ihres momentanen Zustands auf der Seite auswählen (anstatt über die Seitenstruktur) */ /* Zum Beispiel, wenn über ein Element mit dem Mauszeiger gefahren wird */ :hover {} /* Oder einen bereits besuchten Link*/ :visited {} /* Oder einen noch nicht besuchten Link*/ :link {} /* Oder ein Eingabeelement, das zurzeit im Fokus steht */ :focus {} /* #################### ## EIGENSCHAFTEN ####################*/ selector { /* Einheiten */ width: 50%; /* in Prozent */ font-size: 2em; /* mal der derzeitigen Schriftgröße */ width: 200px; /* in Pixeln */ font-size: 20pt; /* in Punkten */ width: 5cm; /* in Zentimetern */ width: 50mm; /* in Millimetern */ width: 5in; /* in Zoll */ /* Farben */ background-color: #F6E /* in kurzem Hex */ background-color: #F262E2 /* in langem Hex */ background-color: tomato /* kann auch eine benannte Farbe sein */ background-color: rgb(255, 255, 255) /* in RGB */ background-color: rgb(10%, 20%, 50%) /* in RGB Prozent */ background-color: rgba(255, 0, 0, 0.3); /* in semi-transparentem RGB */ /* Bilder */ background-image: url(/pfad-zum-bild/image.jpg); /* Schriften */ font-family: Arial; font-family: "Courier New"; /* wenn der Name ein Leerzeichen beinhält, kommt er in Anführungszeichen */ font-family: "Courier New", Trebuchet, Arial; /* wird die erste Schriftart nicht gefunden, wird die zweite benutzt, usw. */ } ``` ## Benutzung Speichere das CSS, das du benutzen willst, mit der Endung '.css'. ```xml
``` ## Spezifität Ein Element kann natürlich auch von mehr als einer Regel in einem Stylesheet angesprochen werdenm und kann eine Eigenschaft auch öfters als einmal zugewiesen bekommen. In diesen Fällen gibt es Regeln, die die Spezifität von Selektoren regeln. Wir haben dieses CSS: ```css /*A*/ p.klasse1[attr='wert'] /*B*/ p.klasse1 {} /*C*/ p.klasse2 {} /*D*/ p {} /*E*/ p { property: wert !important; } ``` und das folgende Markup: ```xml

``` Die Spezifität der Stile ist wie folgt: (die Spezifität gilt nur für **einzelne Eigenschaften**, nicht für ganze Blöcke) * `E` hat die größte Spezifität wegen des Schlüsselworts `!important`. man sollte diese Form aber vermeiden. * `F` ist als nächstes dran, da es direkt an dem Element definiert ist. * Dann folgt `A`, da es "spezifischer" als alle anderen ist. spezifischer = mehr Zuweisungen: 1 Tagname `p` + Klassenname `klasse1` + 1 Attribut `attr='value'` * `C` kommt als nächstes, obwohl es genau so ist wie `B`, es erscheint aber später im Stylesheet. * dann kommt `B` * und als letztes `D`. ## Kompatibilität Die meisten Features von CSS sind in allen Browsern verfügbar. Man sollte jedoch immer darauf achten die benutzten Features auf Verfügbarkeit in den vom Projekt unterstützten Browser zu überprüfen. [QuirksMode CSS](http://www.quirksmode.org/css/) oder [Can I Use](http://caniuse.com/) sind zwei der besten Quellen dafür. ## Weiterlesen * [Understanding Style Precedence in CSS: Specificity, Inheritance, and the Cascade](http://www.vanseodesign.com/css/css-specificity-inheritance-cascaade/) * [QuirksMode CSS](http://www.quirksmode.org/css/) * [Z-Index - The stacking context](https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Understanding_z_index/The_stacking_context) --- language: D filename: learnd-de.d contributors: - ["Nick Papanastasiou", "www.nickpapanastasiou.github.io"] translators: - ["Dominik Süß", "www.thesuess.me"] lang: de-de --- ```c // Es war klar dass das kommt... module hello; import std.stdio; // argumente sind optional void main(string[] args) { writeln("Hello, World!"); } ``` Wenn du so wie ich bist und viel zeit im Internet verbringst stehen die Chancen gut das du schonmal über [D](http://dlang.org/) gehört hast. Die D-Sprache ist eine moderne, überall einsetzbare programmiersprache die von Low bis High Level verwendet werden kann und dabei viele Stile anbietet. D wird aktiv von Walter Bright und Andrei Alexandrescu entwickelt, zwei super schlaue, richtig coole leute. Da das jetzt alles aus dem weg ist - auf zu den Beispielen! ```c import std.stdio; void main() { // Logische Ausdrücke und Schleifen funktionieren wie erwartet for(int i = 0; i < 10000; i++) { writeln(i); } auto n = 1; // auto um den typ vom Compiler bestimmen zu lassen // Zahlenliterale können _ verwenden für lesbarkeit while(n < 10_000) { n += n; } do { n -= (n / 2); } while(n > 0); // For und while sind ja schön und gut aber D bevorzugt foreach // Die '..' erstellen eine Spanne von Zahlen, inklusive dem ersten Wert // jedoch ohne dem letzten foreach(i; 1..1_000_000) { if(n % 2 == 0) writeln(i); } // Es gibt auch ein 'foreach_reverse' wenn du rückwerts gehen willst. foreach_reverse(i; 1..int.max) { if(n % 2 == 1) { writeln(i); } else { writeln("No!"); } } } ``` Neue Typen können mit `struct`, `class`, `union`, und `enum` definiert werden. Structs und unions werden as-value (koppiert) an methoden übergeben wogegen Klassen als Referenz übergeben werden. Templates können verwendet werden um alle typen zu parameterisieren. ```c // Hier, T ist ein Type-Parameter, Er funktioniert wie Generics in C#/Java/C++ struct LinkedList(T) { T data = null; LinkedList!(T)* next; // Das ! wird verwendet um T zu übergeben. ( in C#/Java/C++) } class BinTree(T) { T data = null; // Wenn es nur einen T parameter gibt können die Klammern um ihn weggelassen werden BinTree!T left; BinTree!T right; } enum Day { Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, } // Aliase können verwendet werden um die Entwicklung zu erleichtern alias IntList = LinkedList!int; alias NumTree = BinTree!double; // Funktionen können genau so Templates beinhalten T max(T)(T a, T b) { if(a < b) return b; return a; } // Steht ref vor einem Parameter wird sichergestellt das er als Referenz übergeben wird. // Selbst bei werten wird es immer eine Referenz sein. void swap(T)(ref T a, ref T b) { auto temp = a; a = b; b = temp; } // Templates können ebenso werte parameterisieren. class Matrix(uint m, uint n, T = int) { T[m] rows; T[n] columns; } auto mat = new Matrix!(3, 3); // Standardmäßig ist T vom typ Integer ``` Wo wir schon bei Klassen sind - Wie wäre es mit Properties! Eine Property ist eine Funktion die wie ein Wert agiert. Das gibt uns viel klarere Syntax im Stil von `structure.x = 7` was gleichgültig wäre zu `structure.setX(7)` ```c // Diese Klasse ist parameterisiert mit T, U class MyClass(T, U) { T _data; U _other; } // Ihre Getter und Setter Methoden sehen so aus class MyClass(T, U) { T _data; U _other; // Konstruktoren heißen immer `this` this(T t, U u) { data = t; other = u; } // getters @property T data() { return _data; } @property U other() { return _other; } // setters // @property kann genauso gut am ende der Methodensignatur stehen void data(T t) @property { _data = t; } void other(U u) @property { _other = u; } } // Und so kann man sie dann verwenden void main() { auto mc = MyClass!(int, string); mc.data = 7; mc.other = "seven"; writeln(mc.data); writeln(mc.other); } ``` Mit properties können wir sehr viel logik hinter unseren gettern und settern hinter einer schönen syntax verstecken Other object-oriented goodies at our disposal Andere Objektorientierte features sind beispielsweise `interface`s, `abstract class` und `override`. Vererbung funktioniert in D wie in Java: Erben von einer Klasse, so viele interfaces wie man will. Jetzt haben wir Objektorientierung in D gesehen aber schauen wir uns noch was anderes an. D bietet funktionale programmierung mit _first-class functions_ puren funktionen und unveränderbare daten. Zusätzlich können viele funktionale Algorithmen wie z.B map, filter, reduce und friends im `std.algorithm` Modul gefunden werden! ```c import std.algorithm : map, filter, reduce; import std.range : iota; // builds an end-exclusive range void main() { // Wir wollen die summe aller quadratzahlen zwischen // 1 und 100 ausgeben. Nichts leichter als das! // Einfach eine lambda funktion als template parameter übergeben // Es ist genau so gut möglich eine normale funktion hier zu übergeben // Lambdas bieten sich hier aber an. auto num = iota(1, 101).filter!(x => x % 2 == 0) .map!(y => y ^^ 2) .reduce!((a, b) => a + b); writeln(num); } ``` Ist dir aufgefallen wie wir eine Haskell-Style pipeline gebaut haben um num zu berechnen? Das war möglich durch die Uniform Function Call Syntax. Mit UFCS können wir auswählen ob wir eine Funktion als Methode oder als freie Funktion aufrufen. Walters artikel dazu findet ihr [hier.](http://www.drdobbs.com/cpp/uniform-function-call-syntax/232700394) Kurzgesagt kann man Funktionen deren erster parameter vom typ A ist, als Methode auf A anwenden. Parrallel Computing ist eine Tolle sache, findest du nicht auch? ```c import std.stdio; import std.parallelism : parallel; import std.math : sqrt; void main() { // Wir wollen die Wurzel von jeder Zahl in unserem Array berechnen // und dabei alle Kerne verwenden die wir zur verfügung haben auto arr = new double[1_000_000]; // Wir verwenden den index und das element als referenz // und rufen einfach parallel auf! foreach(i, ref elem; parallel(arr)) { ref = sqrt(i + 1.0); } } ``` --- language: elixir contributors: - ["Joao Marques", "http://github.com/mrshankly"] translators: - ["Gregor Große-Bölting", "http://www.ideen-und-soehne.de"] filename: learnelixir-de.ex lang: de-de --- Elixir ist eine moderne, funktionale Sprache für die Erlang VM. Sie ist voll kompatibel mit Erlang, verfügt aber über eine freundlichere Syntax und bringt viele Features mit. ```ruby # Einzeilige Kommentare werden mit der Raute gesetzt. # Es gibt keine mehrzeiligen Kommentare; # es ist aber problemlos möglich mehrere einzeilige Kommentare hintereinander # zu setzen (so wie hier). # Mit 'iex' ruft man die Elixir-Shell auf. # Zum kompilieren von Modulen dient der Befehl 'elixirc'. # Beide Befehle sollten als Umgebungsvariable gesetzt sein, wenn Elixir korrekt # installiert wurde. ## --------------------------- ## -- Basistypen ## --------------------------- # Es gibt Nummern: 3 # Integer 0x1F # Integer 3.0 # Float # Atome, das sind Literale, sind Konstanten mit Namen. Sie starten mit einem # ':'. :hello # Atom # Außerdem gibt es Tupel, deren Werte im Arbeitsspeicher vorgehalten werden. {1,2,3} # Tupel # Die Werte innerhalb eines Tupels können mit der 'elem'-Funktion ausgelesen # werden: elem({1, 2, 3}, 0) # => 1 # Listen sind als verkettete Listen implementiert. [1, 2, 3] # list # Auf Kopf und Rest einer Liste kann wie folgt zugegriffen werden: [ kopf | rest ] = [1,2,3] kopf # => 1 rest # => [2, 3] # In Elixir, wie auch in Erlang, kennzeichnet '=' ein 'pattern matching' # (Musterabgleich) und keine Zuweisung. # Das heißt, dass die linke Seite auf die rechte Seite 'abgeglichen' wird. # Auf diese Weise kann im Beispiel oben auf Kopf und Rest der Liste zugegriffen # werden. # Ein Musterabgleich wird einen Fehler werfen, wenn die beiden Seiten nicht # zusammenpassen. # Im folgenden Beispiel haben die Tupel eine unterschiedliche Anzahl an # Elementen: {a, b, c} = {1, 2} #=> ** (MatchError) no match of right hand side value: {1,2} # Es gibt außerdem 'binaries', <<1,2,3>> # binary. # Strings und 'char lists' "hello" # String 'hello' # Char-Liste # ... und mehrzeilige Strings """ Ich bin ein mehrzeiliger String. """ #=> "Ich bin ein\nmehrzeiliger String.\n" # Alles Strings werden in UTF-8 enkodiert: "héllò" #=> "héllò" # Eigentlich sind Strings in Wahrheit nur binaries und 'char lists' einfach # Listen. <> #=> "abc" [?a, ?b, ?c] #=> 'abc' # In Elixir gibt `?a` den ASCII-Integer für den Buchstaben zurück. ?a #=> 97 # Um Listen zu verbinden gibt es den Operator '++', für binaries nutzt man '<>' [1,2,3] ++ [4,5] #=> [1,2,3,4,5] 'hello ' ++ 'world' #=> 'hello world' <<1,2,3>> <> <<4,5>> #=> <<1,2,3,4,5>> "hello " <> "world" #=> "hello world" ## --------------------------- ## -- Operatoren ## --------------------------- # Einfache Arithmetik 1 + 1 #=> 2 10 - 5 #=> 5 5 * 2 #=> 10 10 / 2 #=> 5.0 # In Elixir gibt der Operator '/' immer einen Float-Wert zurück. # Für Division mit ganzzahligen Ergebnis gibt es 'div' div(10, 2) #=> 5 # Um den Rest der ganzzahligen Division zu erhalten gibt es 'rem' rem(10, 3) #=> 1 # Natürlich gibt es auch Operatoren für Booleans: 'or', 'and' und 'not'. Diese # Operatoren erwarten einen Boolean als erstes Argument. true and true #=> true false or true #=> true # 1 and true #=> ** (ArgumentError) argument error # Elixir bietet auch '||', '&&' und '!', die Argumente jedweden Typs # akzeptieren. Alle Werte außer 'false' und 'nil' werden zu wahr evaluiert. 1 || true #=> 1 false && 1 #=> false nil && 20 #=> nil !true #=> false # Für Vergleiche gibt es die Operatoren `==`, `!=`, `===`, `!==`, `<=`, `>=`, # `<` und `>` 1 == 1 #=> true 1 != 1 #=> false 1 < 2 #=> true # '===' und '!==' sind strikter beim Vergleich von Integern und Floats: 1 == 1.0 #=> true 1 === 1.0 #=> false # Es ist außerdem möglich zwei verschiedene Datentypen zu vergleichen: 1 < :hello #=> true # Die gesamte Ordnung über die Datentypen ist wie folgt definiert: # number < atom < reference < functions < port < pid < tuple < list < bitstring # Um Joe Armstrong zu zitieren: "The actual order is not important, but that a # total ordering is well defined is important." ## --------------------------- ## -- Kontrollstrukturen ## --------------------------- # Es gibt die `if`-Verzweigung if false do "Dies wird nie jemand sehen..." else "...aber dies!" end # ...und ebenso `unless` unless true do "Dies wird nie jemand sehen..." else "...aber dies!" end # Du erinnerst dich an 'pattern matching'? Viele Kontrollstrukturen in Elixir # arbeiten damit. # 'case' erlaubt es uns Werte mit vielerlei Mustern zu vergleichen. case {:one, :two} do {:four, :five} -> "Das wird nicht passen" {:one, x} -> "Das schon und außerdem wird es ':two' dem Wert 'x' zuweisen." _ -> "Dieser Fall greift immer." end # Es ist eine übliche Praxis '_' einen Wert zuzuweisen, sofern dieser Wert # nicht weiter verwendet wird. # Wenn wir uns zum Beispiel nur für den Kopf einer Liste interessieren: [kopf | _] = [1,2,3] kopf #=> 1 # Für bessere Lesbarkeit können wir auch das Folgende machen: [kopf | _rest] = [:a, :b, :c] kopf #=> :a # Mit 'cond' können diverse Bedingungen zur selben Zeit überprüft werden. Man # benutzt 'cond' statt viele if-Verzweigungen zu verschachteln. cond do 1 + 1 == 3 -> "Ich werde nie aufgerufen." 2 * 5 == 12 -> "Ich auch nicht." 1 + 2 == 3 -> "Aber ich!" end # Es ist üblich eine letzte Bedingung einzufügen, die immer zu wahr evaluiert. cond do 1 + 1 == 3 -> "Ich werde nie aufgerufen." 2 * 5 == 12 -> "Ich auch nicht." true -> "Aber ich! (dies ist im Grunde ein 'else')" end # 'try/catch' wird verwendet um Werte zu fangen, die zuvor 'geworfen' wurden. # Das Konstrukt unterstützt außerdem eine 'after'-Klausel die aufgerufen wird, # egal ob zuvor ein Wert gefangen wurde. try do throw(:hello) catch nachricht -> "#{nachricht} gefangen." after IO.puts("Ich bin die 'after'-Klausel.") end #=> Ich bin die 'after'-Klausel. # ":hello gefangen" ## --------------------------- ## -- Module und Funktionen ## --------------------------- # Anonyme Funktionen (man beachte den Punkt) square = fn(x) -> x * x end square.(5) #=> 25 # Anonyme Funktionen unterstützen auch 'pattern' und 'guards'. Guards erlauben # es die Mustererkennung zu justieren und werden mit dem Schlüsselwort 'when' # eingeführt: f = fn x, y when x > 0 -> x + y x, y -> x * y end f.(1, 3) #=> 4 f.(-1, 3) #=> -3 # Elixir bietet zahlreiche eingebaute Funktionen. Diese sind im gleichen # Geltungsbereich ('scope') verfügbar. is_number(10) #=> true is_list("hello") #=> false elem({1,2,3}, 0) #=> 1 # Mehrere Funktionen können in einem Modul gruppiert werden. Innerhalb eines # Moduls ist es möglich mit dem Schlüsselwort 'def' eine Funktion zu # definieren. defmodule Math do def sum(a, b) do a + b end def square(x) do x * x end end Math.sum(1, 2) #=> 3 Math.square(3) #=> 9 # Um unser einfaches Mathe-Modul zu kompilieren muss es unter 'math.ex' # gesichert werden. Anschließend kann es mit 'elixirc' im Terminal aufgerufen # werden: elixirc math.ex # Innerhalb eines Moduls definieren wir private Funktionen mit 'defp'. Eine # Funktion, die mit 'def' erstellt wurde, kann von anderen Modulen aufgerufen # werden; eine private Funktion kann nur lokal angesprochen werden. defmodule PrivateMath do def sum(a, b) do do_sum(a, b) end defp do_sum(a, b) do a + b end end PrivateMath.sum(1, 2) #=> 3 # PrivateMath.do_sum(1, 2) #=> ** (UndefinedFunctionError) # Auch Funktionsdeklarationen unterstützen 'guards' und Mustererkennung: defmodule Geometry do def area({:rectangle, w, h}) do w * h end def area({:circle, r}) when is_number(r) do 3.14 * r * r end end Geometry.area({:rectangle, 2, 3}) #=> 6 Geometry.area({:circle, 3}) #=> 28.25999999999999801048 # Geometry.area({:circle, "not_a_number"}) #=> ** (FunctionClauseError) no function clause matching in Geometry.area/1 # Wegen der Unveränderlichkeit von Variablen ist Rekursion ein wichtiger # Bestandteil von Elixir. defmodule Recursion do def sum_list([head | tail], acc) do sum_list(tail, acc + head) end def sum_list([], acc) do acc end end Recursion.sum_list([1,2,3], 0) #=> 6 # Elixir-Module unterstützen Attribute. Es gibt eingebaute Attribute, ebenso # ist es möglich eigene Attribute hinzuzufügen. defmodule MyMod do @moduledoc """ Dies ist ein eingebautes Attribut in einem Beispiel-Modul """ @my_data 100 # Dies ist ein selbst-definiertes Attribut. IO.inspect(@my_data) #=> 100 end ## --------------------------- ## -- 'Records' und Ausnahmebehandlung ## --------------------------- # 'Records' sind im Grunde Strukturen, die es erlauben einem Wert einen eigenen # Namen zuzuweisen. defrecord Person, name: nil, age: 0, height: 0 joe_info = Person.new(name: "Joe", age: 30, height: 180) #=> Person[name: "Joe", age: 30, height: 180] # Zugriff auf den Wert von 'name' joe_info.name #=> "Joe" # Den Wert von 'age' überschreiben joe_info = joe_info.age(31) #=> Person[name: "Joe", age: 31, height: 180] # Der 'try'-Block wird zusammen mit dem 'rescue'-Schlüsselwort dazu verwendet, # um Ausnahmen beziehungsweise Fehler zu behandeln. try do raise "Irgendein Fehler." rescue RuntimeError -> "Laufzeit-Fehler gefangen." _error -> "Und dies fängt jeden Fehler." end # Alle Ausnahmen haben das Attribut 'message' try do raise "ein Fehler" rescue x in [RuntimeError] -> x.message end ## --------------------------- ## -- Nebenläufigkeit ## --------------------------- # Elixir beruht auf dem Aktoren-Model zur Behandlung der Nebenläufigkeit. Alles # was man braucht um in Elixir nebenläufige Programme zu schreiben sind drei # Primitive: Prozesse erzeugen, Nachrichten senden und Nachrichten empfangen. # Um einen neuen Prozess zu erzeugen nutzen wir die 'spawn'-Funktion, die # wiederum eine Funktion als Argument entgegen nimmt. f = fn -> 2 * 2 end #=> #Function spawn(f) #=> #PID<0.40.0> # 'spawn' gibt eine pid (einen Identifikator des Prozesses) zurück. Diese kann # nun verwendet werden, um Nachrichten an den Prozess zu senden. Um # zu senden nutzen wir den '<-' Operator. Damit das alles Sinn macht müssen wir # in der Lage sein Nachrichten zu empfangen. Dies wird mit dem # 'receive'-Mechanismus sichergestellt: defmodule Geometry do def area_loop do receive do {:rectangle, w, h} -> IO.puts("Area = #{w * h}") area_loop() {:circle, r} -> IO.puts("Area = #{3.14 * r * r}") area_loop() end end end # Kompiliere das Modul, starte einen Prozess und gib die 'area_loop' Funktion # in der Shell mit, etwa so: pid = spawn(fn -> Geometry.area_loop() end) #=> #PID<0.40.0> # Sende eine Nachricht an die 'pid', die ein Muster im 'receive'-Ausdruck # erfüllt: pid <- {:rectangle, 2, 3} #=> Area = 6 # {:rectangle,2,3} pid <- {:circle, 2} #=> Area = 12.56000000000000049738 # {:circle,2} # Die Shell selbst ist ein Prozess und mit dem Schlüsselwort 'self' kann man # die aktuelle pid herausfinden. self() #=> #PID<0.27.0> ``` ## Referenzen und weitere Lektüre * [Getting started guide](http://elixir-lang.org/getting_started/1.html) auf der [elixir Website](http://elixir-lang.org) * [Elixir Documentation](http://elixir-lang.org/docs/master/) * ["Learn You Some Erlang for Great Good!"](http://learnyousomeerlang.com/) von Fred Hebert * "Programming Erlang: Software for a Concurrent World" von Joe Armstrong --- category: tool tool: git contributors: - ["Jake Prather", "http://github.com/JakeHP"] translators: - ["kultprok", "http://www.kulturproktologie.de"] lang: de-de --- Git ist eine verteilte Versions- und Quellcodeverwaltung. Es nimmt Schnappschüsse der Projekte, um mit diesen Schnappschüssen verschiedene Versionen unterscheiden und den Quellcode verwalten zu können. Anmerkung des Übersetzers: Einige englische Begriffe wie *Repository*, *Commit* oder *Head* sind idiomatische Bestandteile im Umgang mit Git. Sie wurden nicht übersetzt. ## Konzepte der Versionsverwaltung ### Was ist Versionsverwaltung? Eine Versionsverwaltung erfasst die Änderungen einer Datei oder eines Verzeichnisses im Verlauf der Zeit. ### Zentrale im Vergleich mit verteilter Versionverwaltung * Zentrale Versionsverwaltung konzentriert sich auf das Synchronisieren, Verfolgen und Sichern von Dateien. * Verteilte Versionsverwaltung konzentriert sich auf das Teilen der Änderungen. Jede Änderung hat eine eindeutige ID. * Verteilte Systeme haben keine vorbestimmte Struktur. Ein SVN-ähnliches, zentrales System wäre mit Git ebenso umsetzbar. [Weiterführende Informationen](http://git-scm.com/book/en/Getting-Started-About-Version-Control) ### Warum Git? * Ist offline einsetzbar. * Einfache Kollaboration! * Branching ist einfach! * Branching ist schnell! * Merging ist einfach! * Git ist schnell. * Git ist flexibel. ## Die Architektur von Git ### Repository (Repo) Ein Satz von Dateien, Verzeichnisen, Historieneinträgen, Commits und Heads. Stell es dir wie eine Quellcode-Datenstruktur vor, unter anderem mit der Eigenschaft, dass alle *Elemente* dir Zugriff auf die Revisionshistorie geben. Ein Repository besteht in Git aus dem .git-Verzeichnis und dem Arbeitsverzeichnis. ### .git-Verzeichnis (Teil des Repositorys) Das .git-Verzeichnis enthält alle Einstellung, Logs, Branches, den HEAD und mehr. [Ausführliche Übersicht](http://gitready.com/advanced/2009/03/23/whats-inside-your-git-directory.html) ### Arbeitsverzeichnis (Teil des Repositorys) Dies sind die Verzeichnisse und Dateien in deinem Repository, also z.B. dein Programmcode. ### Index (Teil des .git-Verzeichnisses) Der Index ist die Staging-Area von Git. Es ist im Grunde eine Ebene, die Arbeitsverzeichnis vom Repository trennt. Sie gibt Entwicklern mehr Einfluss darüber, was ins Git-Repository eingeht. ### Commit Ein Commit ist ein Schnappschuss von Änderungen in deinem Arbeitsverzeichnis. Wenn du zum Beispiel 5 Dateien hinzugefügt und 2 andere entfernt hast, werden diese Änderungen im Commit (Schnappschuss) enthalten sein. Dieser Commit kann dann in andere Repositories gepusht werden. Oder nicht! ### Branch Ein Branch, ein Ast oder Zweig, ist im Kern ein Pointer auf den letzten Commit, den du gemacht hast. Während des Commits wird der Pointer automatisch auf Stand gebracht und zeigt dann auf den neuen letzten Commit. ### HEAD und head (Teil des .git-Verzeichnisses) HEAD ist ein Pointer auf den aktuellen Branch. Ein Repository hat nur einen *aktiven* HEAD. Ein *head* ist ein Pointer, der auf einen beliebigen Commit zeigt. Ein Repository kann eine beliebige Zahl von *heads* enthalten. ### Konzeptionelle Hintergründe * [Git For Computer Scientists](http://eagain.net/articles/git-for-computer-scientists/) * [Git For Designers](http://hoth.entp.com/output/git_for_designers.html) ## Befehle ### init Erstelle ein leeres Git-Repository im aktuellen Verzeichnis. Die Einstellungen, gespeicherte Informationen und mehr zu diesem Git-Repository werden in einem Verzeichnis namens *.git* angelegt. ```bash $ git init ``` ### config Hiermit werden Einstellungen vorgenommen. Dies kann das Repository, das System selbst oder globale Einstellungen betreffen. ```bash # Grundlegende Config-Variablen ausgeben und setzen $ git config --global user.email $ git config --global user.name $ git config --global user.email "MyEmail@Zoho.com" $ git config --global user.name "My Name" ``` [Mehr über git config](http://git-scm.com/docs/git-config) ### help Schnellzugriff auf extrem detaillierte Anleitungen zu allen Befehlen. Oder als Erinnerung zu semantischen Eigenheiten. ```bash # Übersicht gängiger Befehle $ git help # Übersicht aller verfügbaren Befehle $ git help -a # Befehlspezifische Hilfe - Bedienungsanleitung # git help $ git help add $ git help commit $ git help init ``` ### status Zeigt die Unterschiede zwischen Index (im Grunde dein Arbeitsverzeichnis/-repository) und dem aktuellen HEAD an. ```bash # Zeigt den Branch, nicht-verfolgte Dateien, Änderungen und andere Unterschiede an $ git status # Anderes Wissenswertes über git status anzeigen $ git help status ``` ### add Hinzufügen von Dateien zum Arbeitsverzeichnis/-repository. Wenn du neue Dateien nicht mit *git add* zum Arbeitsverzeichnis hinzufügst, werden sie nicht in den Commit aufgenommen! ```bash # Fügt eine Datei deinem aktuellen Arbeitsverzeichnis hinzu $ git add HelloWorld.java # Fügt eine Datei aus einem verschachtelten Verzeichnis hinzu $ git add /path/to/file/HelloWorld.c # Reguläre Ausdrücke werden unterstützt! $ git add ./*.java ``` ### branch Verwalte alle Branches. Du kannst sie mit diesem Befehl ansehen, bearbeiten, neue erzeugen oder löschen. ```bash # Liste alle bestehenden Branches und Remotes auf $ git branch -a # Erstelle einen neuen Branch $ git branch myNewBranch # Lösche einen Branch $ git branch -d myBranch # Benenne einen Branch um # git branch -m $ git branch -m myBranchName myNewBranchName # Ändere die Beschreibung eines Branchs $ git branch myBranchName --edit-description ``` ### checkout Bringt alle Dateien im Arbeitsverzeichnis auf den Stand des Index oder des angegebenen Branches. ```bash # Ein Repo auschecken - wenn nicht anders angegeben ist das der master $ git checkout # Eine Datei auschecken - sie befindet sich dann auf dem aktuellen Stand im Repository $ git checkout /path/to/file # Einen bestimmten Branch auschecken $ git checkout branchName # Erstelle einen neuen Branch und wechsle zu ihm. Wie: "git branch ; git checkout " $ git checkout -b newBranch ``` ### clone Ein bestehendes Repository in ein neues Verzeichnis klonen oder kopieren. Es fügt außerdem für jedes geklonte Repository remote-tracking Branches hinzu. Du kannst auf diese Remote-Branches pushen. ```bash # Klone learnxinyminutes-docs $ git clone https://github.com/adambard/learnxinyminutes-docs.git ``` ### commit Speichert die aktuellen Inhalte des Index in einen neuen *Commit*. Dieser Commit enthält alle Änderungen und eine vom Benutzer erstellte Beschreibung der Änderungen. ```bash # Commit mit Beschreibung erstellen. $ git commit -m "Added multiplyNumbers() function to HelloWorld.c" ``` ### diff Zeigt die Unterschiede zwischen Dateien von Arbeitsverzeichnisse, dem Index und Commits an. ```bash # Unterschiede zwischen deinem Arbeitsverzeichnis und dem Index anzeigen $ git diff # Unterschiede zwischen dem Index und dem aktuellsten Commit anzeigen $ git diff --cached # Unterschiede zwischen deinem Arbeitsverzeichnis und dem aktuellsten Commit anzeigen $ git diff HEAD # Unterschiede zwischen dem Index und dem aktuellsten Commit (betrifft nur Dateien im Index) $ git diff --staged ``` ### grep Schnell ein Repository durchsuchen. Optionale Einstellungen: ```bash # Vielen Dank an Travis Jeffery für die Hinweise. # Zeilennummerierung in grep-Suchergebnissen $ git config --global grep.lineNumber true # Suchergebnisse lesbarer gestalten, auch Gruppierungen sind möglich $ git config --global alias.g "grep --break --heading --line-number" ``` ```bash # Suche nach "variableName" in allen java-Dateien $ git grep 'variableName' -- '*.java' # Suche nach eine Zeile, die "arrayListName" und "add" oder "remove" enthält $ git grep -e 'arrayListName' --and \( -e add -e remove \) ``` Google ist dein Freund; für mehr Beispiele: [Git Grep Ninja](http://travisjeffery.com/b/2012/02/search-a-git-repo-like-a-ninja) ### log Zeige Commits für das Repository an. ```bash # Zeige alle Commits $ git log # Zeige die Anzahl n an Commits $ git log -n 10 # Zeige nur Merges an $ git log --merges ``` ### merge *Merge*, also verschmelze, alle Änderungen von externen Commits in den aktuellen Branch. ```bash # Merge den angegebenen Branch in den aktuellen. $ git merge branchName # Erstelle immer einen Merge-Commit. $ git merge --no-ff branchName ``` ### mv Eine Datei umbenennen oder verschieben. ```bash # Umbenennen $ git mv HelloWorld.c HelloNewWorld.c # Verschieben $ git mv HelloWorld.c ./new/path/HelloWorld.c # Umbenennung oder Verschieben erzwingen # "existingFile" besteht schon im Verzeichnis, wird überschrieben mit "myFile" $ git mv -f myFile existingFile ``` ### pull Führe einen Pull (zieht alle Daten eines Repositories) aus und führt einen Merge mit einem anderen Branch durch. ```bash # Update deines lokalen Repos, indem ein Merge der neuen Änderungen # von den remote-liegenden "origin"- und "master"-Branches durchgeführt wird. # git pull # git pull => impliziter Verweis auf origin und master $ git pull origin master # Führt einen Merge von Änderungen eines remote-Branch und ein Rebase # des Branch-Commits im lokalen Repo durch. Wie: pull , git rebase " $ git pull origin master --rebase ``` ### push Führe einen Push, ein Hochladen, und einen Merge von Änderungen eines remote-Branch mit einem Branch aus. ```bash # Führe Push und Merge von Änderungen des lokalen Repo zu einem # remote-Branch namens "origin" und dem "master"-Branch aus. # git push # git push => impliziter Verweis auf => git push origin master $ git push origin master ``` ### rebase (mit Vorsicht einsetzen) Nimm alle Änderungen, die in einem Branch durch Commits vorgenommen wurden, und übertrage sie auf einen anderen Branch. Achtung: Führe keinen Rebase von Commits durch, die auf ein öffentliches Repo gepusht wurden. ```bash # Rebase "experimentBranch" in den "master"-Branch # git rebase $ git rebase master experimentBranch ``` [Weiterführende Informationen](http://git-scm.com/book/en/Git-Branching-Rebasing) ### reset (mit Vorsicht einsetzen) Setze den aktuellen HEAD auf den angegebenen Zustand zurück. So können Merges, Pulls, Commits, Hinzufügungen und andere Änderungen rückgängig gemacht werden. Es ist ein hervorragender Befehl, aber auch sehr gefährlich, wenn du nicht weißt, was du tust. ```bash # Setze die Staging-Area zurück, um dem letzten Commit zu entsprechen (das Verzeichnis bleibt unberührt) $ git reset # Setze die Staging-Area zurück, um dem letzten Commit zu entsprechen und überschreibe das Arbeitsverzeichnis $ git reset --hard # Bewegt die Spitze des Branches zu dem angegebenen Commit (das Verzeichnis bleibt unberührt) # Alle Änderungen bleiben im Verzeichnis erhalten $ git reset 31f2bb1 # Bewegt die Spitze des Branches zurück zu dem angegebenen Commit # und gleicht die Arbeitsverzeichnisse ab (löscht nicht vom Commit erfasste Änderungen und alle Commits, # die dem angegebenen Commit folgen). $ git reset --hard 31f2bb1 ``` ### rm Das Gegenteil von *git add*. *git rm* löscht Dateien vom Arbeitsverzeichnis. ```bash # Entferne HelloWorld.c $ git rm HelloWorld.c # Entferne eine Datei aus einem verschachtelten Verzeichnis $ git rm /pather/to/the/file/HelloWorld.c ``` ## Weiterführende Informationen * [tryGit - A fun interactive way to learn Git.](http://try.github.io/levels/1/challenges/1) * [git-scm - Video Tutorials](http://git-scm.com/videos) * [git-scm - Documentation](http://git-scm.com/docs) * [Atlassian Git - Tutorials & Workflows](https://www.atlassian.com/git/) * [SalesForce Cheat Sheet](https://na1.salesforce.com/help/doc/en/salesforce_git_developer_cheatsheet.pdf) * [GitGuys](http://www.gitguys.com/) * [gitflow - Ein Modell um mit Branches zu arbeiten](http://nvie.com/posts/a-successful-git-branching-model/) --- language: Go filename: learngo-de.go contributors: - ["Joseph Adams", "https://github.com/jcla1"] - ["Dennis Keller", "https://github.com/denniskeller"] translators: - ["Jerome Meinke", "https://github.com/jmeinke"] lang: de-de --- Die Sprache Go (auch golang) wurde von Google entwickelt und wird seit 2007 benutzt. Go ähnelt in der Syntax der Sprache C, bietet darüber hinaus aber viele Vorteile. Einerseits verzichtet Go auf Speicherarithmetik und benutzt einen Garbage Collector. Andererseits enthält Go native Sprachelemente für die Unterstützung von Nebenläufigkeit. Durch den Fokus auf einen schnellen Kompilierprozess wird außerdem die Softwareentwicklung in Großprojekten erleichtert. Außerdem beinhaltet Go eine gut ausgestattete Standardbibliothek und hat eine aktive Community. ```go // Einzeiliger Kommentar /* Mehr- zeiliger Kommentar */ // Wie bei Java gehört jede Quelldatei einem Paket an (Modularisierung). // "main" ist ein besonderer Paketname, da er ein ausführbares Programm // einleitet, im Gegensatz zu jedem anderen Namen, der eine Bibliothek // deklariert. package main // Ein "import" wird verwendet, um Pakete zu deklarieren, die in dieser // Quelldatei Anwendung finden. import ( "fmt" // Ein Paket in der Go Standardbibliothek "net/http" // Ja, ein Webserver. "strconv" // Zeichenkettenmanipulation ) // Es folgt die Definition einer Funktion, in diesem Fall von "main". Auch hier // ist der Name wieder besonders. "main" markiert den Eintrittspunkt des // Programms. func main() { // Println gibt eine Zeile zu stdout aus. // Der Prefix "fmt" bestimmt das Paket aus welchem die Funktion stammt. fmt.Println("Hello world!") // Aufruf einer weiteren Funktion definiert innerhalb dieses Pakets. beyondHello() } // Funktionen können Parameter akzeptieren. Diese werden in Klammern deklariert, // die aber auch ohne Parameter erforderlich sind. func beyondHello() { var x int // Deklaration einer Variable, muss vor Gebrauch geschehen. x = 3 // Zuweisung eines Werts. // Kurze Deklaration: Benutzen Sie ":=", um die Typisierung automatisch zu // folgern, die Variable zu deklarieren und ihr einen Wert zuzuweisen. y := 4 // Eine Funktion mit mehreren Rückgabewerten. sum, prod := learnMultiple(x, y) fmt.Println("sum:", sum, "prod:", prod) // Simple Ausgabe learnTypes() // In < y Minuten lernen Sie mehr! } // Funktionen können mehrere Parameter und (mehrere!) Rückgabewerte haben. func learnMultiple(x, y int) (sum, prod int) { return x + y, x * y // Wiedergabe zweier Werte } // Überblick über einige eingebaute Typen und Literale. func learnTypes() { // Kurze Deklarationen sind die Norm. s := "Lernen Sie Go!" // Zeichenketten-Typ s2 := `Eine "raw" Zeichenkette kann Zeilenumbrüche beinhalten.` // Selber Zeichenketten-Typ // nicht-ASCII Literal. Go Quelltext ist UTF-8 kompatibel. g := 'Σ' // Ein Runen-Typ, alias int32, gebraucht für unicode code points. f := 3.14195 // float64, eine IEEE-754 64-bit Dezimalzahl c := 3 + 4i // complex128, besteht intern aus zwei float64-er // "var"-Syntax mit Initalwert var u uint = 7 // Vorzeichenlos, aber die Größe ist implementationsabhängig var pi float32 = 22. / 7 // Umwandlungs-Syntax mit kurzer Deklaration n := byte('\n') // byte ist ein Alias für uint8 // Arrays haben bei Kompile-Zeit festgelegte Größen var a4 [4]int // Ein Array mit 4 ints, alle mit Initialwert 0 a3 := [...]int{3, 1, 5} // Ein Array mit 4 ints, Initialwerte wie angezeigt // "slices" haben eine dynamische Größe. Arrays und Slices haben beide ihre // Vorzüge, aber slices werden viel häufiger verwendet s3 := []int{4, 5, 9} // Vergleichen Sie mit a3, hier: keine Ellipse s4 := make([]int, 4) // Weist Speicher für 4 ints zu, alle mit Wert 0 var d2 [][]float64 // Nur eine Deklaration, keine Speicherzuweisung bs := []byte("eine slice") // Umwandlungs-Syntax p, q := learnMemory() // Deklariert p & q als Zeiger zu einer int. fmt.Println(*p, *q) // Die gibt die zwei Werte aus. "*" für den Zugriff // "Maps" sind dynamische Datenstrukturen mit variabler Größe. Sie sind wie // "hashs" oder "dictionaries" aus anderen Sprachen. m := map[string]int{"drei": 3, "vier": 4} m["eins"] = 1 // Ungebrauchte Variablen sind Fehler in Go // Der Unterstrich wird verwendet, um einen Wert zu verwerfen. _, _, _, _, _, _, _, _, _ = s2, g, f, u, pi, n, a3, s4, bs // Die Ausgabe zählt natürlich auch als Gebrauch fmt.Println(s, c, a4, s3, d2, m) learnFlowControl() // Auf zum Kontrollfluss! } // Go ist komplett "garbage collected". Sie unterstützt Zeiger (pointers) aber // keine Zeiger-Rechnungen. Fehler können sich durch "nil" einschleichen, jedoch // nicht durch erhöhen eines Zeigers. func learnMemory() (p, q *int) { // Die bennanten Rückgabewerte p & q sind vom Typ *int p = new(int) // Eingebaute Funktion "new" weist neuen Speicherplatz zu // Der zugewiesene Speicher ist mit 0 initialisiert, p ist nicht länger nil s := make([]int, 20) // So weist man 20 ints nebeneinander (im Speicher) zu s[3] = 7 // Einer von ihnen wird ein Wert zugewiesen r := -2 // Deklaration einer weiteren lokalen Variable return &s[3], &r // & gibt die Addresse einer Variable } func expensiveComputation() int { return 1e6 } func learnFlowControl() { // Bedingte Anweisungen verlangen nach geschweiften Klammern, normale // Klammern um die Bedingung werden aber nicht gebraucht. if true { fmt.Println("hab's dir ja gesagt!") } // Die Formatierung ist durch den Befehl "go fmt" standardisiert if false { // nicht hier } else { // sondern hier! spielt die Musik } // Benutzen Sie ein "switch" Statement anstatt eine Anreihung von if-s x := 1 switch x { case 0: case 1: // Einzelne Fälle fallen nicht zum nächsten durch! case 2: // wird nicht ausgeführt } // Wie bei "if", braucht "for" auch keine Klammern um die Bedingung for x := 0; x < 3; x++ { // ++ ist ein Statement fmt.Println(x, "-te Iteration") } // Ab hier gilt wieder: x == 1 // For ist die einzige Schleifenform in Go, sie hat aber mehrere Formen: for { // Endlosschleife break // nur ein Spaß continue // wird nie ausgeführt } // Wie bei for, bedeutet := in einer bedingten Anweisung zunächst die // Zuweisung und erst dann die Überprüfung der Bedingung. if y := expensiveComputation(); y > x { x = y } // Funktionsliterale sind "closures" xBig := func() bool { return x > 100 // Verweist auf x, deklariert vor dem switch } fmt.Println("xBig:", xBig()) // true (im moment gilt: x == 1e6) x /= 1e5 // dies macht x == 10 fmt.Println("xBig:", xBig()) // jetzt: false // Wenn Sie's brauchen, werden Sie's lieben! goto love love: learnInterfaces() // Jetzt zum interessanten Teil! } // Definiere "Stringer" als ein Interface mit einer Methode: String type Stringer interface { String() string } // Definiere ein Paar als struct mit zwei Feldern, Integers mit Namen x & y. type pair struct { x, y int } // Definiere eine Methode von "pair". // Dieser Typ erfüllt jetzt das Stringer interface. func (p pair) String() string { // p ist der Empfänger // Sprintf ist eine weitere öffentliche Funktion von fmt. // Der Syntax mit Punkt greift auf die Felder zu. return fmt.Sprintf("(%d, %d)", p.x, p.y) } func learnInterfaces() { // Der Klammer-Syntax ist ein "struct literal". Es ist ein vollkommen // initialisiertes struct. Der := Syntax deklariert und initialisiert p. p := pair{3, 4} fmt.Println(p.String()) // Aufruf der String() Methode von p. var i Stringer // Deklariere i vom Typ: Stringer i = p // Ok, weil p auch vom Typ Stringer ist. // Aufruf der String Methode von i, gleiche Ausgabe wie zuvor. fmt.Println(i.String()) // Funktionen des fmt-Pakets rufen die String() Methode auf um eine // druckbare Variante des Empfängers zu erhalten. fmt.Println(p) // gleiche Ausgabe wie zuvor fmt.Println(i) // und wieder die gleiche Ausgabe wie zuvor learnErrorHandling() } func learnErrorHandling() { // Das ", ok" Idiom wird häufig verwendet um zu überprüfen ob etwas schief // gegangen ist. m := map[int]string{3: "drei", 4: "vier"} if x, ok := m[1]; !ok { // ok wird false sein, da 1 nicht in der map ist. fmt.Println("keine eins gefunden") } else { fmt.Print(x) // x wäre der Wert, wenn er in der map wäre. } // Ein Fehler-Wert (error value) gibt mehr Informationen über den Grund für // das Problem an. if _, err := strconv.Atoi("nicht-int"); err != nil { // _ verwirft den Wert // Gibt: "strconv.ParseInt: parsing "nicht-int": invalid syntax" aus fmt.Println(err) } // Wir kommen bald nochmal auf Interfaces zurück. Aber inzwischen: learnConcurrency() } // c ist ein Kanal, ein sicheres Kommunikationsmedium. func inc(i int, c chan int) { c <- i + 1 // <- ist der "send" Operator, wenn ein Kanal auf der Linken ist } // Wir verwenden "inc" um Zahlen parallel zu erhöhen. func learnConcurrency() { // Die selbe "make"-Funktion wie vorhin. Sie initialisiert Speicher für // maps, slices und Kanäle. c := make(chan int) // Starte drei parallele "Goroutines". // Die Zahlen werden parallel (concurrently) erhöht. // Alle drei senden ihr Ergebnis in den gleichen Kanal. go inc(0, c) // "go" ist das Statement zum Start einer neuen Goroutine go inc(10, c) go inc(-805, c) // Auslesen und dann Ausgeben der drei berechneten Werte. // Man kann nicht im voraus feststellen in welcher Reihenfolge die Werte // ankommen. fmt.Println(<-c, <-c, <-c) // mit dem Kanal rechts ist <- der Empfangs-Operator cs := make(chan string) // ein weiterer Kanal, diesmal für strings cc := make(chan chan string) // ein Kanal für string Kanäle // Start einer neuen Goroutine, nur um einen Wert zu senden go func() { c <- 84 }() go func() { cs <- "wortreich" }() // schon wieder, diesmal für // "select" hat eine Syntax wie ein switch Statement, aber jeder Fall ist // eine Kanaloperation. Es wählt einen Fall zufällig aus allen, die // kommunikationsbereit sind, aus. select { case i := <-c: // der empfangene Wert kann einer Variable zugewiesen werden fmt.Printf("es ist ein: %T", i) case <-cs: // oder der Wert kann verworfen werden fmt.Println("es ist eine Zeichenkette!") case <-cc: // leerer Kanal, nicht bereit für den Empfang fmt.Println("wird nicht passieren.") } // Hier wird eine der beiden Goroutines fertig sein, die andere nicht. // Sie wird warten bis der Wert den sie sendet von dem Kanal gelesen wird. learnWebProgramming() // Go kann es und Sie hoffentlich auch bald. } // Eine einzige Funktion aus dem http-Paket kann einen Webserver starten. func learnWebProgramming() { // Der erste Parameter von "ListenAndServe" ist eine TCP Addresse, an die // sich angeschlossen werden soll. // Der zweite Parameter ist ein Interface, speziell: ein http.Handler err := http.ListenAndServe(":8080", pair{}) fmt.Println(err) // Fehler sollte man nicht ignorieren! } // Wir lassen "pair" das http.Handler Interface erfüllen, indem wir seine einzige // Methode implementieren: ServeHTTP func (p pair) ServeHTTP(w http.ResponseWriter, r *http.Request) { // Senden von Daten mit einer Methode des http.ResponseWriter w.Write([]byte("Sie haben Go in Y Minuten gelernt!")) } ``` ## Weitere Resourcen Informationen zu Go findet man auf der [offiziellen Go Webseite](http://golang.org/). Dort gibt es unter anderem ein Tutorial und interaktive Quelltext-Beispiele, vor allem aber Dokumentation zur Sprache und den Paketen. Auch zu empfehlen ist die Spezifikation von Go, die nach heutigen Standards sehr kurz und gut verständlich formuliert ist. Auf der Leseliste von Go-Neulingen ist außerdem der Quelltext der [Go standard Bibliothek](http://golang.org/src/pkg/) einzusehen. Dieser kann als Referenz für leicht zu verstehendes und im idiomatischen Stil verfasstes Go dienen. Erreichbar ist der Quelltext auch durch das Klicken der Funktionsnamen in der [offiziellen Dokumentation von Go](http://golang.org/pkg/). --- language: Hack lang: de-de contributors: - ["Stephen Holdaway", "https://github.com/stecman"] - ["David Lima", "https://github.com/davelima"] translators: - ["Jerome Meinke", "https://github.com/jmeinke"] filename: learnhack-de.hh --- Hack ist eine von Facebook neu entwickelte Programmiersprache auf Basis von PHP. Sie wird von der HipHop Virtual Machine (HHVM) ausgeführt. Die HHVM kann aufgrund der Ähnlichkeit der Programmiersprachen nicht nur Hack, sondern auch PHP-Code ausführen. Der wesentliche Unterschied zu PHP besteht in der statischen Typisierung der Sprache, die eine wesentlich höhere Performance erlaubt. Hier werden nur Hack-spezifische Eigenschaften beschrieben. Details über PHP's Syntax findet man im [PHP Artikel](http://learnxinyminutes.com/docs/php/) dieser Seite. ```php id = $id; } } // Kurzgefasste anonyme Funktionen (lambdas) $multiplier = 5; array_map($y ==> $y * $multiplier, [1, 2, 3]); // Weitere, spezielle Felder (Generics) // Diese kann man sich als ein zugreifbares Interface vorstellen class Box { protected T $data; public function __construct(T $data) { $this->data = $data; } public function getData(): T { return $this->data; } } function openBox(Box $box) : int { return $box->getData(); } // Formen // // Hack fügt das Konzept von Formen hinzu, wie struct-ähnliche arrays // mit einer typ-geprüften Menge von Schlüsseln type Point2D = shape('x' => int, 'y' => int); function distance(Point2D $a, Point2D $b) : float { return sqrt(pow($b['x'] - $a['x'], 2) + pow($b['y'] - $a['y'], 2)); } distance( shape('x' => -1, 'y' => 5), shape('x' => 2, 'y' => 50) ); // Typen-Definition bzw. Aliasing // // Hack erlaubt es Typen zu definieren und sorgt somit für bessere Lesbarkeit newtype VectorArray = array>; // Ein Tupel mit zwei Integern newtype Point = (int, int); function addPoints(Point $p1, Point $p2) : Point { return tuple($p1[0] + $p2[0], $p1[1] + $p2[1]); } addPoints( tuple(1, 2), tuple(5, 6) ); // Erstklassige Aufzählungen (enums) enum RoadType : int { Road = 0; Street = 1; Avenue = 2; Boulevard = 3; } function getRoadType() : RoadType { return RoadType::Avenue; } // Automatische Erstellung von Klassen-Eigenschaften durch Konstruktor-Argumente // // Wiederkehrende Definitionen von Klassen-Eigenschaften können durch die Hack- // Syntax vermieden werden. Hack erlaubt es die Klassen-Eigenschaften über // Argumente des Konstruktors zu definieren. class ArgumentPromotion { public function __construct(public string $name, protected int $age, private bool $isAwesome) {} } class WithoutArgumentPromotion { public string $name; protected int $age; private bool $isAwesome; public function __construct(string $name, int $age, bool $isAwesome) { $this->name = $name; $this->age = $age; $this->isAwesome = $isAwesome; } } // Kooperatives Multitasking // // Die Schlüsselworte "async" and "await" führen Multitasking ein. // Achtung, hier werden keine Threads benutzt, sondern nur Aktivität getauscht. async function cooperativePrint(int $start, int $end) : Awaitable { for ($i = $start; $i <= $end; $i++) { echo "$i "; // Geben anderen Tasks die Möglichkeit aktiv zu werden await RescheduleWaitHandle::create(RescheduleWaitHandle::QUEUE_DEFAULT, 0); } } // Die Ausgabe von folgendem Code ist "1 4 7 2 5 8 3 6 9" AwaitAllWaitHandle::fromArray([ cooperativePrint(1, 3), cooperativePrint(4, 6), cooperativePrint(7, 9) ])->getWaitHandle()->join(); // Attribute // // Attribute repräsentieren eine Form von Metadaten für Funktionen. // Hack bietet Spezial-Attribute, die nützliche Eigenschaften mit sich bringen. // Das __Memoize Attribut erlaubt es die Ausgabe einer Funktion zu cachen. <<__Memoize>> function doExpensiveTask() : ?string { return file_get_contents('http://example.com'); } // Der Funktionsrumpf wird im Folgenden nur ein einziges mal ausgeführt: doExpensiveTask(); doExpensiveTask(); // Das __ConsistentConstruct Attribut signalisiert dem type-checker, dass // die Funktionsdeklaration von __construct für alle Unterklassen dieselbe ist. <<__ConsistentConstruct>> class ConsistentFoo { public function __construct(int $x, float $y) { // ... } public function someMethod() { // ... } } class ConsistentBar extends ConsistentFoo { public function __construct(int $x, float $y) { // Der Type-checker erzwingt den Aufruf des Eltern-Klassen-Konstruktors parent::__construct($x, $y); // ... } // Das __Override Attribut ist ein optionales Signal an den Type-Checker, // das erzwingt, dass die annotierte Methode die Methode der Eltern-Klasse // oder des Traits verändert. <<__Override>> public function someMethod() { // ... } } class InvalidFooSubclass extends ConsistentFoo { // Wenn der Konstruktor der Eltern-Klasse nicht übernommen wird, // wird der Type-Checker einen Fehler ausgeben: // // "This object is of type ConsistentBaz. It is incompatible with this object // of type ConsistentFoo because some of their methods are incompatible" // public function __construct(float $x) { // ... } // Auch bei der Benutzung des __Override Attributs für eine nicht veränderte // Methode wird vom Type-Checker eine Fehler ausgegeben: // // "InvalidFooSubclass::otherMethod() is marked as override; no non-private // parent definition found or overridden parent is defined in non-> public function otherMethod() { // ... } } // Ein Trait ist ein Begriff aus der objektorientierten Programmierung und // beschreibt eine wiederverwendbare Sammlung von Methoden und Attributen, // ähnlich einer Klasse. // Anders als in PHP können Traits auch als Schnittstellen (Interfaces) // implementiert werden und selbst Schnittstellen implementieren. interface KittenInterface { public function play() : void; } trait CatTrait implements KittenInterface { public function play() : void { // ... } } class Samuel { use CatTrait; } $cat = new Samuel(); $cat instanceof KittenInterface === true; // True ``` ## Weitere Informationen Die Hack [Programmiersprachen-Referenz](http://docs.hhvm.com/manual/de/hacklangref.php) erklärt die neuen Eigenschaften der Sprache detailliert auf Englisch. Für allgemeine Informationen kann man auch die offizielle Webseite [hacklang.org](http://hacklang.org/) besuchen. Die offizielle Webseite [hhvm.com](http://hhvm.com/) bietet Infos zum Download und zur Installation der HHVM. Hack's [nicht-untersützte PHP Syntax-Elemente](http://docs.hhvm.com/manual/en/hack.unsupported.php) werden im offiziellen Handbuch beschrieben. --- language: haml filename: learnhaml-de.haml contributors: - ["Simon Neveu", "https://github.com/sneveu"] - ["Sol Bekic", "https://github.com/S0lll0s"] lang: de-de --- Haml ist eine Markup- und Templatingsprache, aufgesetzt auf Ruby, mit der HTML Dokumente einfach beschrieben werden können. Haml vermindert Wiederholung und Fehleranfälligkeit, indem es Tags basierend auf der Markup-Struktur schließt und schachtelt. Dadurch ergibt sich kurzes, präzises und logisches Markup. Haml kann außerhalb eines Ruby-projekts verwendet werden. Mit dem installierten Haml gem kann man das Terminal benutzen um Haml zu HTML umzuwandeln: $ haml input_file.haml output_file.html ```haml / ------------------------------------------- / Einrückung / ------------------------------------------- / Einrückung ist ein wichtiges Element des Haml Syntax, deswegen ist es wichtig ein konsequentes Schema zu verwenden. Meistens werden zwei spaces verwendet, solange die Einrückungen das gleiche Schema verfolgen können aber auch andere Breiten und Tabs verwendet werden / ------------------------------------------- / Kommentare / ------------------------------------------- / Kommentare beginnen mit einem Slash / Mehrzeilige Kommentare werden eingerückt und mit einem Slash eingeführt -# Diese Zeile ist ein "stummes" Kommentar, es wird nicht mitgerendert / ------------------------------------------- / HTML Elemente / ------------------------------------------- / Tags werden durch ein Prozentzeichen und den Tagnamen erzeugt %body %header %nav / Die Zeilen oben würden folgendes ergeben:
/ Text kann direkt nach dem Tagnamen eingefügt werden: %h1 Headline copy / Mehrzeilige Inhalte müssen stattdessen eingerückt werden: %p This is a lot of content that we could probably split onto two separate lines. / HTML kann mit &= escaped werden. So werden HTML-sensitive Zeichen enkodiert. Zum Beispiel: %p &= "Ja & Nein" / würde 'Ja & Nein' ergeben / HTML kann mit != dekodiert werden: %p != "so schreibt man ein Paragraph-Tag:

" / ...was 'This is how you write a paragraph tag

' ergeben würde / CSS Klassen können mit '.classname' an Tags angehängt werden: %div.foo.bar / oder über einen Ruby Hash: %div{:class => 'foo bar'} / Das div Tag wird standardmäßig verwendet, divs können also verkürzt werden: .foo / andere Attribute können über den Hash angegeben werden: %a{:href => '#', :class => 'bar', :title => 'Bar'} / Booleesche Attribute können mit 'true' gesetzt werden: %input{:selected => true} / data-Attribute können in einem eigenen Hash im :data key angegeben werden: %div{:data => {:attribute => 'foo'}} / ------------------------------------------- / Verwendung von Ruby / ------------------------------------------- / Mit dem = Zeichen können Ruby-werte evaluiert und als Tag-text verwendet werden: %h1= book.name %p = book.author = book.publisher / Code nach einem Bindestrich wird ausgeführt aber nicht gerendert: - books = ['book 1', 'book 2', 'book 3'] / So können zum Beispiel auch Blöcke verwendet werden: - books.shuffle.each_with_index do |book, index| %h1= book if book do %p This is a book / Auch hier werden wieder keine End-Tags benötigt! Diese ergeben sich aus der Einrückung. / ------------------------------------------- / Inline Ruby / Ruby Interpolation / ------------------------------------------- / Ruby variablen können mit #{} in Text interpoliert werden: %p dein bestes Spiel ist #{best_game} / ------------------------------------------- / Filter / ------------------------------------------- / Mit dem Doppelpinkt können Haml Filter benutzt werden. Zum Beispiel gibt es den :javascript Filter, mit dem inline JS geschrieben werden kann: :javascript console.log('Dies ist ein ``` ### Optimizar todo un proyecto usando r.js Muchas personas prefieren usar AMD para la organización del código durante el desarrollo, pero quieren enviar para producción un solo fichero en vez de ejecutar cientos de XHRs en las cargas de página. `require.js` incluye un script llamado `r.js` (el que probablemente correrás en node.js, aunque Rhino también es soportado) que puede analizar el gráfico de dependencias de tu proyecto, y armar un solo fichero que contenga todos tus módulos (adecuadamente nombrados), minificado y listo para consumo. Instálalo usando `npm`: ```shell $ npm install requirejs -g ``` Ahora puedes alimentarlo con un fichero de configuración: ```shell $ r.js -o app.build.js ``` Para nuestro ejemplo anterior el archivo de configuración luciría así: ```javascript /* file : app.build.js */ ({ name : 'main', // nombre del punto de entrada out : 'main-built.js', // nombre del fichero donde se escribirá la salida baseUrl : 'app', paths : { // `empty:` le dice a r.js que esto aún debe ser cargado desde el CDN, usando // la ubicación especificada en `main.js` jquery : 'empty:', coolLibFromBower : '../bower_components/cool-lib/coollib' } }) ``` Para usar el fichero creado en producción, simplemente intercambia `data-main`: ```html ``` Un increíblemente detallado [resumen de opciones de generación](https://github.com/jrburke/r.js/blob/master/build/example.build.js) está disponible en el repositorio de GitHub. ### Temas no cubiertos en este tutorial * [Cargador de plugins / transformaciones](http://requirejs.org/docs/plugins.html) * [Cargando y exportando estilos CommonJS](http://requirejs.org/docs/commonjs.html) * [Configuración avanzada](http://requirejs.org/docs/api.html#config) * [Configuración de Shim (cargando módulos no-AMD)](http://requirejs.org/docs/api.html#config-shim) * [Cargando y optimizando CSS con require.js](http://requirejs.org/docs/optimization.html#onecss) * [Usando almond.js para construcciones](https://github.com/jrburke/almond) ### Otras lecturas: * [Especificaciones oficiales](https://github.com/amdjs/amdjs-api/wiki/AMD) * [¿Por qué AMD?](http://requirejs.org/docs/whyamd.html) * [Definición Universal de Módulos](https://github.com/umdjs/umd) ### Implementaciones: * [require.js](http://requirejs.org) * [dojo toolkit](http://dojotoolkit.org/documentation/tutorials/1.9/modules/) * [cujo.js](http://cujojs.com/) * [curl.js](https://github.com/cujojs/curl) * [lsjs](https://github.com/zazl/lsjs) * [mmd](https://github.com/alexlawrence/mmd) --- category: Algorithms & Data Structures name: Asymptotic Notation contributors: - ["Jake Prather", "http://github.com/JakeHP"] translators: - ["Gerson Lázaro", "https://gersonlazaro.com"] lang: es-es --- # Notaciones asintóticas ## ¿Qué son? Las notaciones asintóticas son lenguajes que nos permitan analizar el tiempo de ejecución de un algoritmo identificando su comportamiento si el tamaño de entrada para el algoritmo aumenta. Esto también se conoce como la tasa de crecimiento de un algoritmo. ¿El algoritmo de repente se vuelve increíblemente lento cuando el tamaño de entrada crece? ¿Tiende a mantener un rápido tiempo de ejecución a medida que el tamaño de entrada aumenta? La notación asintótica nos da la capacidad para responder a estas preguntas. ## ¿Hay alternativas que respondan a estas preguntas? Una manera sería contar el número de operaciones primitivas en diferentes tamaños de entrada. Aunque esta es una solución válida, la cantidad de trabajo que esto conlleva, incluso para los algoritmos simples, no justifica su uso. Otra manera es medir físicamente la cantidad de tiempo que un algoritmo toma para completar su ejecución dados diferentes tamaños de entrada. Sin embargo, la exactitud y la relatividad (los tiempos obtenidos sólo serían relativos a la máquina sobre la cual se calcularon) de este método está ligado a variables ambientales tales como especificaciones de hardware, capacidad de procesamiento, etc. ## Tipos de Notación Asintótica En la primera sección de este documento hemos descrito cómo una notación asintótica identifica el comportamiento de un algoritmo ante los cambios en el tamaño de la entrada. Imaginemos un algoritmo como una función f, con tamaño de entrada n, y f(n) siendo el tiempo de ejecución. Así que para un algoritmo f dado, con el tamaño de entrada n obtenemos algún tiempo de ejecución resultante f(n). Esto resulta en un gráfico donde el eje Y es el tiempo de ejecución, el eje X es el tamaño de la entrada y los puntos en el gráfico son los resultantes de la cantidad de tiempo para un tamaño de entrada dado. Puedes etiquetar una función, o un algoritmo, con una notación asintótica de muchas maneras diferentes. Algunos ejemplos son describir un algoritmo por su mejor caso, su peor caso, o el caso promedio. Lo más común es analizar un algoritmo por su peor caso. Por lo general, no se evalúa el mejor caso, porque no planeas el algoritmo para estas condiciones. Un muy buen ejemplo de esto son los algoritmos de ordenamiento; específicamente, añadir elementos a un árbol. El mejor caso para la mayoría de los algoritmos podría ser tan bajo como una sola operación. Sin embargo, en la mayoría de los casos, el elemento que está añadiendo tendrá que ser ordenado adecuadamente a través del árbol, lo que podría significar examinar toda una rama. Este es el peor de los casos, y para estos casos es que planeamos el algoritmo. ### Tipos de funciones, límites, y simplificación ``` Función logarítmica - log n Función lineal - an + b Función cuadrática - an^2 + bn + c Función polinomicas - an^z + . . . + an^2 + a*n^1 + a*n^0, donde z es constante Función exponencial - a^n, donde a es constante ``` Estas son algunas clasificaciones de funciones de crecimiento básicos utilizados en varias notaciones. La lista comienza en la función de crecimiento menor (logarítmica, el tiempo de ejecución mas rápido) y pasa a la de mayor crecimiento (exponencial, el tiempo de ejecución mas lento). Observe como al crecer 'n', o la entrada, en cada una de estas funciones, el resultado aumenta claramente mucho más rápido en las cuadráticas, polinómicas y exponenciales, en comparación con las logarítmicas y lineales. Una anotación muy importante es que en las notaciones que se discutirán debes hacer tu mejor esfuerzo por utilizar los términos más simples. Esto significa hacer caso omiso de las constantes y terminos de orden inferior, porque a medida que el tamaño de entrada (o n en f(n)) aumenta hacia el infinito (límites matemáticos), los términos y constantes de orden inferior se vuelven de poca o ninguna importancia. Dicho esto, si tienes constantes que son 2^9001, o alguna otra cantidad ridícula, inimaginable, te daras cuenta de que la simplificación sesgará la exactitud de la notación. Como queremos algo simplificado, vamos a modificarlo un poco... ``` Logarítmico - log n Lineal - n Cuandrático - n^2 Polinómico - n^z, donde z es constante Exponencial - a^n, donde a es constante ``` ### O-grande (Big-O) O-grande (Big-O), comúnmente escrito como O, es una notación asintótica para el peor caso, o el techo de crecimiento para una función determinada. Si `f (n)` es el tiempo de ejecución del algoritmo, y `g (n)` es un tiempo de complejidad arbitraria que relacionas con el algoritmo, entonces `f (n)` es O(g(n)), si por cualquier constante real c (c > 0), `f (n)` <= `c g(n)` para cada tamaño de entrada n (n > 0 ). *Ejemplo 1* ``` f(n) = 3log n + 100 g(n) = log n ``` `f(n)` es O(g(n))? `3 log n + 100` es O(log n)? Echemos un vistazo a la definición de O-grande. ``` 3log n + 100 <= c * log n ``` ¿Hay alguna constante c que satisface esto para todo n? ``` 3log n + 100 <= 150 * log n, n > 2 (indefinido en n = 1) ``` ¡Sí! La definición de O-grande se cumple, por lo tanto `f (n)` es O(g(n)). *Ejemplo 2* ``` f(n) = 3*n^2 g(n) = n ``` `f(n)` es O(g(n))? `3 * n^2` es O(n)? Echemos un vistazo a la definición de O-grande. ``` 3 * n^2 <= c * n ``` ¿Hay alguna constante c que satisface esto para todo n? No, no la hay. `f(n)` no es O(g(n)). ### Big-Omega Big-Omega, comunmente escrito como Ω, es una notación asintótica para el mejor caso, o el piso en el crecimiento para una función dada. `f(n)` es Ω(g(n)), si para cualquier constante real c (c > 0), `f(n)` es >= `c g(n)` para cualquier tamaño de entrada n (n > 0). No dudes en dirigirte a los recursos adicionales para ejemplos sobre esto. O-grande es la notación principal utilizada para la complejidad general de tiempo algoritmico. ### Notas finales Es difícil mantener este tipo de tema corto, y sin duda deberias revisar los libros y recursos en línea en la lista. Entran en mucha mayor profundidad con definiciones y ejemplos. ## Libros * [Algoritmos (Algorithms)](http://www.amazon.com/Algorithms-4th-Robert-Sedgewick/dp/032157351X) * [Diseño de algoritmos (Algorithm Design)](http://www.amazon.com/Algorithm-Design-Foundations-Analysis-Internet/dp/0471383651) ## Recursos Online * [MIT](http://web.mit.edu/16.070/www/lecture/big_o.pdf) * [KhanAcademy](https://www.khanacademy.org/computing/computer-science/algorithms/asymptotic-notation/a/asymptotic-notation) * [Apuntes Facultad de Ingeniería](https://www.scribd.com/document/317979564/Apuntes-Sobre-Analisis-de-Algoritmos) --- language: awk filename: learnawk-es.awk contributors: - ["Marshall Mason", "http://github.com/marshallmason"] translators: - ["Hugo Guillén-Ramírez", "http://github.com/HugoGuillen"] lang: es-es --- AWK es una herramienta estándar en cada sistema UNIX compatible con POSIX. Es como un Perl restringido, perfecto para tareas de procesamiento de texto y otras necesidades de scripting. Tiene una sintaxis similar a C, pero sin puntos y comas, manejo manual de memoria y tipado estático. Puedes llamarlo desde un script de shell o usarlo como un lenguaje stand-alone para scripting. ¿Por qué elegir AWK sobre Perl? Principalmente, porque AWK es parte de UNIX. Siempre puedes contar con él, mientras que el futuro de Perl está en duda. AWK es más fácil de leer que Perl. Para scripts sencillos de procesamiento de texto, particularmente si es para leer archivos línea a línea y dividir por delimitadores, probablemente AWK es la herramienta correcta para el trabajo. ```awk #!/usr/bin/awk -f # Los comentarios tienen este aspecto. # Los programas AWK son una colección de patrones y acciones. El patrón más # importante es BEGIN. Las acciones van en bloques delimitados por llaves. BEGIN { # BEGIN correrá al inicio del programa. Es donde pones todo el código # preliminar antes de procesar los archivos de texto. Si no tienes archivos # de texto, piensa en BEGIN como el punto de entrada principal del script. # Las variables son globales. Asígnalas o úsalas sin declararlas. count = 0 # Los operadores son justo como en C (y amigos). a = count + 1 b = count - 1 c = count * 1 d = count / 1 e = count % 1 # módulo f = count ^ 1 # exponenciación a += 1 b -= 1 c *= 1 d /= 1 e %= 1 f ^= 1 # Incremento y decremento en uno a++ b-- # Como un operador prefijo, regresa el valor modificado ++a --b # Nota que no hay puntación para terminar las instrucciones # Instrucciones de control if (count == 0)