Showing preview only (7,333K chars total). Download the full file or copy to clipboard to get everything.
Repository: nitely/nim-regex
Branch: master
Commit: 2c41f0b2fee9
Files: 34
Total size: 6.4 MB
Directory structure:
gitextract_tvdvmii5/
├── .github/
│ ├── FUNDING.yml
│ └── workflows/
│ └── ci.yml
├── .gitignore
├── CHANGELOG.md
├── LICENSE
├── README.md
├── bench/
│ ├── README.md
│ ├── bench.nim
│ └── input-text.txt
├── docs/
│ ├── index.html
│ └── regex/
│ └── .keep
├── regex.nimble
├── src/
│ ├── regex/
│ │ ├── common.nim
│ │ ├── compiler.nim
│ │ ├── dotgraph.nim
│ │ ├── exptransformation.nim
│ │ ├── exptype.nim
│ │ ├── litopt.nim
│ │ ├── nfa.nim
│ │ ├── nfafindall.nim
│ │ ├── nfafindall2.nim
│ │ ├── nfamacro.nim
│ │ ├── nfamatch.nim
│ │ ├── nfamatch2.nim
│ │ ├── nfatype.nim
│ │ ├── nodematch.nim
│ │ ├── oldregex.nim
│ │ ├── parser.nim
│ │ ├── scanner.nim
│ │ └── types.nim
│ └── regex.nim
└── tests/
├── tests.nim
├── tests2.nim
└── tests_misc.nim
================================================
FILE CONTENTS
================================================
================================================
FILE: .github/FUNDING.yml
================================================
# These are supported funding model platforms
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: nitely_
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
polar: # Replace with a single Polar username
buy_me_a_coffee: # Replace with a single Buy Me a Coffee username
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
================================================
FILE: .github/workflows/ci.yml
================================================
name: CI
on:
push:
branches:
- master
pull_request:
jobs:
test:
name: Nim ${{ matrix.nim }}
runs-on: ubuntu-latest
strategy:
matrix:
nim: [1.6.20, 2.0.14, 2.2.0]
steps:
- uses: actions/checkout@v2
- name: Run Tests
run: |
docker pull nimlang/nim:${{ matrix.nim }}
docker run --rm -v `pwd`:/usr/src/app -w /usr/src/app nimlang/nim:${{ matrix.nim }} /bin/bash -c "git config --global --add safe.directory /usr/src/app; nimble install -y; nimble test"
- name: Build docs
if: matrix.nim == '1.6.20'
run: |
docker pull nimlang/nim:${{ matrix.nim }}
docker run --rm -v `pwd`:/usr/src/app -w /usr/src/app nimlang/nim:${{ matrix.nim }} /bin/bash -c "git config --global --add safe.directory /usr/src/app; nimble install -y; nimble docs"
- name: Deploy docs
# to view docs on your own fork: push a gh-pages branch on your fork,
# enable gh-pages in your fork
# and remove `github.ref == 'refs/heads/master'` below
if: |
github.event_name == 'push' && github.ref == 'refs/heads/master' &&
matrix.nim == '1.6.20'
uses: crazy-max/ghaction-github-pages@v1
with:
build_dir: docs
target_branch: gh-pages
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
================================================
FILE: .gitignore
================================================
nimcache/
src/regex.js
src/regex.out
src/regex/litopt
src/regex/nfatype
src/regex/common
tests/tests
tests/tests.js
tests/tests2
tests/tests2.js
tests/tests_misc
tests/tests_misc.js
tests/test_bug
docs/ugh
bin/*
bench/bench
config.nims
================================================
FILE: CHANGELOG.md
================================================
v0.26.2
==================
* Performance improvements
v0.26.1
==================
* Fix unicode case-insensitive match edge case #150
v0.26.0
==================
* Performance improvements
* Fix devel compiler warnings
v0.25.0
==================
* Drop support for Nim < 1.6
* Implement PCRE var flags (#137)
* Performance improvements
v0.24.1
==================
* Disable utf8 regex check for arbitrary bytes (#136)
v0.24.0
==================
* Fix dot to match anything in ascii mode (#135)
* Match arbitrary bytes (#134)
v0.23.0
==================
* Verify input is utf-8 (#131)
v0.22.0
==================
* Literals substring optimization (#130)
* Refactor epsilon transitions (#129)
v0.21.0
==================
* Deprecated all of the APIs (except the macro one)
* New API (issue #111)
* Removed the "capture all group/submatch repetitions" feature.
Only the last group repetition is captured.
Changes to migrate to the new API:
```text
re"regex" -> re2"regex"
Regex -> Regex2
RegexMatch -> RegexMatch2
```
Then deal with `group(RegexMatch2, int)` and similar APIs returning
the last capture group/submatch repetition instead of a sequence
with all of them.
v0.20.2
==================
* Nim compat fixes: #119
v0.20.1
==================
* Nim compat fixes: #117
v0.20.0
==================
* Add `reRepRangeLimit` compile option to define range limit #113
* Nim compat fixes: #98, #101, #110
v0.19.0
==================
* Adds support for unbounded lookaround assertions
* Fix: parsing `{n,m}` repetitions is less strict;
`{}`, `{abc}`, etc are parsed as characters. This is
closer to PCRE, but it won't allow error prone instances
such as missing brackets: `{123`.
* Fix: double repetitions: `**`, `++`, `*+`, `???`, `{n}*`, `{n}+`,
and other combinations are no longer allowed. The `++` PCRE hack
is not allowed, as it won't work the same way anyway.
v0.18.0
==================
* Adds `escapeRe(string): string` function
* Removed `unicodeplus` dependency
v0.17.1
==================
* Fix: regression related to repetitions,
and lonely assertions; issue #83
* Fix: make it compile with ARC; thanks to @timotheecour
v0.17.0
==================
* Removes macro usage for regular function APIs
* Adds `match` block macro
* Fix: sub-matches with nested optional operators
(ex: `(a?)*`) to work the same as PCRE
v0.16.2
==================
* Adds `findAllBounds`
* Adds some minor perf improvements
v0.16.1
==================
* Adds `groupFirstCapture`, `groupLastCapture`, and
`group(1): seq[string]` for group numbers
* Adds support for negative lookaround assertions
v0.16.0
==================
* Adds literals optimization to `findAll`,
`split`, `splitIncl`, and `replace`; this makes
some regexes run ~100x faster.
* Support lookbehind; this is limited to one character
* Fix: `findAll` ran in quadratic time for some regexes;
`split`, `splitIncl`, and `replace` were also affected;
Linear time is now guaranteed.
* Fix: regex compilation errors were swallow due to
a Nim bug; A workaround to raise the error was implemented
v0.15.0
==================
* Fix multiline not working with beginning of line, issue #13
* Fix replace re"", issue #29
* Fixes a number of issues related to empty matches
in the `findAll`, `split`, and `replace` APIs
v0.14.1
==================
* Fix non-greedy find, issue #61 (v0.14.0 regression)
v0.14
==================
* Drop Nim 0.19.0 support (0.19.6 is supported)
* Changed all `proc` to `func`
* Faster macro for static regex
* Deprecated `toPattern`
* New `match` API that does not require the `MatchRegex` parameter
v0.13.1
==================
* Fix nested non-capturing group repetition #46
* Remove stylecheck config #55
v0.13
==================
* Add `groupFirstCapture`, `groupLastCapture`, and
`group(1): seq[string]` (thanks to @xmonader)
* Add Nim 1.0.0 to CI
* Drop Nim 0.18 support
* Fix nested captures with repetition range; issue #46
* Fix Nim `sets` warnings
v0.12
==================
* Support matching at compile-time; issue #4
(thanks to @timotheecour)
v0.11.2
==================
* Added `isInitialized*(re: Regex)`
v0.11.1
==================
* Fix `\w` not matching `_` on ASCII mode
* Fixes to support the JS backend
v0.11
==================
* Update to Unicode 12.1
v0.10.1
==================
* Fix for Nim devel (PR #34)
v0.10.0
==================
* Add Nim 0.18 support back
v0.9.0 (unreleased)
==================
* Drop Nim 0.18 support
* Improved `re` API to support compile-time
or run-time compilation depending on input
(thanks to @timotheecour)
v0.8.0
==================
* Drop Nim 0.17 support
* Add Nim 0.19 support
* Update dependencies
* Remove deprecated `match` and `find`
returning `Option[RegexMatch]`
v0.7.4
==================
* Add `splitIncl`, similar to `split` but
includes captured groups
v0.7.3
==================
* Fix deprecation warnings on devel
v0.7.2
==================
* Fixes for devel (#17)
v0.7.1
==================
* Update dependencies
v0.7.0
==================
* New API taking `var RegexMatch` instead
of returning `Option[RegexMatch]`
* Deprecate `match` and `find`
returning `Option[RegexMatch]`
* Update to unicode 11
v0.6.3
==================
* Pretty error messages
v0.6.2
==================
* Adds limited lookahead support
* Improves compilation time
v0.6.1
==================
* Initial release
================================================
FILE: LICENSE
================================================
MIT License
Copyright (c) 2017 Esteban Castro Borsani
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: README.md
================================================
# Regex
[](https://github.com/nitely/nim-regex/actions?query=workflow%3ACI)
[](https://raw.githubusercontent.com/nitely/nim-regex/master/LICENSE)
A library for parsing, compiling, and executing regular expressions at both runtime and compile-time.
Features:
* The match time is linear in the length of the input string
* Supports compiling regex at compile-time
* Supports matching at compile-time
* Unicode level-1 support
* Descriptive error messages
* PCRE syntax and semantics
## Install
```
nimble install regex
```
# Compatibility
Nim +1.6.0
## Docs
[Read the docs](https://nitely.github.io/nim-regex/)
## Tests
```
nimble test
```
## Debugging
Compile with `-d:regexDotDir:.` to generate [dot files](https://en.wikipedia.org/wiki/DOT_(graph_description_language)) of the regexes (NFAs) within the nim file. A dot file can be viewed in [Graphviz](https://dreampuf.github.io/GraphvizOnline/). Requires Nim +1.2.
## LICENSE
MIT
================================================
FILE: bench/README.md
================================================
## Benchmarks
Run first:
```
nimble install nimbench
nimble develop
```
Run benchmarks:
```
nim c -r -d:danger bench/bench.nim
```
================================================
FILE: bench/bench.nim
================================================
import pkg/nimbench
import std/unicode
from std/re import nil
from ../src/regex import nil
func genText(): string {.compileTime.} =
result = ""
for _ in 0 .. 100000:
result.add("a")
result.add("sol")
for _ in 0 .. 100000:
result.add("b")
#result.add("ฅ")
const text = genText()
var pattern2 = re.re"^\w*sol\w*$"
bench(re_sol, m):
var d: bool
for i in 0 ..< m:
d = re.match(text, pattern2)
doNotOptimizeAway(d)
const pattern4 = regex.re2(r"\w*sol\w*") #, {regex.RegexFlag.reAscii})
benchRelative(regex_sol, m):
var m2: regex.RegexMatch2
for i in 0 ..< m:
discard regex.match(text, pattern4, m2)
doNotOptimizeAway(m2)
benchRelative(regex_macro_sol, m):
var d: bool
for i in 0 ..< m:
regex.match text, regex.rex"\w*sol\w*":
d = true
doNotOptimizeAway(d)
var dummyTextNums = """650-253-0001"""
var pattern_nums = re.re"^[0-9]+-[0-9]+-[0-9]+$"
bench(re_nums, m):
var d: bool
for i in 0 ..< m:
d = re.match(dummyTextNums, pattern_nums)
doNotOptimizeAway(d)
const n_pattern_nums = regex.re2"[0-9]+-[0-9]+-[0-9]+"
benchRelative(regex_nums, m):
var m2: regex.RegexMatch2
for i in 0 ..< m:
discard regex.match(dummyTextNums, n_pattern_nums, m2)
doNotOptimizeAway(m2)
benchRelative(regex_macro_nums, m):
var d: bool
for i in 0 ..< m:
regex.match text, regex.rex"[0-9]+-[0-9]+-[0-9]+":
d = true
doNotOptimizeAway(d)
var pattern_nums2 = re.re"^[0-9]+..*$"
bench(re_nums2, m):
var d: bool
for i in 0 ..< m:
d = re.match(dummyTextNums, pattern_nums2)
doNotOptimizeAway(d)
const n_pattern_nums2 = regex.re2"[0-9]+..*"
benchRelative(regex_nums2, m):
var m3: regex.RegexMatch2
for i in 0 ..< m:
discard regex.match(dummyTextNums, n_pattern_nums2, m3)
doNotOptimizeAway(m3)
benchRelative(regex_macro_nums2, m):
var d: bool
for i in 0 ..< m:
regex.match text, regex.rex"[0-9]+..*":
d = true
doNotOptimizeAway(d)
when false: # XXX remove
var lits_find_re = re.re"do|re|mi|fa|sol"
bench(re_lits_find, m):
var d: int
for i in 0 ..< m:
d = re.find(text, lits_find_re)
doNotOptimizeAway(d)
const lits_find = regex.re2"do|re|mi|fa|sol"
benchRelative(regex_lits_find, m):
var m2: regex.RegexMatch2
for i in 0 ..< m:
discard regex.find(text, lits_find, m2)
doNotOptimizeAway(m2)
const bench_text = staticRead("input-text.txt")
var email_find_all_re = re.re"[\w\.+-]+@[\w\.-]+\.[\w\.-]+"
bench(re_email_find_all, m):
var d = 0
for i in 0 ..< m:
for _ in re.findAll(bench_text, email_find_all_re):
d += 1
doAssert d == 92
doNotOptimizeAway(d)
const email_find_all = regex.re2"[\w\.+-]+@[\w\.-]+\.[\w\.-]+"
benchRelative(regex_email_find_all, m):
var d = 0
for i in 0 ..< m:
for _ in regex.findAll(bench_text, email_find_all):
d += 1
doAssert d == 92
doNotOptimizeAway(d)
var uri_find_all_re = re.re"[\w]+://[^/\s?#]+[^\s?#]+(?:\?[^\s#]*)?(?:#[^\s]*)?"
bench(re_uri_find_all, m):
var d = 0
for i in 0 ..< m:
for _ in re.findAll(bench_text, uri_find_all_re):
d += 1
doAssert d == 5301
doNotOptimizeAway(d)
const uri_find_all = regex.re2"[\w]+://[^/\s?#]+[^\s?#]+(?:\?[^\s#]*)?(?:#[^\s]*)?"
benchRelative(regex_uri_find_all, m):
var d = 0
for i in 0 ..< m:
for _ in regex.findAll(bench_text, uri_find_all):
d += 1
doAssert d == 5301
doNotOptimizeAway(d)
var ip_find_all_re = re.re"(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9])"
bench(re_ip_find_all, m):
var d = 0
for i in 0 ..< m:
for _ in re.findAll(bench_text, ip_find_all_re):
d += 1
doAssert d == 5
doNotOptimizeAway(d)
const ip_find_all = regex.re2"(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9])"
benchRelative(regex_ip_find_all, m):
var d = 0
for i in 0 ..< m:
for _ in regex.findAll(bench_text, ip_find_all):
d += 1
doAssert d == 5
doNotOptimizeAway(d)
var sql_find_all_re = re.re"mysql://[^/\s?#]+[^\s?#]+(?:\?[^\s#]*)?(?:#[^\s]*)?"
bench(re_sql_find_all, m):
var d = 0
for i in 0 ..< m:
for _ in re.findAll(bench_text, sql_find_all_re):
d += 1
doAssert d == 4
doNotOptimizeAway(d)
const sql_find_all = regex.re2"mysql://[^/\s?#]+[^\s?#]+(?:\?[^\s#]*)?(?:#[^\s]*)?"
benchRelative(regex_sql_find_all, m):
var d = 0
for i in 0 ..< m:
for _ in regex.findAll(bench_text, sql_find_all):
d += 1
doAssert d == 4
doNotOptimizeAway(d)
var url_find_all_re = re.re"https?://[^/\s?#]+[^\s?#]+(?:\?[^\s#]*)?(?:#[^\s]*)?"
bench(re_url_find_all, m):
var d = 0
for i in 0 ..< m:
for _ in re.findAll(bench_text, url_find_all_re):
d += 1
doAssert d == 5295
doNotOptimizeAway(d)
const url_find_all = regex.re2"https?://[^/\s?#]+[^\s?#]+(?:\?[^\s#]*)?(?:#[^\s]*)?"
benchRelative(regex_url_find_all, m):
var d = 0
for i in 0 ..< m:
for _ in regex.findAll(bench_text, url_find_all):
d += 1
doAssert d == 5295
doNotOptimizeAway(d)
var unicode_find_all_re = re.re"\smůžete\s"
bench(re_unicode_find_all, m):
var d = 0
for i in 0 ..< m:
for _ in re.findAll(bench_text, unicode_find_all_re):
d += 1
doAssert d == 25
doNotOptimizeAway(d)
const unicode_find_all = regex.re2"\smůžete\s"
benchRelative(regex_unicode_find_all, m):
var d = 0
for i in 0 ..< m:
for _ in regex.findAll(bench_text, unicode_find_all):
d += 1
doAssert d == 25
doNotOptimizeAway(d)
when true:
bench(runes, m):
var d = 0
for i in 0 ..< m:
for _ in bench_text.runes:
d += 1
doNotOptimizeAway(d)
bench(dummy, m):
for i in 0 ..< m:
memoryClobber()
when isMainModule:
runBenchmarks()
#[
# Profiling:
# (but extract the bench to another module without nimbench)
# open the log with KCachegrind
$ nim c --debugger:native --threads:off -d:danger -d:useMalloc -o:bin/bench2 bench/bench2.nim && valgrind --tool=callgrind -v ./bin/bench2
# Bench
$ nim c -r --threads:off -d:danger --mm:arc -o:bin/bench bench/bench.nim
]#
================================================
FILE: bench/input-text.txt
================================================
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
<!DOCTYPE html>
<html>
<head>
<title>A hundred script tags? Never again!</title>
</head>
<body>
<script src="require.js" data-main="app/main"></script>
</body>
</html>
```
### 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
<script src="require.js" data-main="app/main-built"></script>
```
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:
// <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
///////////////////////////////////
// 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.
<!DOCTYPE html>
<html>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<body>
<div ng-app="">
<p>Name: <input type="text" ng-model="name"></p>
<p ng-bind="name"></p>
</div>
</body>
</html>
/*
* Example explained:
* AngularJS starts automatically when the web page has loaded.
* The ng-app directive tells AngularJS that the <div> 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 <p> element to the application variable name.
*/
<tag> Here are content to be interpreted </tag>
///////////////////////////////////
// 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 }}
<!DOCTYPE html>
<html>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<body>
<div ng-app="">
<p>My first expression: {{ 5 + 5 }}</p>
</div>
</body>
</html>
//If you remove the ng-app directive, HTML will display the expression as it is, without solving it:
<!DOCTYPE html>
<html>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<body>
<div>
<p>My first expression: {{ 5 + 5 }}</p>
</div>
</body>
</html>
// AngularJS expressions bind AngularJS data to HTML the same way as the ng-bind directive.
<!DOCTYPE html>
<html>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<body>
<div ng-app="">
<p>Name: <input type="text" ng-model="name"></p>
<p>{{name}}</p>
</div>
</body>
</html>
// AngularJS numbers are like JavaScript numbers:
<div ng-app="" ng-init="quantity=1;cost=5">
<p>Total in dollar: {{ quantity * cost }}</p>
</div>
//AngularJS strings are like JavaScript strings:
<div ng-app="" ng-init="firstName='John';lastName='Doe'">
<p>The name is <span ng-bind="firstName + ' ' + lastName"></span></p>
</div>
//AngularJS objects are like JavaScript objects:
<div ng-app="" ng-init="person={firstName:'John',lastName:'Doe'}">
<p>The name is {{ person.lastName }}</p>
</div>
//AngularJS arrays are like JavaScript arrays:
<div ng-app="" ng-init="points=[1,15,19,2,40]">
<p>The third result is {{ points[2] }}</p>
</div>
// 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.
<div ng-app="" ng-init="firstName='John'">
<p>Name: <input type="text" ng-model="firstName"></p>
<p>You wrote: {{ firstName }}</p>
</div>
//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:
<div ng-app="" ng-init="names=['Jani','Hege','Kai']">
<ul>
<li ng-repeat="x in names">
{{ x }}
</li>
</ul>
</div>
//The ng-repeat directive used on an array of objects:
<div ng-app="" ng-init="names=[
{name:'Jani',country:'Norway'},
{name:'Hege',country:'Sweden'},
{name:'Kai',country:'Denmark'}]">
<ul>
<li ng-repeat="x in names">
{{ x.name + ', ' + x.country }}
</li>
</ul>
</div>
// 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.
<div ng-app="myApp" ng-controller="myCtrl">
First Name: <input type="text" ng-model="firstName"><br>
Last Name: <input type="text" ng-model="lastName"><br>
<br>
Full Name: {{firstName + " " + lastName}}
</div>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.firstName = "John";
$scope.lastName = "Doe";
});
</script>
//Application explained:
//The AngularJS application is defined by ng-app="myApp". The application runs inside the <div>.
//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):
<div ng-app="myApp" ng-controller="personCtrl">
First Name: <input type="text" ng-model="firstName"><br>
Last Name: <input type="text" ng-model="lastName"><br>
<br>
Full Name: {{fullName()}}
</div>
<script>
var app = angular.module('myApp', []);
app.controller('personCtrl', function($scope) {
$scope.firstName = "John";
$scope.lastName = "Doe";
$scope.fullName = function() {
return $scope.firstName + " " + $scope.lastName;
}
});
</script>
//In larger applications, it is common to store controllers in external files.
//Just copy the code between the <script> </script> tags into an external file named personController.js:
<div ng-app="myApp" ng-controller="personCtrl">
First Name: <input type="text" ng-model="firstName"><br>
Last Name: <input type="text" ng-model="lastName"><br>
<br>
Full Name: {{firstName + " " + lastName}}
</div>
<script src="personController.js"></script>
// 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:
<div ng-app="myApp" ng-controller="namesCtrl">
<ul>
<li ng-repeat="x in names">
{{ x.name + ', ' + x.country }}
</li>
</ul>
</div>
<script src="namesController.js"></script>
///////////////////////////////////
// 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:
<div ng-app="myApp" ng-controller="personCtrl">
<p>The name is {{ lastName | uppercase }}</p>
</div>
//The lowercase filter format strings to lower case:
<div ng-app="myApp" ng-controller="personCtrl">
<p>The name is {{ lastName | lowercase }}</p>
</div>
//The currency filter formats a number as currency:
<div ng-app="myApp" ng-controller="costCtrl">
<input type="number" ng-model="quantity">
<input type="number" ng-model="price">
<p>Total = {{ (quantity * price) | currency }}</p>
</div>
//A filter can be added to a directive with a pipe character (|) and a filter.
//The orderBy filter orders an array by an expression:
<div ng-app="myApp" ng-controller="namesCtrl">
<ul>
<li ng-repeat="x in names | orderBy:'country'">
{{ x.name + ', ' + x.country }}
</li>
</ul>
<div>
//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:
<div ng-app="myApp" ng-controller="namesCtrl">
<p><input type="text" ng-model="test"></p>
<ul>
<li ng-repeat="x in names | filter:test | orderBy:'country'">
{{ (x.name | uppercase) + ', ' + x.country }}
</li>
</ul>
</div>
///////////////////////////////////
// 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.
<div ng-app="myApp" ng-controller="customersCtrl">
<ul>
<li ng-repeat="x in names">
{{ x.Name + ', ' + x.Country }}
</li>
</ul>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('customersCtrl', function($scope, $http) {
$http.get("http://www.w3schools.com/angular/customers.php")
.success(function(response) {$scope.names = response.records;});
});
</script>
Application explained:
// The AngularJS application is defined by ng-app. The application runs inside a <div>.
// 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:
<div ng-app="myApp" ng-controller="customersCtrl">
<table>
<tr ng-repeat="x in names">
<td>{{ x.Name }}</td>
<td>{{ x.Country }}</td>
</tr>
</table>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('customersCtrl', function($scope, $http) {
$http.get("http://www.w3schools.com/angular/customers.php")
.success(function (response) {$scope.names = response.records;});
});
</script>
// To sort the table, add an orderBy filter:
<table>
<tr ng-repeat="x in names | orderBy : 'Country'">
<td>{{ x.Name }}</td>
<td>{{ x.Country }}</td>
</tr>
</table>
// To display the table index, add a <td> with $index:
<table>
<tr ng-repeat="x in names">
<td>{{ $index + 1 }}</td>
<td>{{ x.Name }}</td>
<td>{{ x.Country }}</td>
</tr>
</table>
// Using $even and $odd
<table>
<tr ng-repeat="x in names">
<td ng-if="$odd" style="background-color:#f1f1f1">{{ x.Name }}</td>
<td ng-if="$even">{{ x.Name }}</td>
<td ng-if="$odd" style="background-color:#f1f1f1">{{ x.Country }}</td>
<td ng-if="$even">{{ x.Country }}</td>
</tr>
</table>
///////////////////////////////////
// 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.
<div ng-app="" ng-init="mySwitch=true">
<p>
<button ng-disabled="mySwitch">Click Me!</button>
</p>
<p>
<input type="checkbox" ng-model="mySwitch">Button
</p>
</div>
//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:
<p>
<button disabled>Click Me!</button>
</p>
// If the value of mySwitch evaluates to false, the button will not be disabled:
<p>
<button>Click Me!</button>
</p>
// The ng-show directive shows or hides an HTML element.
<div ng-app="">
<p ng-show="true">I am visible.</p>
<p ng-show="false">I am not visible.</p>
</div>
// 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:
<div ng-app="">
<p ng-show="hour > 12">I am visible.</p>
</div>
///////////////////////////////////
// AngularJS Events
// AngularJS has its own HTML events directives.
// The ng-click directive defines an AngularJS click event.
<div ng-app="myApp" ng-controller="myCtrl">
<button ng-click="count = count + 1">Click me!</button>
<p>{{ count }}</p>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.count = 0;
});
</script>
// 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.
<div ng-app="myApp" ng-controller="personCtrl">
<button ng-click="toggle()">Toggle</button>
<p ng-hide="myVar">
First Name: <input type="text" ng-model="firstName"><br>
Last Name: <input type="text" ng-model="lastName"><br>
<br>
Full Name: {{firstName + " " + lastName}}
</p>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('personCtrl', function($scope) {
$scope.firstName = "John",
$scope.lastName = "Doe"
$scope.myVar = false;
$scope.toggle = function() {
$scope.myVar = !$scope.myVar;
};
});
</script>
//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 <p> 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:
<div ng-app="myApp" ng-controller="personCtrl">
<button ng-click="toggle()">Toggle</button>
<p ng-show="myVar">
First Name: <input type="text" ng-model="firstName"><br>
Last Name: <input type="text" ng-model="lastName"><br>
<br>
Full Name: {{firstName + " " + lastName}}
</p>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('personCtrl', function($scope) {
$scope.firstName = "John",
$scope.lastName = "Doe"
$scope.myVar = true;
$scope.toggle = function() {
$scope.myVar = !$scope.myVar;
}
});
</script>
///////////////////////////////////
// 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"):
<!DOCTYPE html>
<html>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="myCtrl">
{{ firstName + " " + lastName }}
</div>
<script>
var app = angular.module("myApp", []);
app.controller("myCtrl", function($scope) {
$scope.firstName = "John";
$scope.lastName = "Doe";
});
</script>
</body>
</html>
// 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:
<!DOCTYPE html>
<html>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="myCtrl">
{{ firstName + " " + lastName }}
</div>
<script src="myApp.js"></script>
<script src="myCtrl.js"></script>
</body>
</html>
//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
// <body> element, it is recommended that you load the AngularJS library either
// in the <head> or at the start of the <body>.
// This is because calls to angular.module can only be compiled after the library has been loaded.
<!DOCTYPE html>
<html>
<body>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myCtrl">
{{ firstName + " " + lastName }}
</div>
<script>
var app = angular.module("myApp", []);
app.controller("myCtrl", function($scope) {
$scope.firstName = "John";
$scope.lastName = "Doe";
});
</script>
</body>
</html>
///////////////////////////////////
// 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.
<div ng-app="myApp" ng-controller="myCtrl">
First Name: <input type="text" ng-model="firstName"><br>
Last Name: <input type="text" ng-model="lastName"><br>
<br>
Full Name: {{firstName + " " + lastName}}
</div>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.firstName= "John";
$scope.lastName= "Doe";
});
</script>
// 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 الذي سنقوم بالعمل عليه. -->
<!doctype html>
<html>
<head>
<title>موقعي</title>
</head>
<body>
<h1>مرحبا بالعالم!</h1>
<a href = "http://codepen.io/anon/pen/xwjLbZ">الق نظرة كيف يبدو هذا من هنا</a>
<p>هذه فقرة.</p>
<p>هذه فقرة أخرى.</p>
<ul>
<li>هذا عنصر من لائحة غير مرقمة. (لائحة بالعرائض)</li>
<li>هذا عنصر آخر</li>
<li>وهذا آخر عنصر في اللائحة</li>
</ul>
</body>
</html>
<!-- ملف HTML يُبتدأ دائما بتبيين أنه ملف HTML للمتصفح -->
<!doctype html>
<!-- بعد هذا، يبدأ بفتح الوسم <html> -->
<html>
<!-- الذي سيغلق في نهاية الملف بـ </html>. -->
</html>
<!-- لا يجب كتابة أي شيء بعد وسم النهاية ذاك. -->
<!-- داخل هذين الوسمين (<html></html>) نجد: -->
<!-- "ترئيس" محدد ب <head> (يجب أن يغلق بـ </head>) -->
<!-- الترأيس يحتوي على أوصاف وبعض المعلومات الإضافية التي لا تظهر في المتصفح, تدعي metadata (المعلومات الوصفية) -->
<head>
<title>موقعي</title><!-- الوسم <title> يحدد للمتصفح العنوان الذي يظهر في المكان المخصص للعنوان في نافذة المتصفح. -->
</head>
<!-- بعد الجزء الخاص بـ <head>، نجد الوسم <body> -->
<!-- حتى هنا، لا شيء مما كُتب سيظهر في النافذة الرئيسية للمتصفح. -->
<!-- يجب ان نملأ "جسد" الصفحة بالمحتوى الذي نريد أن نُظهر -->
<body>
<h1>مرحبا بالعالم!</h1> <!-- الوسم <h1> خاص بالعناوين الكبيرة. -->
<!-- هناك أيضا وسوم خاصة بالعناوين الفرعية من h1، الأكثر أهمية h2 والذي يليه حتى h6 الذي هو آخر عنوان داخلي. -->
<a href = "http://codepen.io/anon/pen/xwjLbZ">ألق نظرة كيف يبدو هذا من هنا</a> <!-- يظهر رابطا للصفحة التي داخل السمة href="" -->
<p>هذه فقرة.</p> <!-- يمكن من اضافة نصوص للصفحة. يميز الفقرات -->
<p>هذه فقرة أخرى.</p>
<ul> <!-- الوسم <ul> يخلق لائحة بالعرائض -->
<!-- إذا أردت لائحة مرقمة، هناك الوسم <ol>. ويكون الترتيب فيه حسب تموضع العناصر داخله، الأول فالأول. -->
<li>هذا عنصر من لائحة غير مرقمة. (لائحة بالعرائض)</li>
<li>هذا عنصر آخر</li>
<li>وهذا آخر عنصر في اللائحة</li>
</ul>
</body>
<!-- وهكذا، كتابة ملفات HTML جد بسيطة -->
<!-- يمكنك كذلك إضافة أنواع أخرى من الوسوم -->
<!-- لادخال صورة: -->
<img src="http://i.imgur.com/XWG0O.gif"/> <!-- مصدر الصورة يحدد داخل السمة: src="" -->
<!-- مصدرها يمكن أن يكون رابطا أو مسارا لصورة في حاسوبك -->
<!-- يمكنك كذلك تشكيل جداول. -->
<table> <!-- نفتح الجدول بالوسم <table> -->
<tr> <!-- <tr> تسمح بتشكيل صف. -->
<th>العنوان الأول</th> <!-- <th> تسمح لنا بإعطاء عنوان لهذا العمود. -->
<th>العنوان الثاني</th>
</tr>
<tr>
<td>الصف الأول، العمود الأول</td> <!-- <td> تسمح بتشكيل الأعمدة، أو خانات داخل كل صف. -->
<td>الصف الأول، العمود الثاني</td>
</tr>
<tr>
<td>الصف الثاني، العمود الأول</td>
<td>الصف الثاني، العمود الأول</td>
</tr>
</table>
```
## الاستعمال
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 <first.last@learnxinyminutes.com>
Start of this document.
```
Multiple Authors
```
= Document Title
John Doe <john@go.com>; Jane Doe<jane@yo.com>; Black Beard <beardy@pirate.com>
Start of a doc with multiple authors.
```
Revision Line (requires an author line)
```
= Doc Title V1
Potato Man <chip@crunchy.com>
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 <h2>
=== Level 2 <h3>
==== Level 3 <h4>
===== Level 4 <h5>
====== Level 5 <h6>
======= Level 6 <h7>
```
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 n<sub>0</sub>, `f(n)` <= `c g(n)` for every input size
n (n > n<sub>0</sub>).
*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, n<sub>0</sub> that satisfies this for all n > <sub>0</sub>?
```
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, n<sub>0</sub> that satisfies this for all n > <sub>0</sub>?
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 n<sub>0</sub> (n<sub>0</sub> > 0), `f(n)` is >= `c g(n)`
for every input size n (n > n<sub>0</sub>).
### 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 n<sub>0</sub> (n<sub>0</sub> > 0), `f(n)` is < `c g(n)`
for every input size n (n > n<sub>0</sub>).
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 n<sub>0</sub> (n<sub>0</sub> > 0), `f(n)` is > `c g(n)`
for every input size n (n > n<sub>0</sub>).
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 n<sub>0</sub> (c1 > 0, c2 > 0, n<sub>0</sub> > 0),
`c1 g(n)` is < `f(n)` is < `c2 g(n)` for every input size n (n > n<sub>0</sub>).
∴ `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 <cstdio>
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 <iostream> // 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 <myInt>"
cerr << "Used for error messages";
}
//////////
// Strings
//////////
// Strings in C++ are objects and have many member functions
#include <string>
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 <iostream>
// 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 <name> and weights <weight>"
// "Dog is owned by <owner>"
}
//////////////////////////////////////////
// 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 <iostream>
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 T>
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<int> intBox;
// and you can use it as you would expect:
intBox.insert(123);
// You can, of course, nest templates:
Box<Box<int> > 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<typename T>
// 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<class T>
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<int Y>
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 <exception>
#include <stdexcept>
// 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<Foo, int> fooMap;
std::map<Foo, int, compareFunction> 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<pair<int, int> > 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 <algorithm> header
sort(tester.begin(), tester.end(), [](const pair<int, int>& lhs, const pair<int, int>& 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<int> 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<tuple>
// 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<int, char, double> third(11, 'A', 3.14141);
// tuple_size returns number of elements in a tuple (as a constexpr)
cout << tuple_size<decltype(third)>::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<Data_Type> 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<Vector_name.size(); i++)
// It will iterate through the vector from index '0' till last index
// Iterator
vector<Data_Type>::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>
set<int> 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<int>::iterator it;
for(it=ST.begin();it<ST.end();it++) {
cout << *it << endl;
}
// Output:
// 10
// 30
// To clear the complete container we use Container_name.clear()
ST.clear();
cout << ST.size(); // will print the size of set ST
// Output: 0
// NOTE: for duplicate elements we can use multiset
// Map
// Maps store elements formed by a combination of a key value
// and a mapped value, following a specific order.
#include<map>
map<char, int> mymap; // Will initialize the map with key as char and value as int
mymap.insert(pair<char,int>('A',1));
// Will insert value 1 for key A
mymap.insert(pair<char,int>('Z',26));
// Will insert value 26 for key Z
// To iterate
map<char,int>::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
<http://cppreference.com/w/cpp>
Additional resources may be found at <http://cplusplus.com>
---
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 <keyword>
// 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 <stdlib.h>
#include <stdio.h>
#include <string.h>
// (File names between <angle brackets> 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 <limits.h>
// 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:
// <return type> <function name>(<args>)
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 <string.h>
/* 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<String>) {
/*
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<Long> {
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 c
gitextract_tvdvmii5/
├── .github/
│ ├── FUNDING.yml
│ └── workflows/
│ └── ci.yml
├── .gitignore
├── CHANGELOG.md
├── LICENSE
├── README.md
├── bench/
│ ├── README.md
│ ├── bench.nim
│ └── input-text.txt
├── docs/
│ ├── index.html
│ └── regex/
│ └── .keep
├── regex.nimble
├── src/
│ ├── regex/
│ │ ├── common.nim
│ │ ├── compiler.nim
│ │ ├── dotgraph.nim
│ │ ├── exptransformation.nim
│ │ ├── exptype.nim
│ │ ├── litopt.nim
│ │ ├── nfa.nim
│ │ ├── nfafindall.nim
│ │ ├── nfafindall2.nim
│ │ ├── nfamacro.nim
│ │ ├── nfamatch.nim
│ │ ├── nfamatch2.nim
│ │ ├── nfatype.nim
│ │ ├── nodematch.nim
│ │ ├── oldregex.nim
│ │ ├── parser.nim
│ │ ├── scanner.nim
│ │ └── types.nim
│ └── regex.nim
└── tests/
├── tests.nim
├── tests2.nim
└── tests_misc.nim
Condensed preview — 34 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (7,643K chars).
[
{
"path": ".github/FUNDING.yml",
"chars": 834,
"preview": "# These are supported funding model platforms\n\ngithub: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [u"
},
{
"path": ".github/workflows/ci.yml",
"chars": 1332,
"preview": "name: CI\n\non:\n push:\n branches:\n - master\n pull_request:\n\njobs:\n test:\n name: Nim ${{ matrix.nim }}\n ru"
},
{
"path": ".gitignore",
"chars": 236,
"preview": "nimcache/\nsrc/regex.js\nsrc/regex.out\nsrc/regex/litopt\nsrc/regex/nfatype\nsrc/regex/common\ntests/tests\ntests/tests.js\ntest"
},
{
"path": "CHANGELOG.md",
"chars": 5419,
"preview": "v0.26.2\n==================\n\n* Performance improvements\n\nv0.26.1\n==================\n\n* Fix unicode case-insensitive match"
},
{
"path": "LICENSE",
"chars": 1079,
"preview": "MIT License\n\nCopyright (c) 2017 Esteban Castro Borsani\n\nPermission is hereby granted, free of charge, to any person obta"
},
{
"path": "README.md",
"chars": 1148,
"preview": "# Regex\n\n[: string {.com"
},
{
"path": "bench/input-text.txt",
"chars": 6194652,
"preview": "This file is a concatenation of [Learn X in Y minutes](https://github.com/adambard/learnxinyminutes-docs) for testing pu"
},
{
"path": "docs/index.html",
"chars": 191,
"preview": "<!DOCTYPE html>\n<html>\n <head>\n <meta http-equiv=\"Refresh\" content=\"0; url=regex.html\" />\n </head>\n <body>\n <p>"
},
{
"path": "docs/regex/.keep",
"chars": 5,
"preview": "#keep"
},
{
"path": "regex.nimble",
"chars": 2237,
"preview": "# Package\n\nversion = \"0.26.3\"\nauthor = \"Esteban Castro Borsani (@nitely)\"\ndescription = \"Linear time regex matching\"\nlic"
},
{
"path": "src/regex/common.nim",
"chars": 7698,
"preview": "import std/unicode\nimport std/strutils\nimport std/algorithm\nwhen defined(nimPreviewSlimSystem):\n import std/assertions\n"
},
{
"path": "src/regex/compiler.nim",
"chars": 832,
"preview": "import ./common\nimport ./parser\nimport ./exptransformation\nimport ./types\nimport ./nfatype\nimport ./nfa\nimport ./litopt\n"
},
{
"path": "src/regex/dotgraph.nim",
"chars": 1712,
"preview": "import std/strutils\nimport std/hashes\nimport std/os\n\nimport ./nfatype\nimport ./types\n\nfunc getEpsilonTransitions(nfa: Nf"
},
{
"path": "src/regex/exptransformation.nim",
"chars": 14608,
"preview": "import std/unicode\nimport std/sets\nimport std/tables\nimport std/algorithm\nwhen defined(nimPreviewSlimSystem):\n import s"
},
{
"path": "src/regex/exptype.nim",
"chars": 94,
"preview": "import ./types\n\ntype\n Exp* = object\n s*: seq[Node]\n AtomsExp* = object\n s*: seq[Node]\n"
},
{
"path": "src/regex/litopt.nim",
"chars": 17968,
"preview": "## Literals optimization.\n## This is about optimizing the find operation\n## by quickly searching Regular Expression lite"
},
{
"path": "src/regex/nfa.nim",
"chars": 8461,
"preview": "import std/deques\nimport std/algorithm\nwhen defined(nimPreviewSlimSystem):\n import std/assertions\n\nimport ./types\nimpor"
},
{
"path": "src/regex/nfafindall.nim",
"chars": 6515,
"preview": "## DEPRECATED\n\nimport std/unicode\nimport std/tables\nfrom std/strutils import find\nwhen defined(nimPreviewSlimSystem):\n "
},
{
"path": "src/regex/nfafindall2.nim",
"chars": 8146,
"preview": "## Linear time NFA findAll\n\n#[\nThe nfamatch find algorithm can be used\nto search all matches within a string,\nhowever do"
},
{
"path": "src/regex/nfamacro.nim",
"chars": 17115,
"preview": "## NFA matcher for static regexes\n\nimport std/macros\nimport std/unicode\nimport std/tables\nimport std/sets\nimport std/alg"
},
{
"path": "src/regex/nfamatch.nim",
"chars": 6217,
"preview": "## DEPRECATED\n\nimport std/unicode\nimport std/tables\nwhen defined(nimPreviewSlimSystem):\n import std/assertions\n\nimport "
},
{
"path": "src/regex/nfamatch2.nim",
"chars": 8327,
"preview": "## NFA matcher for non-static regexes\n\nimport std/unicode\nimport std/tables\nwhen defined(nimPreviewSlimSystem):\n import"
},
{
"path": "src/regex/nfatype.nim",
"chars": 14322,
"preview": "## Types used by the NFA\n\nimport std/tables\nimport std/sets\nimport std/algorithm\nimport std/math\nimport std/bitops\nwhen "
},
{
"path": "src/regex/nodematch.nim",
"chars": 4577,
"preview": "import std/unicode except `==`\nwhen defined(nimPreviewSlimSystem):\n import std/assertions\n\nimport pkg/unicodedb/casing\n"
},
{
"path": "src/regex/oldregex.nim",
"chars": 10401,
"preview": "# Deprecated regex.nim API\n\nimport std/tables\nimport std/sequtils\nimport std/unicode\nfrom std/strutils import addf\nwhen "
},
{
"path": "src/regex/parser.nim",
"chars": 19883,
"preview": "import std/unicode\nimport std/strutils\nimport std/sets\nimport std/parseutils\nimport std/sequtils\nwhen defined(nimPreview"
},
{
"path": "src/regex/scanner.nim",
"chars": 2140,
"preview": "import std/unicode\n\nimport ./types\nimport ./common\n\nfunc toByteRunes(s: string): seq[Rune] =\n result = newSeqOfCap[Rune"
},
{
"path": "src/regex/types.nim",
"chars": 8437,
"preview": "# XXX hack because of nfamatch compile warning\n{.used.}\n\nimport std/unicode\nfrom std/sequtils import toSeq\nwhen defined("
},
{
"path": "src/regex.nim",
"chars": 45030,
"preview": "##[\nA library for parsing, compiling, and executing\nregular expressions. The match time is linear\nin the length of the t"
},
{
"path": "tests/tests.nim",
"chars": 90381,
"preview": "from std/sequtils import map\nwhen defined(nimPreviewSlimSystem):\n import std/assertions\n\nimport ../src/regex\n\n{.push wa"
},
{
"path": "tests/tests2.nim",
"chars": 131711,
"preview": "from std/unicode import runeLen\nfrom std/sequtils import map\nfrom std/strutils import contains\nwhen defined(nimPreviewSl"
},
{
"path": "tests/tests_misc.nim",
"chars": 42032,
"preview": "#[\n *\n *\tGlenn Fowler <glenn.s.fowler@gmail.com>\n *\tAT&T Research\n *\n * PLEASE: publish your tests so everyone can benef"
}
]
About this extraction
This page contains the full source code of the nitely/nim-regex GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 34 files (6.4 MB), approximately 1.7M tokens. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.