diff options
106 files changed, 12135 insertions, 2561 deletions
diff --git a/CONTRIBUTING.markdown b/CONTRIBUTING.markdown index e2192d88..18a5a5d7 100644 --- a/CONTRIBUTING.markdown +++ b/CONTRIBUTING.markdown @@ -52,6 +52,8 @@ languages: Other fields: +- **category**: The category of the article. So far, can be one of *language*, + *tool* or *Algorithms & Data Structures*. Defaults to *language* if omitted. - **filename**: The filename for this article's code. It will be fetched, mashed together, and made downloadable. + For non-English articles, *filename* should have a language-specific diff --git a/ansible.html.markdown b/ansible.html.markdown index 2b61cc8e..41a8c9b5 100644 --- a/ansible.html.markdown +++ b/ansible.html.markdown @@ -49,7 +49,7 @@ environments, it may be noticable amount. 'on-demand' - there is no built-in mechanism that would warn you about some change automatically (this can be achieved with reasonable effort) * Official GUI - Ansible Tower - is great but expensive. -* There is no 'small enterprice' payment plan, however Ansible AWX is the free +* There is no 'small enterprise' payment plan, however Ansible AWX is the free open source version we were all waiting for. #### Neutral diff --git a/ar-ar/python3-ar.html.markdown b/ar-ar/python3-ar.html.markdown new file mode 100644 index 00000000..e1a12690 --- /dev/null +++ b/ar-ar/python3-ar.html.markdown @@ -0,0 +1,1019 @@ +--- +language: python3 +contributors: + - ["Louie Dinh", "http://pythonpracticeprojects.com"] + - ["Steven Basart", "http://github.com/xksteven"] + - ["Andre Polykanine", "https://github.com/Oire"] + - ["Zachary Ferguson", "http://github.com/zfergus2"] + - ["evuez", "http://github.com/evuez"] + - ["Rommel Martinez", "https://ebzzry.io"] + - ["Roberto Fernandez Diaz", "https://github.com/robertofd1995"] +translators: + - ["Ahmad Hegazy", "https://github.com/ahegazy"] +lang: ar-ar +filename: learnpython3-ar.py +--- + +لقد أُنشئت لغة البايثون بواسطة جايدو ڤان روسم في بداية التسعينات. هي الأن أحد أشهر اللغات الموجودة. +لقد أحببت لغة البايثون بسبب وضوحها. هي في الأساس عبارة عن سودوكود قابل للتنفيذ. + +ردود أفعالكم عن المقال مُقدرة بشدة. يمكنكم التواصل مع الكاتب الاساسي من خلال [@louiedinh](http://twitter.com/louiedinh) أو louiedinh [at] [google's email service] + +ملحوظة: هذا المقال يُطبق على بايثون 3 فقط. راجع المقال [هنا](http://learnxinyminutes.com/docs/python/) إذا أردت تعلم لغة البايثون نسخة 2.7 الأقدم + +```python + +# تعليق من سطر واحد يبدأ برمز الرقم. + +""" يمكن كتابة تعليق يتكون من أكثر من سطر + باستخدام ثلاثة علامات " + ، وعادة يُستخدم في كتابة التوثيقات. +""" + +#################################################### +## 1. أنواع البيانات البدائية والعمليات +#################################################### + +# لديك أرقام +3 # => 3 + +# العمليات الحسابية هي ما تتوقعه +1 + 1 # => 2 +8 - 1 # => 7 +10 * 2 # => 20 +35 / 5 # => 7.0 + +# نتائج قسمة الأرقام الصحيحية تُقرب للأصغر سواءًا كانت الأرقام موجبة أو سالبة. +5 // 3 # => 1 +5.0 // 3.0 # => 1.0 # يعمل في حالة الكسور أيضا +-5 // 3 # => -2 +-5.0 // 3.0 # => -2.0 + +# ناتج القسمة هو دائما كسر +10.0 / 3 # => 3.3333333333333335 + +# عملية باقي القسمة +7 % 3 # => 1 + +# الأُس (س ** ص، رفع س لقوى ص) +2**3 # => 8 + +# أفرض ترتيب العمليات الحسابية بالأقواس +(1 + 3) * 2 # => 8 + +# القيم الثنائية هي المعروفة عموما (ﻻحظ: تكبير أول حرف) +True +False + +# أنفي بـ (not) +not True # => False +not False # => True + +# العمليات على القيم الثنائية +# ﻻحظ ﻻيهم حالة الحرف (كبير أو صغير) في "and" و "or" +True and False # => False +False or True # => True + +# True و False هما في الواقع 1 و 0 لكن بمسميات مختلفة +True + True # => 2 +True * 8 # => 8 +False - 5 # => -5 + +# عمليات المقارنة تنظر الي القيمة الرقمية لل True وال False +0 == False # => True +1 == True # => True +2 == True # => False +-5 != False # => True + +# عند استخدام المنطق الثنائي على القيم الصحيحة يتم تحويلهم الي قيم ثنائية لإجرات العمليات عليهم، لكن قيمهم الأصلية تعود +# ﻻ تخلط بين bool(قيمة صحيحة) و العمليات المنطقية الثناية and/or (&,|) +bool(0) # => False +bool(4) # => True +bool(-6) # => True +0 and 2 # => 0 +-5 or 0 # => -5 + +# مقارنة التساوي ب == +1 == 1 # => True +2 == 1 # => False + +# مقارنة الاختلاف ب != +1 != 1 # => False +2 != 1 # => True + +# مقارنات أخرى +1 < 10 # => True +1 > 10 # => False +2 <= 2 # => True +2 >= 2 # => True + +# لمعرفة هل القيمة في نطاق معين +1 < 2 and 2 < 3 # => True +2 < 3 and 3 < 2 # => False + +# التسلسل يجعلها تبدو أجمل +1 < 2 < 3 # => True +2 < 3 < 2 # => False + +# (is مقابل ==) is تتحق من أن المتغيرين يشيران إلي نفس العنصر, +# لكن == تتحقق من أن العنصرين المُشار اليهما بالمتغيرين لهما نفس القيمة. +a = [1, 2, 3, 4] # اجعل a تشير إلي قائمة جديدة, [1, 2, 3, 4] +b = a # اجعل a تُشير الي ما تُشير إليه b +b is a # => True, a و b يُشيران إلي نفس العنصر +b == a # => True, قيمة عنصر a و b متساوية +b = [1, 2, 3, 4] # اجعل b تشير الي قائمة جديدة , [1, 2, 3, 4] +b is a # => False, a و b do ﻻ يشيران إلي نفس العنصر +b == a # => True, قيمة عنصر a و b متساوية + +# يمكنك إنشاء الكلمات (تسلسلات الحروف) عن طريق " أو ' +"This is a string." +'This is also a string.' + +# يمكنك جمع هذا النوع أيضا! لكن حاول ألا تفعل هذا. +"Hello " + "world!" # => "Hello world!" +# يمكنك الربط بين الكلمات بدون استخدام '+' (لكن ليس المتغيرات) +"Hello " "world!" # => "Hello world!" + +# يمكنك معاملة الكلمات كقائمة من الحروف +"This is a string"[0] # => 'T' + +# يمكنك معرفة طول الكلمة +len("This is a string") # => 16 + +# .format يمكنك استخدامها لبناء الجمل بشكل معين, مثل هذا: +"{} can be {}".format("Strings", "interpolated") # => "Strings can be interpolated" + +# يمكنك تكرار معاملات بناء الجملة لتقليل الكتابة. +"{0} be nimble, {0} be quick, {0} jump over the {1}".format("Jack", "candle stick") +# => "Jack be nimble, Jack be quick, Jack jump over the candle stick" + +# يمكنك استخدام الكلمات المفتاحية إذا لم تُرد العد. +"{name} wants to eat {food}".format(name="Bob", food="lasagna") # => "Bob wants to eat lasagna" + +# إذا كان كود بايثون 3 الخاص بك يحتاج لبايثون 2.5 أو نسخة أقدم +# يمكنك استخدام أسلوب بناء الجمل القديم: +"%s can be %s the %s way" % ("Strings", "interpolated", "old") # => "Strings can be interpolated the old way" + +# يمكنك أبضا بناء الجمل باستخدام f-strings أو حروف بناء الجمل (في بايثون 3.6 فما فوق) +name = "Reiko" +f"She said her name is {name}." # => "She said her name is Reiko" +# يمكنك ببساطة وضع أي كود بايثون داخل أقواس وستقوم بإخراج الجملة. +f"{name} is {len(name)} characters long." + + +# None عبارة عن كائن +None # => None + +# ﻻ تستخدم رمز المساواة "==" لمقارنة العناصر ب None +# استخدم is بدلا منه. يقوم بالتحقق من مساواة هوية العنصر +"etc" is None # => False +None is None # => True + +# None, 0, قوائم/جمل/قواميس/صفوف فارغة كلها تُترجم إلي False. +# كل القيم الأخرى True. +bool(0) # => False +bool("") # => False +bool([]) # => False +bool({}) # => False +bool(()) # => False + +#################################################### +## 2. المتغيرات والمجموعات +#################################################### + +# بايثون لديها دالة عرض "print" +print("I'm Python. Nice to meet you!") # => I'm Python. Nice to meet you! + +# الافتراضي دالة print تطبع سطر جديد في النهاية. +# استخدم المعامل end لتغيير أخر الجملة المعروضة. +print("Hello, World", end="!") # => Hello, World! + +# طريقة بسيطة لطلب مدخل من الطرفية +input_string_var = input("Enter some data: ") # يقوم بإعادة البيانات ك "string" +# لاحظ: في النسخ القديمة من بايثون، دالة input() كان اسمها raw_input() + +# ﻻ يوجد تعريفات للمتغيرات، يتم تعيين قيمة المتغير مباشرة. +# العٌرف تسمية المتغيرات حروف_صغيرة_مع_خطوط_سُفلية +some_var = 5 +some_var # => 5 + +# محاولة استخدام متغير غير مُعين يعتبر خطأ +# إقرأ جزء 3.مسار التحكم لمعرفة المزيد عن التحكم في الأخطاء +some_unknown_var # يعرض خطأ NameError + +# يمكن استخدام if كتعبير واحد +# مساوِ للتعبير الأتي في لغة السي '?:' عملية ثلاثية +"yahoo!" if 3 > 2 else 2 # => "yahoo!" + +# القوائم تحفظ المتسلسلات +li = [] +# يمكنك البدأ بقائمة مليئة +other_li = [4, 5, 6] + +# إضافة بيانات لأخر القائمة عن طريق append +li.append(1) # li is now [1] +li.append(2) # li is now [1, 2] +li.append(4) # li is now [1, 2, 4] +li.append(3) # li is now [1, 2, 4, 3] +# حذف أخر عنصر في القائمة عن طريق pop +li.pop() # => 3 and li is now [1, 2, 4] +# هيا نعيده ثانية +li.append(3) # li is now [1, 2, 4, 3] again. + +# يمكنك الوصول لعناصر القائمة كما تفعل في ال array +# Access a list like you would any array +li[0] # => 1 +# للوصول لأخر عنصر +li[-1] # => 3 + +# محاولة الوصول لعنصر خارج نطاق القائمة يعتبر خطأ: IndexError +li[4] # يعرض خطأ IndexError + +# يمكنك النظر للنطاقات باستخدام تركيب التقطيع +# مؤشر/رقم/فهرس البداية مُضمن، مؤشر النهاية ﻻ +# (لمحبي الرياضيات هو نطاق مفتوح/مغلق) +li[1:3] # => [2, 4] +# إحذف أول عنصر ثم إعرض القائمة +li[2:] # => [4, 3] +# إحذف أخر عنصر ثم إعرض القائمة +li[:3] # => [1, 2, 4] +# حدد عنصر ثم إحذف الذي يليه ثم حدد عنصر وهكذا +li[::2] # =>[1, 4] +# اعرض نسخة معكوسة من القائمة +li[::-1] # => [3, 4, 2, 1] +# إستخدم أي تجميعة من الطرق المذكورة لعمل تقطيعات متقدمة +# li[start:end:step] + +# عمل نسخة من طبقة واحدة باستخدم التقطيع +li2 = li[:] # => li2 = [1, 2, 4, 3] لكن عند عمل(li2 is li) سينتج False. + +# إمسح أي عنصر من القائمة باستخدام "del" +del li[2] # li is now [1, 2, 3] + +# إمسح أول ظهور لقيمة. +li.remove(2) # li is now [1, 3] +li.remove(2) # يعرض خطأ ValueError لأن 2 غير موجود في القائمة + +# أضف عنصر في خانة معينة +li.insert(1, 2) # li is now [1, 2, 3] مرة أخرى + +# أحصل على مؤشر/رقم لأول ظهور للقيمة +li.index(2) # => 1 +li.index(4) # يعرض خطأ ValueError لأن 4 غير موجودة في القائمة + +# يمكنك جمع قوائم +# لاحظ: لا يتم تعديل قيمة li و other_li +li + other_li # => [1, 2, 3, 4, 5, 6] + +# إستخدم دالة "extend()" لربط القوائم +li.extend(other_li) # Now li is [1, 2, 3, 4, 5, 6] + +# راجع وجود قيمة في القائمة باستخدام "in" +1 in li # => True + +# إحصل على طول القائمة باستخدام دالة "len()" +len(li) # => 6 + + +# الصفوف تشبه القوائم لكنها غير قابلة للتغيير. +tup = (1, 2, 3) +tup[0] # => 1 +tup[0] = 3 # يعرض خطأ TypeError + +# لاحظ أن صف طوله عنصر واحد يحتاج لإضافة فاصلة "," بعد أخر عنصر +# لكن الصفوف من أي طول أخر، حتى صفر لا تحتاج. +type((1)) # => <class 'int'> +type((1,)) # => <class 'tuple'> +type(()) # => <class 'tuple'> + +# يمكنك عمل معظم عمليات القوائم على الصفوف. +len(tup) # => 3 +tup + (4, 5, 6) # => (1, 2, 3, 4, 5, 6) +tup[:2] # => (1, 2) +2 in tup # => True + +# يمكنك تفريغ الصفوف (أو القوائم) في متغيرات +a, b, c = (1, 2, 3) # a is now 1, b is now 2 and c is now 3 +# يمكنك أيضا عمل تفريغ واسع +a, *b, c = (1, 2, 3, 4) # a is now 1, b is now [2, 3] and c is now 4 +# الصفوف تُنشأ تلقائيا إذا تركت الأقواس +d, e, f = 4, 5, 6 # تم توسعة الصف 4, 5 ,6 في المتغيرات d, e, f +# بالترتيب حيث d = 4, e = 5 و f = 6 +# الأن إنظر إلي مدى سهولة التبديل بين قيم متغيرين +e, d = d, e # d is now 5 and e is now 4 + + +# القواميس تُخزن خرائط من المفتاح للقيمة +empty_dict = {} +# هذا قاموس مملوء +filled_dict = {"one": 1, "two": 2, "three": 3} + +# لاحظ أن القواميس يجب أن تكون أنواع غير قابلة للتغيير. +# هذا للتأكد من أن المفتاح يمكن تحويله لقيمة ثابتة للوصول السريع. +# الأنواع الغير قابلة للتغير تتضمن: الأرقام الصحيحة، الكسور، الكلمات، الصفوف. +invalid_dict = {[1,2,3]: "123"} # =>يعرض خطأ TypeError: unhashable type: 'list' +valid_dict = {(1,2,3):[1,2,3]} # القيم يمكن أن تكون من أي نوع. + +# يمكنك البحث عن قيمة باستخدام [] +filled_dict["one"] # => 1 + +# يمكنك الحصول على كل المفاتيح باستخدام "keys()". +# نحتاج لإرسالها لدالة list() لتحويلها لقائمة. سنتعلم هذا لاحقًا +# لاحظ - لنسخ بايثون قبل 3.7، ترتيب مفاتيح القاموس غير مضمون. نتائجك +# يمكن ألا تساوي المثال بالأسفل. مع ذلك، من أول بايثون 3.7، +# عناصر القاموس تحتفظ بالترتيب الذي تم إضافة المفاتيح به في القاموس. +list(filled_dict.keys()) # => ["three", "two", "one"] in Python <3.7 +list(filled_dict.keys()) # => ["one", "two", "three"] in Python 3.7+ + +# يمكنك الحصول على كل القيم باستخدام "values()". +# مرة أخرى نستخدم list() للحصول عليها كقائمة. +# نفس الكلام السابق بخصوص ترتيب المفاتيح +list(filled_dict.values()) # => [3, 2, 1] in Python <3.7 +list(filled_dict.values()) # => [1, 2, 3] in Python 3.7+ + +# إفحص للتأكد من وجود مغتاح في القاموس باستخدام "in" +"one" in filled_dict # => True +1 in filled_dict # => False + +# البحث عن مفتاح غير موجود يعرض خطأ KeyError +filled_dict["four"] # KeyError + +# استخدم "get()" لتجنب الخطأ KeyError +filled_dict.get("one") # => 1 +filled_dict.get("four") # => None +# دالة get تدعم إدخال قيمة افتراضية عند عدم وجود البحث +filled_dict.get("one", 4) # => 1 +filled_dict.get("four", 4) # => 4 + +# "setdefault()" تقوم بإدخال قيمة جديدة في القاموس في حالة عدم وجود المفتاح فقط. +filled_dict.setdefault("five", 5) # filled_dict["five"] is set to 5 +filled_dict.setdefault("five", 6) # filled_dict["five"] is still 5 + +# إضافة عنصر للقاموس +filled_dict.update({"four":4}) # => {"one": 1, "two": 2, "three": 3, "four": 4} +filled_dict["four"] = 4 # طريقة أخرى للإضافة + +# مسح المفاتيح من القاموس باستخدام del +del filled_dict["one"] # Removes the key "one" from filled dict + +# من بايثون 3.5 فما فوق يمكنك أيضا استخدام خيارات تفريغ إضافية +{'a': 1, **{'b': 2}} # => {'a': 1, 'b': 2} +{'a': 1, **{'a': 2}} # => {'a': 2} + + +# المجموعات تُخزن .. مجموعات +empty_set = set() +# .تهيئة مجموعة بمجموعة قيم. نعم، تشبه قليلا تهيئة القاموس. أسف +some_set = {1, 1, 2, 2, 3, 4} # some_set is now {1, 2, 3, 4} + +# مثل مفتاح القاموس، عناصر المجموعة يجب أن تكون غير قابلة للتغيير. +invalid_set = {[1], 1} # => يعرض خطأ TypeError: unhashable type: 'list' +valid_set = {(1,), 1} + +# إضافة عنصر أخر للمجموعة +filled_set = some_set +filled_set.add(5) # filled_set is now {1, 2, 3, 4, 5} +# المجموعات لا يمكن أن تحتوي على عناصر مكررة +filled_set.add(5) # it remains as before {1, 2, 3, 4, 5} + +# تقاطع مجموعتين باستخدام & +other_set = {3, 4, 5, 6} +filled_set & other_set # => {3, 4, 5} + +# اتحاد مجموعتين باستخدام | +filled_set | other_set # => {1, 2, 3, 4, 5, 6} + +# الفرق بين مجموعتين باستخدام - +{1, 2, 3, 4} - {2, 3, 5} # => {1, 4} + +# الفروق بين مجموعتين باستخدام ^ +{1, 2, 3, 4} ^ {2, 3, 5} # => {1, 4, 5} + +# لفحص هل المجموعة على اليسار مجموعة عُليا للمجموعة على اليمين (تحتوي على كل عناصرها) +{1, 2} >= {1, 2, 3} # => False + +# لفحص هل المجموعة على اليسار مجموعة فرعية من المجموعة على اليمين +{1, 2} <= {1, 2, 3} # => True + +# للتأكد من وجود عن في مجموعة استخدم in +2 in filled_set # => True +10 in filled_set # => False + + + +#################################################### +## 3. مسار التحكم والعمليات التكرارية #Control Flow and Iterables +#################################################### + +# هيا ننشيء متغير +some_var = 5 + +# الأن الأمر if. الفجوات (المسافات قبل الأوامر) مهمة في البايثون! +# العُرف استخدام أربع مسافات. ليس تبويب. +# هذا السطر البرمجي يطبع "some_var is smaller than 10" +if some_var > 10: + print("some_var is totally bigger than 10.") +elif some_var < 10: # This elif clause is optional. + print("some_var is smaller than 10.") +else: # This is optional too. + print("some_var is indeed 10.") + + +""" +For عبارة عن حلقات تدور حول عناصر قوائم +:ثم تطبع + dog is a mammal + cat is a mammal + mouse is a mammal +""" +for animal in ["dog", "cat", "mouse"]: + # يمكنك استخدام format() لترجمة كلمات بشكل معين. + print("{} is a mammal".format(animal)) + +""" +"range(number)" يقوم بإعادة مجموعة من الأرقام يمكن الدوران حولها +من الصفر إلي رقم معين +ثم يطبع: + 0 + 1 + 2 + 3 +""" + +for i in range(4): + print(i) + +""" +"range(lower, upper)" يقوم بإعادة مجموعة من الأرقام يمكن الدوران حولها من القيمة السُفلى +lower حتى القيمة العُليا upper +ثم يطبع: + 4 + 5 + 6 + 7 +""" +for i in range(4, 8): + print(i) + +""" +"range(lower, upper, step)" يقوم بإعادة مجموعة من الأرقام يمكن الدوران حولها من القيمة السُفلى +lower حتى القيمة العُليا upper، ثم يقوم بالزيادة قيمة الstep. +إذا لم تُحدد ال step, القيمة الأفتراضية 1. +ثم يطبع: + 4 + 6 +""" +for i in range(4, 8, 2): + print(i) + +""" +While هي عبارة عن حلقات تدور حتى عدم تحقق شرط معين. +وتطبع: + 0 + 1 + 2 + 3 +""" +x = 0 for +while x < 4: + print(x) + x += 1 # اختصار ل x = x + 1 + +# يمكنك التحكم في الأخطاء والاستثناءات باستخدام مجموعة try/except +try: + # استخدم "raise" لرفع خطأ. + raise IndexError("This is an index error") +except IndexError as e: + pass # Pass: هو مجرد أمر ﻻ تفعل شيء. عادة تقوم بتصحيح الخطأ هنا. +except (TypeError, NameError): + pass # يمكنك التحكم في أكثر من خطأ في نفس الوقت، إذا أقتضت الضرورة +else: # فقرة اختيارية في مجموعة try/except. يجب أن يتبع جميع مجموعات معارضة الأخطاء + print("All good!") # تُنفذ في حالة أن السطور البرمجية داخل ال try لم ترفع أي خطأ +finally: # تُنفذ في كل الحالات + print("We can clean up resources here") + +# بدلا من مجموعة try/finally لتنظيف الموارد يمكنك استخدام سطر with +with open("myfile.txt") as f: + for line in f: + print(line) + +# يتيح البايثون تجريد أساسي يسمى المُكرَر. +# المُكرٍَر عبارة عن متغير يمكن التعامل معه كسلسلة. +# الكائن الذي يعود من دالة نطاق، يسمى المُكرَر. + +filled_dict = {"one": 1, "two": 2, "three": 3} +our_iterable = filled_dict.keys() +print(our_iterable) # => dict_keys(['one', 'two', 'three']) +# هذا عبارة عن متغير يعرض عناصر مفاتيح المُكرَر. + +# يمكننا الدوران حوله. +for i in our_iterable: + print(i) # Prints one, two, three + +# مع ذلك ﻻ يمكننا الوصول للعناصر بالمؤشر. +our_iterable[1] # يرفع خطأ TypeError + +# المُكرَر هو عبارة عن عنصر يعلم كيفية إنشاء مُكرِر +our_iterator = iter(our_iterable) + +# المُكرِر هو عبارة عن عنصر يمكنه تذكر الحالة أثناء مرورنا بعناصره. +# يمكننا الحصول على العنصر التالي عن طريق "next()" +next(our_iterator) # => "one" + +# يحفظ الحالة أثناء الدوران. +next(our_iterator) # => "two" +next(our_iterator) # => "three" + +# بعد عرض المُكرِر كل عناصره، يرفع استثناء StopIteration +next(our_iterator) # يرفع StopIteration + +# يمكنك الحصول على كل عناصر المُكرر بمناداة دالة list() عليه. +list(filled_dict.keys()) # => Returns ["one", "two", "three"] + + +#################################################### +## 4. الدوال +#################################################### + +# إستخدم "def" لإنشاء دوال جديدة. +def add(x, y): + print("x is {} and y is {}".format(x, y)) + return x + y # يمكنك إرجاع قيمة من الدالة بسطر return + +# مناداة دوال بمعطيات +add(5, 6) # => prints out "x is 5 and y is 6" and returns 11 + +# طريقة أخرى لمناداة دوال باستخدام كلمات مفتاحية. +add(y=6, x=5) # الكلمة المفتاحية يمكن أن تُعطى بأي ترتيب. + +# يمكنك تعريف دوال تأخذ عدد متغير من المُعطيات + +def varargs(*args): + return args + +varargs(1, 2, 3) # => (1, 2, 3) + +# يمكنك تعريف دوال تأخذ عدد متغير من الكلمات المفتاحية كمعطيات أيضا. +def keyword_args(**kwargs): + return kwargs + +# هيا ننادي على الدالة لنرى ماذا سيحدث +keyword_args(big="foot", loch="ness") # => {"big": "foot", "loch": "ness"} + + +# يمكنك فعل الأثنين معًا في نفس الوقت، إذا أردت +def all_the_args(*args, **kwargs): + print(args) + print(kwargs) +""" +all_the_args(1, 2, a=3, b=4) prints: + (1, 2) + {"a": 3, "b": 4} +""" + +# عندما تنادي على دوال، يمكنك عمل عكس المعطيات/المفاتيح! +# استخدم * لتوسعة الصفوف، واستخدم ** لتوسعة المفاتيح. +args = (1, 2, 3, 4) +kwargs = {"a": 3, "b": 4} +all_the_args(*args) # مساوٍ ل all_the_args(1, 2, 3, 4) +all_the_args(**kwargs) # مساوٍ ل to all_the_args(a=3, b=4) +all_the_args(*args, **kwargs) # مساوٍ ل to all_the_args(1, 2, 3, 4, a=3, b=4) + +# يقوم بإعادة مجموعة من القيم (بتعيين الصفوف) +def swap(x, y): + return y, x # يقوم بإعادة مجموعة من القيم على شكل صفوف بدون الأقواس + # (لاحظ: الأقواس حُذفت لكن يمكن إضافتها) + +x = 1 +y = 2 +x, y = swap(x, y) # => x = 2, y = 1 +# (x, y) = swap(x,y) # مرة أخرى الأقواس حُذفت لكن يمكن إضافتها. + +# مجال الدالة +x = 5 + +def set_x(num): + # المتغير المحلي x ليس هو المتغير العام x + x = num # => 43 + print(x) # => 43 + +def set_global_x(num): + global x + print(x) # => 5 + x = num #المتغير العام x الأن مساوٍ ل 6 + print(x) # => 6 + +set_x(43) +set_global_x(6) + + +# بايثون تدعم دوال الفئة أولية [first class functions] (أي أنه يمكن إرسال الدوال كمعطيات لدوال أخرى) +def create_adder(x): + def adder(y): + return x + y + return adder + +add_10 = create_adder(10) +add_10(3) # => 13 + +# يوجد أيضا دوال مجهولة +(lambda x: x > 2)(3) # => True +(lambda x, y: x ** 2 + y ** 2)(2, 1) # => 5 + +# يوجد دوال مدمجة من درجة أعلى +list(map(add_10, [1, 2, 3])) # => [11, 12, 13] +list(map(max, [1, 2, 3], [4, 2, 1])) # => [4, 2, 3] + +list(filter(lambda x: x > 5, [3, 4, 5, 6, 7])) # => [6, 7] + +# يمكن إشتمال القوائم على خرائط وفلاتر حسنة الشكل +# هذه القوائم تحفظ المُخرج كقائمة والتي بدورها يمكن أن تكون قائمة مداخلة +[add_10(i) for i in [1, 2, 3]] # => [11, 12, 13] +[x for x in [3, 4, 5, 6, 7] if x > 5] # => [6, 7] + +# يمكنك بناء مجموعات وقواميس على هذا المنوال أيضا +{x for x in 'abcddeef' if x not in 'abc'} # => {'d', 'e', 'f'} +{x: x**2 for x in range(5)} # => {0: 0, 1: 1, 2: 4, 3: 9, 4: 16} + + +#################################################### +## 5. الوحدات البرمجية (الموديولات) +#################################################### + +# يمكنك استدعاء موديولات +import math +print(math.sqrt(16)) # => 4.0 + +# يمكنك استدعاء دالة معينة من موديول +from math import ceil, floor +print(ceil(3.7)) # => 4.0 +print(floor(3.7)) # => 3.0 + +# يمكنك استدعاء كل الدوال من مديول. +# تحذير: هذا الفعل غير موصى به +from math import * + +# يمكنك تصغير اسم موديول +import math as m +math.sqrt(16) == m.sqrt(16) # => True + +# موديولات البايثون عبارة عن ملفات بايثون عادية. +# يمكنك كتابة الموديولات الخاصة بك, واستدعاها. +# اسم الموديول يكون نفس اسم الملف. + +# يمكنك معرفة أي الدوال والصفات مُعرفة في الموديول. +import math +dir(math) + +# إذا كان لديك سكربت بايثون يسمى math.py +# في نفس المجلد الموجود به السكربت الخاص بك، الملف الخاص بك math.py +# سَيُستدعى بدلا من موديول البايثون بنفس الاسم +# هذا يحدث لأن المجلدات المحلية لديها أولوية عن مكتبات البايثون المُدمجة + + +#################################################### +## 6. الفئات/القوالب (الكلاسات) +#################################################### + +# نستخدم السطر البرمجي "class" لإنشاء قالب +class Human: + + # صفة القالب. مشتركة بين كل نسخ القالب + species = "H. sapiens" + + # مُهيئ إبتدائي، يُنادى عليه عندما يتم استدعاء القالب. + # لاحظ أن الشرطة السٌفلية المُكررة مرتين __ قبل وبعد الاسم تُعبر عن الكائنات + # أو الصفات المُستخدمة عن طريق بايثون لكنها تعيش في مساحة تحكم المُستخدم. + # العمليات -الدوال- (أو الكائنات أو الصفات) مثل: __init__, __str__,__repr__ ألخ. + # تُسمى عمليات خاصة (أو أحيانا تسمى عمليات سحرية أو dunder methods) + # يجب عليك ألا تُسمي مثل هذه الاسماء بنفسك. + def __init__(self, name): + # ساوِ المُعطى بالصفة name الخاصة بهذه النسخة من القالب. + self.name = name + + # هيئ الصفة + self._age = 0 + + # عملية/دالة خاصة بنسخة القالب. كل العمليات تأخذ "self" كأول مُعطى + # An instance method. All methods take "self" as the first argument + def say(self, msg): + print("{name}: {message}".format(name=self.name, message=msg)) + + # عملية أخرى خاصة بنسخة القالب. + def sing(self): + return 'yo... yo... microphone check... one two... one two...' + + # عمليات القالب مشتركة بين كل أجزاء القالب + # يتم مناداتهم عن طريق جعل القالب المُنادي أول معطى + # They are called with the calling class as the first argument + @classmethod + def get_species(cls): + return cls.species + + # تُنادى العملية الثابتة بدون قالب أو نسخة قالب + @staticmethod + def grunt(): + return "*grunt*" + + # الخاصية تشبه تماما إمر الطلب + # تُحَوِل العملية age() إلي صفة مقروءة فقط بنفس الاسم. + # ﻻ حاجة لكتابة أوامر طلب أو تهيئة + @property + def age(self): + return self._age + + # هذا يتيح تهيئة الخاصية + @age.setter + def age(self, age): + self._age = age + + # هذا يتيح حذف الخاصية + @age.deleter + def age(self): + del self._age + + +# عندما يقرأ مُترجم البايثون ملف مصدري يقوم بتنفيذ كل الكود. +# فحص ال __name__ يجعل هذا الجزء من الكود يُنَفَذ فقط +# في حالة أن هذا الموديول هو البرنامج الرئيسي +if __name__ == '__main__': + # Instantiate a class + i = Human(name="Ian") + i.say("hi") # "Ian: hi" + j = Human("Joel") + j.say("hello") # "Joel: hello" + # i و j نُسخ من النوع Human, أول بكلمات أخرى: هما كائنات للقالب Human + + # نادي على عملية القالب + i.say(i.get_species()) # "Ian: H. sapiens" + # عدل الخاصية المُشتركة + Human.species = "H. neanderthalensis" + i.say(i.get_species()) # => "Ian: H. neanderthalensis" + j.say(j.get_species()) # => "Joel: H. neanderthalensis" + + # نادي على العملية الثابتة + print(Human.grunt()) # => "*grunt*" + + # لا يمكن مناداة العملية الثابتة من نسخة الكائن + # لأن i.grunt() سيقوم تلقائيا بوضع "self" (الكائن i) كمُعطى للعملية + print(i.grunt()) # => TypeError: grunt() takes 0 positional arguments but 1 was given + + # حدًث الخاصية لهذه النسخة + i.age = 42 + # أحصل على الخاصية + i.say(i.age) # => "Ian: 42" + j.say(j.age) # => "Joel: 0" + # إحذف الخاصية + del i.age + # i.age # => سوف يرفع استثناء AttributeError + + +#################################################### +## 6.1 الإرث +#################################################### + +# الإرث يتيح لقالب ابن أن يُعَرف ويرث بعض عمليات/دوال ومتغيرات القالب الأب. + +# باستخدام القالب Human المُعَرف بالأعلى كأساس أو كقالب أب، +# يمكننا تعريف قالب ابن،Superhero ، يرث متغيرات القالب مثل "species", "name", و "age"، +# وأيضا العمليات، مثل "sing", "grunt" +# من القالب Human، لكنه أيضا لديه خواصه الفريدة + +# للاستفادة من التقطيع بالملف يمكنك وضع القوالب بالأعلى في ملفاتهم الخاصة، +# مثلا، human.py + +# لاستيراد دالة من ملف أخر استخدم الطريقة التالية +# from "اسم الملف بدون مُلحق" import "اسم الدالة أو القالب" + +from human import Human + +# حدد القالب/ات الأب كمُعطى أثناء تعريف القالب. +class Superhero(Human): + + # إذا أردت أن يرث القالب الابن كل تعريفات القالب الأب بدون تعديل + # يمكنك استخدام الكلمة المفتاحية "pass" (بدون شيء أخر) + # لكن في هذه الحالة تم أهمالها لإنشاء قالب ابن فريد: + # pass + + # القوالب الابن يمكنها تعديل صفات القوالب الأب + species = 'Superhuman' + + # القوالب الابن ترث تلقائيا عمليات الإنشاء الخاصة بالقالب الأب بالإضافة إلي مُعطياتهم + # لكن يمكن أيضا تعريف مُعطيات إضافية أو تعريفات + # وتعديل العمليات مثل منشيء القالب. + # هذا المُنشيء يرث المُعطى "name" من القالب "Human" + # ويضيف المعطيات"superpower" و "movies": + def __init__(self, name, movie=False, + superpowers=["super strength", "bulletproofing"]): + + # إضافة صفة جديدة للقالب + self.fictional = True + self.movie = movie + # كن على علم بالقيم الافتراضية المتغيرة، حيث أن القيم الافتراضية تُشارك + self.superpowers = superpowers + + # الدالة "super" تتيح لك الوصول لعمليات القالب الأب + # التي تم تغييرها عن طريق الابن، في هذه الحالة، العملية __init__< + # هذا السطر يُنادي على منشيء القالب الأب. + super().__init__(name) + + # تعديل العملية sing + def sing(self): + return 'Dun, dun, DUN!' + + # إضافة عملية جديدة للنسخة + def boast(self): + for power in self.superpowers: + print("I wield the power of {pow}!".format(pow=power)) + + +if __name__ == '__main__': + sup = Superhero(name="Tick") + + # فحص نوع النسخة + if isinstance(sup, Human): + print('I am human') + if type(sup) is Superhero: + print('I am a superhero') + + # إحصل على ترتيب قرار البحث للعملية (Method Resolution search Order) المُستخدمة بواسطة العمليات getattr() و super() + # هذه الصفة ديناميكية ويمكن أن تُحَدًث. + print(Superhero.__mro__) # => (<class '__main__.Superhero'>, + # => <class 'human.Human'>, <class 'object'>) + + # نادي العملية الأب لكن استخدم صفات القالب الخاص بها. + print(sup.get_species()) # => Superhuman + + # نادي العملية المُعدلة. + print(sup.sing()) # => Dun, dun, DUN! + + # نادي العملية من القالب Human + sup.say('Spoon') # => Tick: Spoon + + # نادي عملية موجودة فقط في Superhero + sup.boast() # => I wield the power of super strength! + # => I wield the power of bulletproofing! + + # وَرَثَ صفات القالب + sup.age = 31 + print(sup.age) # => 31 + + # صفة موجودة فقط في القالب Superhero + print('Am I Oscar eligible? ' + str(sup.movie)) + +#################################################### +## 6.2 الإرث المُتعدد +#################################################### + +# تعريف قالب أخرA +# bat.py +class Bat: + + species = 'Baty' + + def __init__(self, can_fly=True): + self.fly = can_fly + + # هذا القالب لديه عملية تسمى say + def say(self, msg): + msg = '... ... ...' + return msg + + # ولديه عمليته الخاصة به أيضا + def sonar(self): + return '))) ... (((' + +if __name__ == '__main__': + b = Bat() + print(b.say('hello')) + print(b.fly) + +# تعريف قالب أخر يرث من Superhero و Bat +# superhero.py +from superhero import Superhero +from bat import Bat + +# عَرٍف Batman كقالب ابن يرث من كلا من Superhero و Bat +class Batman(Superhero, Bat): + + def __init__(self, *args, **kwargs): + # عادة لكي ترث صفة يجد أن تنادي على super: + # super(Batman, self).__init__(*args, **kwargs) + # لكننا في هذه الحالة نتعامل مع إرث متعدد هنا، و super() + # تعمل فقط مع القالب التالي في قائمة ال MRO. + # لذا بدلا من ذلك ننادي على __init__ صراحة لكل الأباء. + # استخدام *args و **kwargs يتيح طريقة نظيفة لتمرير المعطيات. + # لكل أب "تقشير طبقة من البصل". + Superhero.__init__(self, 'anonymous', movie=True, + superpowers=['Wealthy'], *args, **kwargs) + Bat.__init__(self, *args, can_fly=False, **kwargs) + # تعديل قيمة الصفة name + self.name = 'Sad Affleck' + + def sing(self): + return 'nan nan nan nan nan batman!' + + +if __name__ == '__main__': + sup = Batman() + + # إحصل على ترتيب قرار البحث للعملية (Method Resolution search Order) المُستخدمة بواسطة العمليات getattr() و super() + # هذه الصفة ديناميكية ويمكن أن تُحَدًث. + print(Batman.__mro__) # => (<class '__main__.Batman'>, + # => <class 'superhero.Superhero'>, + # => <class 'human.Human'>, + # => <class 'bat.Bat'>, <class 'object'>) + + # نادي على العملية الخاصة بالأب لكن استخدم الصفات الخاصة بالقالب الابن + print(sup.get_species()) # => Superhuman + + # نادي على العملية المُعدلة + print(sup.sing()) # => nan nan nan nan nan batman! + + # نادي على العملية من القالب Human, لأن الترتيب في الأرث مهم. + sup.say('I agree') # => Sad Affleck: I agree + + # نادي على العملية الموجودة فقط في القالب الأب الثاني + print(sup.sonar()) # => ))) ... ((( + + # الصفة الموروثة من القالب الأب + sup.age = 100 + print(sup.age) # => 100 + + # الصفة الموروثة من القالب الأب الثاني، الذي تم تعديل قيمته الافتراضية + print('Can I fly? ' + str(sup.fly)) # => Can I fly? False + + + +#################################################### +## 7. مُتَقدم +#################################################### + +# المولدات تُساعدك على كتابة كود كسول. +def double_numbers(iterable): + for i in iterable: + yield i + i + +# المولدات فعالة من حيث الذاكرة، لأنها تُحمٍل الذاكرة بالبيانات التي تحتاج +# لإجراء العملية عليها في الخطوة التالية في المُكَرِر. +# هذا يتيح إجراء عمليات على قيم كبيرة ممنوعة في حالات أخرى. +# ﻻحظ: `range` بديل ل `xrange` في بايثون 3. +for i in double_numbers(range(1, 900000000)): # `range` is a generator. + print(i) + if i >= 30: + break + +# كما يمكنك إنشاء قوائم اشتمال، يمكنك إنشاء مولدات اشتمال أيضا +values = (-x for x in [1,2,3,4,5]) +for x in values: + print(x) # prints -1 -2 -3 -4 -5 to console/terminal + +# يمكنك أيضا تغيير نوع مولد الاشتمال مباشرة إلي قائمة +values = (-x for x in [1,2,3,4,5]) +gen_to_list = list(values) +print(gen_to_list) # => [-1, -2, -3, -4, -5] + + +# المُحسنات +# في هذا المثال الدالة`beg` تُغلف الدالة `say`. +# إذا كانت say_please تساوي True +# إذا ستُغير الرسالة الراجعة من الدالة +from functools import wraps + +def beg(target_function): + @wraps(target_function) + def wrapper(*args, **kwargs): + msg, say_please = target_function(*args, **kwargs) + if say_please: + return "{} {}".format(msg, "Please! I am poor :(") + return msg + + return wrapper + + +@beg +def say(say_please=False): + msg = "Can you buy me a beer?" + return msg, say_please + + +print(say()) # Can you buy me a beer? +print(say(say_please=True)) # Can you buy me a beer? Please! I am poor :( +``` + +## جاهز للمزيد? + +### مجانا عبر الانترنت + +* [أتمتتة المهمات المُملة عبر بايثون](https://automatetheboringstuff.com) +* [أفكار لمشروعات بلغة البايثون](http://pythonpracticeprojects.com) +* [التوثيقات الرسمية](http://docs.python.org/3/) +* [دليل المُسافر لبايثون](http://docs.python-guide.org/en/latest/) +* [دورة بايثون](http://www.python-course.eu/index.php) +* [أولى الخطوات مع بايثون](https://realpython.com/learn/python-first-steps/) +* [قائمة مُختارة من إطارات عمل بايثون الرائعة, المكتبات والبرمجيات](https://github.com/vinta/awesome-python) +* [ثلاثون خاصية وخدعة للغة البايثون ربما لم تعرف بها](http://sahandsaba.com/thirty-python-language-features-and-tricks-you-may-not-know.html) +* [الدليل الرسمي لنمط البايثون](https://www.python.org/dev/peps/pep-0008/) +* [بايثون 3 دوائر علوم الحاسب](http://cscircles.cemc.uwaterloo.ca/) +* [غُص في بايثون 3](http://www.diveintopython3.net/index.html) +* [دورة سريعة في البايثون للعلماء](http://nbviewer.jupyter.org/gist/anonymous/5924718) diff --git a/asymptotic-notation.html.markdown b/asymptotic-notation.html.markdown index a1dfe9e1..7a7989d3 100644 --- a/asymptotic-notation.html.markdown +++ b/asymptotic-notation.html.markdown @@ -110,7 +110,7 @@ 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>? +Is there some pair of constants c, n<sub>0</sub> that satisfies this for all n > n<sub>0</sub>? ``` 3log n + 100 <= 150 * log n, n > 2 (undefined at n = 1) diff --git a/awk.html.markdown b/awk.html.markdown index 3d2c4ccb..3ff3f937 100644 --- a/awk.html.markdown +++ b/awk.html.markdown @@ -1,5 +1,6 @@ --- -language: awk +category: tool +tool: awk filename: learnawk.awk contributors: - ["Marshall Mason", "http://github.com/marshallmason"] @@ -10,7 +11,7 @@ AWK is a standard tool on every POSIX-compliant UNIX system. It's like flex/lex, from the command-line, perfect for text-processing tasks and other scripting needs. It has a C-like syntax, but without mandatory semicolons (although, you should use them anyway, because they are required -when you're writing one-liners, something AWK excells at), manual memory +when you're writing one-liners, something AWK excels at), 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. @@ -32,7 +33,7 @@ pattern2 { action; } # There is an implied loop and AWK automatically reads and parses each # record of each file supplied. Each record is split by the FS delimiter, # which defaults to white-space (multiple spaces,tabs count as one) -# You cann assign FS either on the command line (-F C) or in your BEGIN +# You can assign FS either on the command line (-F C) or in your BEGIN # pattern # One of the special patterns is BEGIN. The BEGIN pattern is true @@ -238,7 +239,7 @@ function io_functions( localvar) { # 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, but to get the same output, the string - # must match exactly, so use a vaiable: + # must match exactly, so use a variable: outfile = "/tmp/foobar.txt"; @@ -381,3 +382,5 @@ Further Reading: * [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. * [AWK one-liner collection](http://tuxgraphics.org/~guido/scripts/awk-one-liner.html) +* [Awk alpinelinux wiki](https://wiki.alpinelinux.org/wiki/Awk) a technical summary and list of "gotchas" (places where different implementations may behave in different or unexpected ways). +* [basic libraries for awk](https://github.com/dubiousjim/awkenough) diff --git a/bash.html.markdown b/bash.html.markdown index 8c40931e..0385c46d 100644 --- a/bash.html.markdown +++ b/bash.html.markdown @@ -20,21 +20,23 @@ contributors: 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. +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 #!/usr/bin/env bash -# First line of the script is shebang which tells the system how to execute +# First line of the script is the 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! # => Hello world! -# Each command starts on a new line, or after semicolon: +# Each command starts on a new line, or after a semicolon: echo 'This is the first line'; echo 'This is the second line' # => This is the first line # => This is the second line @@ -47,7 +49,7 @@ Variable = "Some string" # => returns error "Variable: command not found" # Bash will decide that Variable is a command it must execute and give an error # because it can't be found. -# Or like this: +# Nor like this: Variable= 'Some string' # => returns error: "Some string: command not found" # 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 @@ -65,8 +67,9 @@ echo '$Variable' # => $Variable # Parameter expansion ${ }: echo ${Variable} # => Some string # 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 +# Parameter Expansion gets a value from a variable. +# It "expands" or prints the value +# During the expansion time the value or parameter can be modified # Below are other modifications that add onto this expansion # String substitution in variables @@ -114,8 +117,8 @@ echo {1..10} # => 1 2 3 4 5 6 7 8 9 10 echo {a..z} # => a b c d e f g h i j k l m n o p q r s t u v w x y z # This will output the range from the start value to the end value -# Builtin variables: -# There are some useful builtin variables, like +# Built-in variables: +# There are some useful built-in variables, like echo "Last program's return value: $?" echo "Script's PID: $$" echo "Number of arguments passed to script: $#" @@ -127,7 +130,7 @@ echo "Script's arguments separated into different variables: $1 $2..." # Our current directory is available through the command `pwd`. # `pwd` stands for "print working directory". -# We can also use the builtin variable `$PWD`. +# We can also use the built-in 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 @@ -143,7 +146,7 @@ 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 +# use `man test` for more info about conditionals if [ $Name != $USER ] then echo "Your name isn't your username" @@ -180,7 +183,7 @@ then echo "This will run if $Name is Daniya OR Zach." fi -# There is also the =~ operator, which tests a string against a Regex pattern: +# There is also the `=~` operator, which tests a string against a Regex pattern: Email=me@example.com if [[ "$Email" =~ [a-z]+@[a-z]{2,}\.(com|net|org) ]] then @@ -190,9 +193,9 @@ fi # which are subtly different from single [ ]. # See http://www.gnu.org/software/bash/manual/bashref.html#Conditional-Constructs for more on this. -# Redefine command 'ping' as alias to send only 5 packets +# Redefine command `ping` as alias to send only 5 packets alias ping='ping -c 5' -# Escape alias and use command with this name instead +# Escape the alias and use command with this name instead \ping 192.168.1.1 # Print all aliases alias -p @@ -205,14 +208,14 @@ echo $(( 10 + 5 )) # => 15 # directory with the ls command: ls # Lists the files and subdirectories contained in the current directory -# These commands have options that control their execution: +# This command has options that control its 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: +# The `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: @@ -280,10 +283,17 @@ EOF # Run the hello.py Python script with various stdin, stdout, and # stderr redirections: python hello.py < "input.in" # pass input.in as input to the script + python hello.py > "output.out" # redirect output from the script to output.out + python hello.py 2> "error.err" # redirect error output to error.err -python hello.py > "output-and-error.log" 2>&1 # redirect both output and errors to output-and-error.log -python hello.py > /dev/null 2>&1 # redirect all output and errors to the black hole, /dev/null, i.e., no output + +python hello.py > "output-and-error.log" 2>&1 +# redirect both output and errors to output-and-error.log + +python hello.py > /dev/null 2>&1 +# redirect all output and errors to the black hole, /dev/null, i.e., no output + # 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" @@ -312,11 +322,11 @@ rm -r tempDir/ # recursively delete # 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 $( ). +# 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++: +# 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.";; @@ -324,7 +334,7 @@ case "$Variable" in *) echo "It is not null.";; esac -# for loops iterate for as many arguments given: +# `for` loops iterate for as many arguments given: # The contents of $Variable is printed three times. for Variable in {1..3} do @@ -345,14 +355,14 @@ done # => 3 # They can also be used to act on files.. -# This will run the command 'cat' on file1 and file2 +# 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. +# This will `cat` the output from `ls`. for Output in $(ls) do cat "$Output" @@ -432,8 +442,8 @@ grep "^foo.*bar$" file.txt | grep -v "baz" # and not the regex, use fgrep (or grep -F) fgrep "foobar" file.txt -# The trap command allows you to execute a command whenever your script -# receives a signal. Here, trap will execute `rm` if it receives any of the +# The `trap` command allows you to execute a command whenever your script +# receives a signal. Here, `trap` will execute `rm` if it receives any of the # three listed signals. trap "rm $TEMP_FILE; exit" SIGHUP SIGINT SIGTERM @@ -442,7 +452,7 @@ NAME1=$(whoami) NAME2=$(sudo whoami) echo "Was $NAME1, then became more powerful $NAME2" -# Read Bash shell builtins documentation with the bash 'help' builtin: +# Read Bash shell built-ins documentation with the bash `help` built-in: help help help help for @@ -450,12 +460,12 @@ help return help source help . -# Read Bash manpage documentation with man +# Read Bash manpage documentation with `man` apropos bash man 1 bash man bash -# Read info documentation with info (? for help) +# Read info documentation with `info` (`?` for help) apropos info | grep '^info.*(' man info info info diff --git a/c++.html.markdown b/c++.html.markdown index 4113d5f4..80ad3a6c 100644 --- a/c++.html.markdown +++ b/c++.html.markdown @@ -78,7 +78,7 @@ int* ip = nullptr; // The C++ standard version: #include <cstdio> -//The C standard version: +// The C standard version: #include <stdio.h> int main() @@ -257,7 +257,7 @@ 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. +// 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. @@ -657,7 +657,7 @@ printMessage<10>(); // Prints "Learn C++ faster in only 10 minutes!" // 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 +// but any type can be thrown as an exception #include <exception> #include <stdexcept> @@ -809,7 +809,103 @@ void doSomethingWithAFile(const std::string& filename) // 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 + +///////////////////// +// 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> +string val; +vector<string> my_vector; // initialize the vector +cin >> val; +my_vector.push_back(val); // will push the value of 'val' into vector ("array") my_vector +my_vector.push_back(val); // will push the value into the vector again (now having two elements) + +// To iterate through a vector we have 2 choices: +// Either classic looping (iterating through the vector from index 0 to its last index): +for (int i = 0; i < my_vector.size(); i++) { + cout << my_vector[i] << endl; // for accessing a vector's element we can use the operator [] +} + +// or using an iterator: +vector<string>::iterator it; // initialize the iterator for vector +for (it = my_vector.begin(); it != my_vector.end(); ++it) { + cout << *it << endl; +} + +// 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 +// NOTE: For hash sets, use unordered_set. They are more efficient but +// do not preserve order. unordered_set is available since C++11 + +// 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 + +// NOTE: For hash maps, use unordered_map. They are more efficient but do +// not preserve order. unordered_map is available since C++11. + +// 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 { @@ -822,12 +918,13 @@ struct compareFunction { return a.j < b.j; } }; -//this isn't allowed (although it can vary depending on compiler) -//std::map<Foo, int> fooMap; +// 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) /////////////////////////////////////// @@ -994,101 +1091,6 @@ 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> -string val; -vector<string> my_vector; // initialize the vector -cin >> val; -my_vector.push_back(val); // will push the value of 'val' into vector ("array") my_vector -my_vector.push_back(val); // will push the value into the vector again (now having two elements) - -// To iterate through a vector we have 2 choices: -// Either classic looping (iterating through the vector from index 0 to its last index): -for (int i = 0; i < my_vector.size(); i++) { - cout << my_vector[i] << endl; // for accessing a vector's element we can use the operator [] -} - -// or using an iterator: -vector<string>::iterator it; // initialize the iterator for vector -for (it = my_vector.begin(); it != my_vector.end(); ++it) { - cout << *it << endl; -} - -// 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 -// NOTE: For hash sets, use unordered_set. They are more efficient but -// do not preserve order. unordered_set is available since C++11 - -// 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 - -// NOTE: For hash maps, use unordered_map. They are more efficient but do -// not preserve order. unordered_map is available since C++11. - /////////////////////////////////// // Logical and Bitwise operators ////////////////////////////////// diff --git a/chapel.html.markdown b/chapel.html.markdown index 354cd832..7e8fc41a 100644 --- a/chapel.html.markdown +++ b/chapel.html.markdown @@ -708,7 +708,7 @@ class MyClass { // We also get the compiler-generated initializer, with one argument per field. // Note that soon there will be no compiler-generated initializer when we // define any initializer(s) explicitly. - proc MyClass(val : real) { + proc init(val : real) { this.memberInt = ceil(val): int; } diff --git a/cmake.html.markdown b/cmake.html.markdown index c705beea..32a7b758 100644 --- a/cmake.html.markdown +++ b/cmake.html.markdown @@ -1,5 +1,6 @@ --- -language: cmake +category: tool +tool: cmake contributors: - ["Bruno Alano", "https://github.com/brunoalano"] filename: CMake diff --git a/crystal.html.markdown b/crystal.html.markdown index 8210b443..9fae9da3 100644 --- a/crystal.html.markdown +++ b/crystal.html.markdown @@ -25,17 +25,19 @@ true.class #=> Bool 1.class #=> Int32 -# Four signed integer types -1_i8.class #=> Int8 -1_i16.class #=> Int16 -1_i32.class #=> Int32 -1_i64.class #=> Int64 - -# Four unsigned integer types -1_u8.class #=> UInt8 -1_u16.class #=> UInt16 -1_u32.class #=> UInt32 -1_u64.class #=> UInt64 +# Five signed integer types +1_i8.class #=> Int8 +1_i16.class #=> Int16 +1_i32.class #=> Int32 +1_i64.class #=> Int64 +1_i128.class #=> Int128 + +# Five unsigned integer types +1_u8.class #=> UInt8 +1_u16.class #=> UInt16 +1_u32.class #=> UInt32 +1_u64.class #=> UInt64 +1_u128.class #=> UInt128 2147483648.class #=> Int64 9223372036854775808.class #=> UInt64 diff --git a/cs-cz/python3.html.markdown b/cs-cz/python3.html.markdown index dbaae88b..2cbf52e6 100644 --- a/cs-cz/python3.html.markdown +++ b/cs-cz/python3.html.markdown @@ -572,7 +572,7 @@ Clovek.odkaslej_si() # => "*ehm*" # Lze importovat moduly import math -print(math.sqrt(16.0)) # => 4 +print(math.sqrt(16.0)) # => 4.0 # Lze také importovat pouze vybrané funkce z modulu from math import ceil, floor diff --git a/csharp.html.markdown b/csharp.html.markdown index f27adf18..df6544d3 100644 --- a/csharp.html.markdown +++ b/csharp.html.markdown @@ -344,7 +344,7 @@ on a new line! ""Wow!"", the masses cried"; tryInt.ToString(); // Casting - // Cast decimal 15 to a int + // Cast decimal 15 to an int // and then implicitly cast to long long x = (int) 15M; } diff --git a/cypher.html.markdown b/cypher.html.markdown index acd44733..32868354 100644 --- a/cypher.html.markdown +++ b/cypher.html.markdown @@ -50,7 +50,7 @@ Relationships (or Edges) **Connects two nodes** `[:KNOWS]` -It's a *relationship* with the *label* **KNOWS**. It's a *label* as the node's label. It begins with uppercase and use UPPER_SNAKE_CASE. +It's a *relationship* with the *label* **KNOWS**. It's a *label* as the node's label. It begins with uppercase and use UPPER\_SNAKE\_CASE. `[k:KNOWS]` The same *relationship*, referred by the variable **k**, reusable in the query, but it's not necessary. diff --git a/dart.html.markdown b/dart.html.markdown index e12a4ed5..07f755f7 100644 --- a/dart.html.markdown +++ b/dart.html.markdown @@ -25,42 +25,42 @@ import "dart:math" as DM; // The fat arrow function declaration has an implicit return for the result of // the expression. example1() { - example1nested1() { - example1nested2() => print("Example1 nested 1 nested 2"); - example1nested2(); + nested1() { + nested2() => print("Example1 nested 1 nested 2"); + nested2(); } - example1nested1(); + nested1(); } // Anonymous functions don't include a name. example2() { - example2nested1(fn) { + nested1(fn) { fn(); } - example2nested1(() => print("Example2 nested 1")); + nested1(() => print("Example2 nested 1")); } // When a function parameter is declared, the declaration can include the // number of parameters the function takes by specifying the names of the // parameters it takes. example3() { - example3nested1(fn(informSomething)) { - fn("Example3 nested 1"); + planA(fn(informSomething)) { + fn("Example3 plan A"); } - example3planB(fn) { // Or don't declare number of parameters. + planB(fn) { // Or don't declare number of parameters. fn("Example3 plan B"); } - example3nested1((s) => print(s)); - example3planB((s) => print(s)); + planA((s) => print(s)); + planB((s) => print(s)); } // Functions have closure access to outer variables. var example4Something = "Example4 nested 1"; example4() { - example4nested1(fn(informSomething)) { + nested1(fn(informSomething)) { fn(example4Something); } - example4nested1((s) => print(s)); + nested1((s) => print(s)); } // Class declaration with a sayIt method, which also has closure access @@ -81,9 +81,9 @@ example5() { // Where classBody can include instance methods and variables, but also // class methods and variables. class Example6Class { - var example6InstanceVariable = "Example6 instance variable"; + var instanceVariable = "Example6 instance variable"; sayIt() { - print(example6InstanceVariable); + print(instanceVariable); } } example6() { @@ -92,12 +92,12 @@ example6() { // Class methods and variables are declared with "static" terms. class Example7Class { - static var example7ClassVariable = "Example7 class variable"; + static var classVariable = "Example7 class variable"; static sayItFromClass() { - print(example7ClassVariable); + print(classVariable); } sayItFromInstance() { - print(example7ClassVariable); + print(classVariable); } } example7() { @@ -110,40 +110,40 @@ example7() { // or outside of class have to be constant. Strings and numbers are constant // by default. But arrays and maps are not. They can be made constant by // declaring them "const". -var example8A = const ["Example8 const array"], - example8M = const {"someKey": "Example8 const map"}; +var example8Array = const ["Example8 const array"], + example8Map = const {"someKey": "Example8 const map"}; example8() { - print(example8A[0]); - print(example8M["someKey"]); + print(example8Array[0]); + print(example8Map["someKey"]); } // Loops in Dart take the form of standard for () {} or while () {} loops, // slightly more modern for (.. in ..) {}, or functional callbacks with many // supported features, starting with forEach. -var example9A = const ["a", "b"]; +var example9Array = const ["a", "b"]; example9() { - for (var i = 0; i < example9A.length; i++) { - print("Example9 for loop '${example9A[i]}'"); + for (var i = 0; i < example9Array.length; i++) { + print("Example9 for loop '${example9Array[i]}'"); } var i = 0; - while (i < example9A.length) { - print("Example9 while loop '${example9A[i]}'"); + while (i < example9Array.length) { + print("Example9 while loop '${example9Array[i]}'"); i++; } - for (var e in example9A) { + for (var e in example9Array) { print("Example9 for-in loop '${e}'"); } - example9A.forEach((e) => print("Example9 forEach loop '${e}'")); + example9Array.forEach((e) => print("Example9 forEach loop '${e}'")); } // To loop over the characters of a string or to extract a substring. -var example10S = "ab"; +var example10String = "ab"; example10() { - for (var i = 0; i < example10S.length; i++) { - print("Example10 String character loop '${example10S[i]}'"); + for (var i = 0; i < example10String.length; i++) { + print("Example10 String character loop '${example10String[i]}'"); } - for (var i = 0; i < example10S.length; i++) { - print("Example10 substring loop '${example10S.substring(i, i + 1)}'"); + for (var i = 0; i < example10String.length; i++) { + print("Example10 substring loop '${example10String.substring(i, i + 1)}'"); } } diff --git a/de-de/asciidoc-de.html.markdown b/de-de/asciidoc-de.html.markdown index 24100e0b..e3f64a00 100644 --- a/de-de/asciidoc-de.html.markdown +++ b/de-de/asciidoc-de.html.markdown @@ -88,7 +88,7 @@ Abteilungstitel Listen -Um eine Aufzählung zu erstellen verwendest du Sternchen. +Um eine Aufzählung zu erstellen, verwendest du Sternchen. ``` * foo @@ -96,7 +96,7 @@ Um eine Aufzählung zu erstellen verwendest du Sternchen. * baz ``` -Um eine nummerierte Liste zu erstellen verwendest du Punkte. +Um eine nummerierte Liste zu erstellen, verwendest du Punkte. ``` . item 1 @@ -104,7 +104,7 @@ Um eine nummerierte Liste zu erstellen verwendest du Punkte. . item 3 ``` -Um Listen zu verschachteln musst du zusätzliche Sternchen beziehungsweise Punkte hinzufügen. Dies ist bis zu fünf Mal möglich. +Um Listen zu verschachteln, musst du zusätzliche Sternchen beziehungsweise Punkte hinzufügen. Dies ist bis zu fünf Mal möglich. ``` * foo 1 diff --git a/de-de/c++-de.html.markdown b/de-de/c++-de.html.markdown new file mode 100644 index 00000000..eec11d61 --- /dev/null +++ b/de-de/c++-de.html.markdown @@ -0,0 +1,1161 @@ +--- +language: c++ +filename: learncpp-de.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"] + - ["Maximilian Sonnenburg", "https://github.com/LamdaLamdaLamda"] +lang: de-de +--- + +C++ ist eine Systemprogrammiersprache die, + +[laut dem Begründer Bjarne Stroustrup](http://channel9.msdn.com/Events/Lang-NEXT/Lang-NEXT-2014/Keynote) +entworfen wurde um, + +- "besseres C" zu sein +- Datenabstraktion zu unterstützen +- Objektorientierung zu unterstützen +- generische Programmierung zu unterstützen + +Durch seinen Syntax kann sie durchaus schwieriger und komplexer als neuere Sprachen sein. +Sie ist weit verbeitet, weil sie in Maschinen-Code compiliert, welches direkt vom Prozessor ausgeführt +werden kann und somit eine strikte Kontrolle über die Hardware bietet und gleichzeitig +High-Level-Features wie generics, exceptions und Klassen enthält. (wie C) +Diese Kombination aus Geschwindigkeit und Funktionalität bildet C++ und ist eine der +weitverbreitesten Programmiersprachen. + +```c++ +////////////////// +// Vergleich zu C +////////////////// + +// C++ ist fast eine Untermenge von C and teilt sich grundsätzlich den +// Syntax für Variablen Deklarationen, primitiven Typen und Funktionen. + +// Wie in C ist der Programmeinsprungpunkt eine Funktion, welche "main" genannt wird und +// einen Ineteger als Rückgabetyp besitzt. +// Dieser Wert fungiert als Beendigungsstatus des Programms. +// Siehe: https://de.wikipedia.org/wiki/Return_Code für weitere Informationen +int main(int argc, char** argv) +{ + // Kommandozeilen Argumente werden genauso wie in C über argc und argv übergeben + // argc entspricht der Anzahl von Argumenten und argv ist ein Array von C-style + // strings (char*), welche die Argumente repräsentieren. + // Das erste Argument ist der Name des Programms welches aufgerufen wird. + // Argc und argv können, wenn nicht benötigt, weg gelassen werden, indem + // die Funktionssignatur "int main()" verwendet wird. + + // Ein Rückgabewert von 0 repräsentiert die erfolgreiche Ausführung. + return 0; +} + +// C++ unterscheidet sich in einigen Punkten: + +// In C++ sind Zeichen-Literale chars +sizeof('c') == sizeof(char) == 1 + +// In C sind Zeichen-Literale ints +sizeof('c') == sizeof(int) + +// C++ verwendet striktes prototyping +void func(); // Funktion ohne Argumente + +// In C +void func(); // Funktion mit beliebiger Anzahl von Argumenten + +// Verwende nullptr, anstatt von NULL!!! +int* ip = nullptr; + +// C standard headers sind in C++ verfügbar. +// C header enden mit .h, während +// C++ header das Präfix "c" besitzen und kein ".h" Suffix verwenden. + +// Die C++ Standard Version: +#include <cstdio> + +// Die C Standard Version: +#include <stdio.h> + +int main() +{ + printf("Hello, world!\n"); + return 0; +} + +/////////////////////// +// Funktionsüberladung +/////////////////////// + +// C++ unterstützt Funktionsüberladung +// Jede Funktion kann unterschiedliche Parameter erhalten. +void print(char const* myString) +{ + printf("String %s\n", myString); +} + +void print(int myInt) +{ + printf("My int is %d", myInt); +} + +int main() +{ + print("Hello"); // Wird aufgelöst zu "void print(const char*)" + print(15); // Wird aufgelöst zu "void print(int)" +} + +///////////////////////////// +// Standard Funktionsargumente +///////////////////////////// + +// Argumente können per Standard für eine Funktion gesetzt werden, +// wenn diese beim Aufruf nicht bereitgestellt werden. + +void doSomethingWithInts(int a = 1, int b = 4) +{ + // führe Anweisungen mit "ints" aus. +} + +int main() +{ + doSomethingWithInts(); // a = 1, b = 4 + doSomethingWithInts(20); // a = 20, b = 4 + doSomethingWithInts(20, 5); // a = 20, b = 5 +} + +// Standard-Argumente müssen am Ende der Liste der Argumente stehen. +void invalidDeclaration(int a = 1, int b) // Fehler! +{ +} + + +///////////// +// Namespaces (Namesräume) +///////////// + +// Namespaces stellen einen getrennten Gültigkeitsbereich für Variablen, +// Funktionen und andere Deklarationen zur Verfügung. +// Namespaces können geschachtelt werden. +namespace First +{ + namespace Nested + { + void foo() + { + printf("This is First::Nested::foo\n"); + } + } // Ende des Namespaces "Nested" +} // Ende des Namespaces "First" + +namespace Second +{ + void foo() + { + printf("This is Second::foo\n"); + } +} + +void foo() +{ + printf("This is global foo\n"); +} + +int main() +{ + // Fügt all Symbole aus dem namespace Second in den aktuellen Gültigkeitsbereich (scope). + // "foo()" wird nun nicht länger funktionieren, da es nun doppeldeutig ist, ob foo aus + // dem namespace foo oder darüberliegenden aufgerufen wird. + using namespace Second; + + Second::foo(); // Gibt "This is Second::foo" aus. + First::Nested::foo(); // Gibt "This is First::Nested::foo" aus. + ::foo(); // Gibt "This is global foo" aus. +} + +/////////////// +// Eingabe/Ausgabe +/////////////// + +// C++ verwendet für die Eingabe und Ausgabe streams. +// cin, cout und cerr repräsentieren stdin, stdout und stderr. +// << ist der Einfügeoperator und >> ist der Extraktionsoperator. + +#include <iostream> // Include für Eingabe/Ausgabe (I/O) streams + +using namespace std; // Streams befinden sich im std namespace (standard library) + +int main() +{ + int myInt; + + // Ausgabe auf stdout (oder Terminal/Bildschirm) + cout << "Enter your favorite number:\n"; + + // Empfängt Eingabe + cin >> myInt; + + // cout kann ebenfalls formatiert werden + cout << "Your favorite number is " << myInt << "\n"; + // Gibt "Your favorite number is <myInt>" aus + + cerr << "Used for error messages"; +} + +////////// +// Zeichenketten (Strings) +////////// + +// Strings in C++ sind Objekte und haben diverse member-functions +#include <string> + +using namespace std; // Strings sind ebenfalls im namespace std (Standard Bibliothek) + +string myString = "Hello"; +string myOtherString = " World"; + +// + wird für das Anhängen von strings verwendet. +cout << myString + myOtherString; // "Hello World" + +cout << myString + " You"; // "Hello You" + +// C++ strings sind mutable. +myString.append(" Dog"); +cout << myString; // "Hello Dog" + + +///////////// +// Referenzen +///////////// + +// Zusätzlich zu Pointern, wie jene in C. +// C++ besitzt _Referenzen_. +// Diese sind Pointer-Typen, welche nicht erneut zugewiesen werden können +// und nicht Null sein können. +// Sie besitzen den selben Synthax wie Variablen. +// Für die Dereferenzierung ist kein * notwendig und +// & (die Adresse) wird nicht für die Zuweisung verwendet. + +using namespace std; + +string foo = "I am foo"; +string bar = "I am bar"; + + +string& fooRef = foo; // Erzeugt eine Referenz auf foo. +fooRef += ". Hi!"; // Verändert foo durch die Referenz +cout << fooRef; // Gibt "I am foo. Hi!" aus. + + +// Weist "fooRef" nicht erneut zu. Dies ist dasselbe, wie "foo = bar" und +// foo == "I am bar" +// nach dieser Zeile +cout << &fooRef << endl; // Gibt die Adresse von foo aus +fooRef = bar; +cout << &fooRef << endl; // Gibt ebenfalls die Adresse von foo aus +cout << fooRef; // Gibt "I am bar" aus + +// Die Adresse von fooRef verbleibt die selbe, sie verweist immer noch auf foo + + +const string& barRef = bar; // Erzeugt konstante Referenz auf bar. +// Wie in C, können konstante Werte ( und Pointer bzw. Referenzen) nicht verändert werden. + +barRef += ". Hi!"; // Fehler: konstante Referenzen können nicht verändert werden. + +// Hinweis: bevor wir genauer Referenzen besprechen, schauen wir uns zuerst ein Konzept an +// welches als "temporäres Objekt" bezeichnet wird. Gehen wir von folgenden Code aus: +string tempObjectFun() { ... } +string retVal = tempObjectFun(); + +// Was passiert nun in der zweiten Zeile: +// - ein String Objekt wird von tempObjectFun zurückgegeben +// - ein neuer String wird mit dem zurückgegebenen Objekt als Argument für den Konstruktor erzeugt. +// - das zurückgegebene Objekt wird zerstört +// Das zurückgegbene Objekt wird temporäres Objekt genannt. Temporäre Objekte werden erzeugt +// wann immer eine Funktion ein Objekt zurückgibt. Zerstört werden diese am Ende der Auswertung des Ausdrucks +// (dies schreibt der Standard vor, aber Compiler sind berechtigt dieses Verhalten zu ändern. Siehe "return value optimization" +// für Details). Wie in diesem Code: +foo(bar(tempObjectFun())) + +// Nehmen wir an foo und bar existieren. Das Objekt wird von "tempObjectFun" zurückgegeben, +// wird an bar übergeben und ist zerstört bevor foo aufgerufen wird. + +// Zurück zu Referenzen. Die Ausnahme, dass die "am Ende des Ausdrucks" Regel ist gültig, +// wenn das temporäre Objekt an eine konstante Referenz gebunden ist, in welchem Fall das +// Leben auf den aktuellen Gültigkeitsbereich erweitert wird. + +void constReferenceTempObjectFun() { + // constRef erhält das temporäre Objekt und ist gültig bis ans Ende der Funktion + const string& constRef = tempObjectFun(); + ... +} + +// Eine andere Art von Referenzen wird in C++11 eingeführt und ist speziell für +// temporäre Objekte. Es ist nicht möglich Variablen des Typs zu besitzen, aber +// Vorrechte bei der Auflösung. +void someFun(string& s) { ... } // Reguläre Referenz +void someFun(string&& s) { ... } // Referenz auf ein temporäres Objekt + +string foo; +someFun(foo); // Ruft die Funktion mit der regulären Referenz auf +someFun(tempObjectFun()); // Ruft die Funktion mit der temporären Referenz auf + +// Zum Beispiel existieren diese zwei Varianten von Konstruktoren für +// std::basic_string: +basic_string(const basic_string& other); +basic_string(basic_string&& other); + +// Nehmen wir an, wir erzeugen einen neuen String eines temporären Objekts (welches später +// zerstört wird), hierbei existiert ein effizienterer Konstruktor. Dieses Konzept wird +// als "move semantics" bezeichnet (bewegen eines Objekts in ein anderes in C++). + +///////////////////// +// Enumerations (Aufzählungstypen) +///////////////////// + +// Enums sind eine einfachere Art und Weise einen Wert einer Konstante zu zuweisen. +// Häufig wird dies verwendet, um den Code lesbarer zu gestalten bzw. zu visualisieren. +enum ECarTypes +{ + Sedan, + Hatchback, + SUV, + Wagon +}; + +ECarTypes GetPreferredCarType() +{ + return ECarTypes::Hatchback; +} + +// Mit C++11 existiert eine einfache Möglichkeit einem Typ dem Enum zu zuweisen. Dies +// kann durchaus sinnvoll bei der Serialisierung von Daten sein, oder bei der Konvertierung +// zwischen Typen bzw. Konstanten. +enum ECarTypes : uint8_t +{ + Sedan, // 0 + Hatchback, // 1 + SUV = 254, // 254 + Hybrid // 255 +}; + +void WriteByteToFile(uint8_t InputValue) +{ + // Serialisierung von InputValue in eine Datei +} + +void WritePreferredCarTypeToFile(ECarTypes InputCarType) +{ + // Das enum wird implizit zu einem "uint8_t" konvertiert. Bedingt dadurch, dass + // es sich um ein enum handelt. + WriteByteToFile(InputCarType); +} + +// Nicht immer ist es gewünscht, dass enums zu einem Integer oder zu einem anderen +// enum umgewandelt werden. Daher ist es möglich eine enum-Klasse zu erzeugen, welche +// nicht implizit umgewandelt wird. +enum class ECarTypes : uint8_t +{ + Sedan, // 0 + Hatchback, // 1 + SUV = 254, // 254 + Hybrid // 255 +}; + +void WriteByteToFile(uint8_t InputValue) +{ + // Serialisierung von InputValue in eine Datei +} + +void WritePreferredCarTypeToFile(ECarTypes InputCarType) +{ + // Wird nicht kompilieren, da ECarTypes ein "uint8_t" ist, da das enum + // als "enum class" deklariert wurde! + WriteByteToFile(InputCarType); +} + +////////////////////////////////////////// +// Klassen und objekorientierte Programmierung +////////////////////////////////////////// + +// Erstes Beispiel einer Klasse +#include <iostream> + +// Deklaration einer Klasse. +// Klassen werden üblicherweise im header (.h oder .hpp) deklariert. +class Dog +{ + // Member Variablen und Funktionen sind private per default (standard). + std::string name; + int weight; + +// Alle nachfolgenden member sind "public" bis +// "private:" oder "protected:" auftritt. +public: + + // Standard Konstruktor + Dog(); + + // Member-Funktonensdeklaration (Implementierung folgt) + // Bemerkung: std::string statt der Verwendung von namespace std; + // "using namespace" sollte niemals in einem header verwendet werden. + void setName(const std::string& dogsName); + + void setWeight(int dogsWeight); + + // Funktionen, die Objekte nicht ändern sollte mit const deklariert werden. + // Funktionen müssen explizit als "virtual" deklariert werden, um in einer + // abgeleiteten Klassen überschrieben zu werden. + // Aus performance Gründen sind Funktionen nicht per default virtual. + virtual void print() const; + + // Funktionen können ebenfalls im class body definiert werden. + // Derart definierte Funktionen sind automatisch "inline". + void bark() const { std::cout << name << " barks!\n"; } + + // Neben Konstruktoren, bietet C++ Destruktoren. + // Diese werden aufgerufen, wenn ein Objekt freigegeben wird oder + // seinen Wertebereich verlässt. + // Dies ermöglicht mächtige Paradigmen, wie auch RAII. + // Destruktoren sollten virtual sein, wenn eine Klasse von ihr + // abgeleitet wird. Ist dieser nicht virtual, dann wird der + // Destruktor der abgeleiteten Klasse nicht aufgerufen, insofern + // das Objekt durch eine Referenz/Pointer der Basisklasse entfernt wird. + virtual ~Dog(); + +}; // Ein Semikolon schließt die Definition der Klasse ab. + +// Klassen-Member-Funktionen sind üblicherweise in der .cpp Datei implmentiert. +Dog::Dog() +{ + std::cout << "A dog has been constructed\n"; +} + +// Objekte sollten als Referenz übergeben werden und wenn diese nicht +// verändert werden sollen, sollte das Objekt als const Referenz übergeben werden. +void Dog::setName(const std::string& dogsName) +{ + name = dogsName; +} + +void Dog::setWeight(int dogsWeight) +{ + weight = dogsWeight; +} + +// "Virtual" wird nur bei der Deklaration benötigt und nicht bei der 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; // Ausgabe: "A dog has been constructed" + myDog.setName("Barkley"); + myDog.setWeight(10); + myDog.print(); // Ausgabe: "Dog is Barkley and weighs 10 kg" + return 0; +} // Ausgabe: "Goodbye Barkley" + +// Vererbung: + +// Diese Klasse erbt alles was public bzw. protected ist von der Dog-Klasse +// und darüber hinaus auch private Methoden/Attribute, jedoch kann auf diese +// nicht direkt zugegriffen werden. Lediglich über public/procted getter/setter. +class OwnedDog : public Dog { + +public: + void setOwner(const std::string& dogsOwner); + + // Überschreibt das Verhalten der "print" Funktion für alle "OwnedDogs". + // Siehe: http://en.wikipedia.org/wiki/Polymorphism_(computer_science)#Subtyping + // für eine grundlegende Einführung in "Subtype Polymorphismus". + // Das "override" Schlüsselwort ist optional, aber stellt sicher, dass die + // Methode der Basisklasse tatsächlich überschrieben wurde. + void print() const override; + +private: + std::string owner; +}; + +// Die zugehörige .cpp Datei +void OwnedDog::setOwner(const std::string& dogsOwner) +{ + owner = dogsOwner; +} + +void OwnedDog::print() const +{ + Dog::print(); // Ruft die "print" Funktion der Basisklasse auf. + std::cout << "Dog is owned by " << owner << "\n"; + // Ausgaben: "Dog is <name> and weights <weight>" + // "Dog is owned by <owner>" +} + +////////////////////////////////////////// +// Initialisierung und Operatorüberladung +////////////////////////////////////////// + +// In C++ können Operatoren wie: +, -, *, / etc. überladen werden. +// Dies wird umgesetzt, indem eine entsprechende Funktion definiert wird, +// welche immer dann aufgerufen wird, sobald der Operator verwendet wird. +#include <iostream> +using namespace std; + +class Point +{ +public: + // Member Variablen können mit einem default Wert initialisiert werden. + double x = 0; + double y = 0; + + // Definition des Standard Konstruktor, welcher nichts tut + // außer den Punkt auf den default Wert (0,0) zu setzen. + Point() { }; + + // Die nachfolgende Syntax ist bekannt als "initialization list" + // und ist eine gängige Art Klassen-Member zu initialisieren. + Point (double a, double b) : + x(a), + y(b) + { /* Außschließliche Initialisierung der Werte */ } + + // Überladung des "+" Operator. + Point operator+(const Point& rhs) const; + + // Überladung des "+=" Operator + Point& operator+=(const Point& rhs); + + // Sinnhaft wäre es an dieser Stelle den "-" und "-=" Operator + // ebenfalls zu überladen. +}; + +Point Point::operator+(const Point& rhs) const +{ + // Erzeugung eines neuen Punkts, welcher die Summe aus sich + // selbst und "rhs" bildet + 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); + + // Ruft den + Operator mit den entsprechenden Parametern auf. + Point result = up + right; + // Ausgabe: "Result is upright (1,1)" + cout << "Result is upright (" << result.x << ',' << result.y << ")\n"; + return 0; +} + +///////////////////// +// Templates +///////////////////// + +// Templates in C++ werden in erster Linie dafür verwendet generisch zu programmieren. +// Sie unterstützen explizite und partielle Spezialisierung und darüber hinaus können +// sie für funktionale Klassen verwendet werden. +// Tatsächlich bilden templates die Turing-Vollständigkeit +// (universelle Programmierbarkeit) ab. + + +// Zu Beginn ein einführendes Beispiel der generischen Programmierung. +// Die Definition einer Klasse bzw. Funktion, welche mit dem Typ T parametriert wird. +template<class T> +class Box +{ +public: + // T repräsentiert an dieser Stelle einen beliebigen Typen. + void insert(const T&) { ... } +}; + +// Während der Kompilierung generiert der Kompiler Kopien für jedes Template, wobei +// hierbei die Parameter substituiert werden. Somit muss bei jedem Aufruf die gesamte +// Definition der Klasse zur Verfügung stehen. Aus diesem Grund wird ein Template +// komplett im header definiert. + +// Erzeugung einer Template-Klasse auf dem stack: +Box<int> intBox; + +// eine der zu erwartenden Verwendungen: +intBox.insert(123); + +// Verschachtelungen von Templates sind möglich. +Box<Box<int> > boxOfBox; +boxOfBox.insert(intBox); + +// Bis C++11 war es erforderlich ein Leerzeichen zwischen '>' einzufügen, +// andernfalls wurde es als '>>' geparsed (right shift). + +// Manchmal ist folgende Notation anzutreffen: +// template<typename T> +// Das 'class' Schlüsselwort und das 'typename' Schlüsselwort +// sind fast identisch hinsichtlich der Funktionalität. Weitere +// Informationen auf: http://en.wikipedia.org/wiki/Typename + +// Eine template-Funktion: +template<class T> +void barkThreeTimes(const T& input) +{ + input.bark(); + input.bark(); + input.bark(); +} + +// Hierbei ist zu beachten, dass an dieser Stelle nichts über den Typen des Parameters +// definiert wurde. Der Kompiler wird bei jedem Aufruf bzw. jeder Erzeugung den Typen +// prüfen. Somit funktioniert die zuvor definiert Funktion für jeden Typ 'T', die die +// const Methode 'bark' implementiert hat. + +Dog fluffy; +fluffy.setName("Fluffy") +barkThreeTimes(fluffy); // Gibt "Fluffy barks" dreimal aus. + +// Template Parameter müssen keine Klassen sein. +template<int Y> +void printMessage() +{ + cout << "Learn C++ in " << Y << " minutes!" << endl; +} + +// Des Weiteren können templates aus Effizienzgründen genauer spezifiziert werden. +// Selbstverständlich sind reale-Problemen, welche genauer spezifiziert werden nicht +// derart trivial. Auch wenn alle Parameter explizit definiert wurden, muss die +// Funktion oder Klasse als template deklariert werden. +template<> +void printMessage<10>() +{ + cout << "Learn C++ faster in only 10 minutes!" << endl; +} + +printMessage<20>(); // Gibt "Learn C++ in 20 minutes!" aus. +printMessage<10>(); // Gibt "Learn C++ faster in only 10 minutes!" aus. + + +///////////////////// +// Ausnahme Behandlungen (Exception-Handling) +///////////////////// + +// Die Standard Bibliothek bietet einige Exceptions. +// Siehe: http://en.cppreference.com/w/cpp/error/exception. +// Grundsätzlich können alle Typen als Exception geworfen werden. +#include <exception> +#include <stdexcept> + +// Alle Exceptions, die in dem "try" Block geworfen werden, können mittels +// "catch" abgefangen werden. +try +{ + // Exceptions sollten nicht auf dem heap mithilfe + // von "new" allokiert werden. + throw std::runtime_error("A problem occurred"); +} + +// Exceptions sollten als const Referenz abgefangen werden +// insofern diese Objekte sind. +catch (const std::exception& ex) +{ + std::cout << ex.what(); +} + +// Abfangen aller Exceptions, welche zuvor nicht abgefangen wurden. +catch (...) +{ + std::cout << "Unknown exception caught"; + throw; // Erneutes werfen der exception +} + +/////// +// RAII +/////// + +// RAII steht für "Resource Acquisition Is Initialization". +// Oft wird dies als eines der wichtigsten Paradigmen in C++ betrachtet. +// RAII beschreibt das Konzept, dass der Konstruktor für ein Objekt +// die Ressourcen akquiriert und der Destruktor diese freigibt. + +// Zum Verständnis, warum dies sinnvoll ist, nachfolgend +// ein einführendes Beispiel: +void doSomethingWithAFile(const char* filename) +{ + // Wir nehmen an, dass nichts schiefgehen wird. + FILE* fh = fopen(filename, "r"); // Öffnen der Datei im read-mode. + + doSomethingWithTheFile(fh); + doSomethingElseWithIt(fh); + + fclose(fh); // Schließen des file-handle. +} + +// Unglücklicherweise ist die Fehlerbehandlung äußerst kompliziert. +// Sollte fopen fehlschlagen und "doSomethingWithTheFile" bzw. +// "doSomethingElseWithIt", geben diese einen Fehlercode zurück. +// (Exceptions sind eine bevorzugte Möglichkeit Fehler abzufangen +// , allerdings bei einigen Programmierern, besonders solchen die einen C +// background besitzen, ein unbeliebtes Mittel zur Fehlerbehandlung). +// Nun müssen wir jeden Aufruf auf mögliche auftretende Fehler überprüfen. +bool doSomethingWithAFile(const char* filename) +{ + FILE* fh = fopen(filename, "r"); // Öffnet die Datei im read-mode + if (fh == nullptr) // Der Pointer ist bei einem Fehler NULL . + return false; // Benachrichtigt den Aufrufer über den Fehler. + + // Wir nehmen an, dass jede Funktion false zurückgibt, in einem Fehlerfall + if (!doSomethingWithTheFile(fh)) + { + fclose(fh); // File handle schließen. + return false; // Fehler "melden". + } + + if (!doSomethingElseWithIt(fh)) + { + fclose(fh); // File handle schließen. + return false; // Fehler "melden". + } + + fclose(fh); // File handle schließen. + return true; // Erfolg "melden". +} + +// C-Programmierer handhaben dies häufig durch goto-Anweisungen: +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); // File handle schließen. + return true; // Erfolg "melden". + +failure: + fclose(fh); + return false; // Fehler "melden". +} + +// Insofern Funktionen Fehler durch exceptions indizieren, +// ist dies "sauberer", aber immer noch suboptimal. +void doSomethingWithAFile(const char* filename) +{ + FILE* fh = fopen(filename, "r"); // Öffnet die Datei im read-mode + if (fh == nullptr) + throw std::runtime_error("Could not open the file."); + + try + { + doSomethingWithTheFile(fh); + doSomethingElseWithIt(fh); + } + catch (...) + { + // Im Fehlerfall sollte sichergestellt sein, dass die + // Datei geschlossen wird. + fclose(fh); + throw; // Erneutes werfen der Exception + } + + fclose(fh); // Schließen der Datei +} + +// Folgendes ist mit der C++ file stream Klasse (fstream) zu vergleichen. +// fstream verwendet den Destruktor, um die Datei zu schließen. +// Der obige Destruktor wird automatisch aufgerufen, sobald das Objekt +// den Gültigkeitsbereich verlässt. +void doSomethingWithAFile(const std::string& filename) +{ + // ifstream entspricht der Kurzform von "input file stream". + std::ifstream fh(filename); // Öffnen der Datei + + doSomethingWithTheFile(fh); + doSomethingElseWithIt(fh); + +} // Die Datei wird automatisch vom Destruktor geschlossen. + +// Diese Vorgehensweise bietet massive Vorteile: +// 1. Egal was passiert, die Ressource (das Datei-Handle) wird aufgelöst, +// insofern der Destruktor korrekt beschrieben wurde. Es ist möglich +// zu vergessen das Datei-Handle zu schließen, was zu einem "leak" der +// entsprechenden Ressource führt. +// 2. Der Code selbst ist wesentlich "sauberer". +// Der Destruktor wird das Datei-Handle im Hintergrund schließen und der +// Programmierer muss sich darum keinerlei Sorgen machen. +// 3. Der Code ist "exception sicher". +// Egal wo die exception geworfen wird, das Aufäumen wird definitv vollzogen. + +// Der gesamte idiomatische C++ Code verwendet RAII für alle Ressourcen. +// Weitere Beispiele: +// - Speicher verwenden "unique_ptr" und "shared_ptr". +// - Container - verkettete Listen (linked list), vector (selbst organisierende +// Arrays), hash maps, etc., entfernen deren Inhalt, wenn diese außerhalb des +// Gültigkeitsbereichs laufen. +// - Mutex´s verwenden lock_guard und unique_lock. + +///////////////////// +// Container +///////////////////// + +// Die Container der Standard Tenplate Bibliothek beinhaltet einige vordefinierter templates. +// Diese verwalten die Speicherbereiche für die eigenen Elemente und stellen Member-Funktionen +// für den Zugriff und die Maniplulation bereit. + +// Beispielhafte Container: + +// Vector (dynamisches array) +// Erlaubt das Definieren von Arrays oder Listen zur Laufzeit +#include <vector> +string val; +vector<string> my_vector; // Initialisierung des Vectors. +cin >> val; +my_vector.push_back(val); // Fügt den Wert "val" zum Vektor "my_vector" hinzu. +my_vector.push_back(val); // Fügt den Wert "val" zum Vektor "my_vector" hinzu (nun zwei Elemente). + +// Für die Iteration über Vektoren stehen zwei Methodiken zu Verfügung: +// Entweder die klassische Iteration über den Index: +for (int i = 0; i < my_vector.size(); i++) +{ + cout << my_vector[i] << endl; // Zugriff auf die Elemente des Vektors über den [] Operator +} + +// Oder die Verwendung von Iteratoren: +vector<string>::iterator it; // Initialisierng des Iterators. +for (it = my_vector.begin(); it != my_vector.end(); ++it) +{ + cout << *it << endl; +} + +// Set (Mengen) +// Sets sind Container, welche einzigartige Elemente beinhalten die einer +// spezifischen Ordnung folgen. + +#include<set> +set<int> ST; // Initialisierung des Sets mit einem Integer Datentyp. +ST.insert(30); // Einfügen des Werts 30 in das Set ST +ST.insert(10); // Einfügen des Werts 10 in das Set ST +ST.insert(20); // Einfügen des Werts 20 in das Set ST +ST.insert(30); // Einfügen des Werts 30 in das Set ST +// Folgende Elemente befinden sich nun in dem Set: +// 10 20 30 + +// Entfernen eines Elements: +ST.erase(20); + +// Set ST: 10 30 +// Für das iterieren verwenden wir Iteratoren: +set<int>::iterator it; + +for(it=ST.begin();it<ST.end();it++) +{ + cout << *it << endl; +} + +// Ausgabe: +// 10 +// 30 + +// Zum leeren des gesmten Container wird die Methode +// Container._name.clear() verwendet. +ST.clear(); +cout << ST.size(); // Ausgabe der Set-Größe + +// Ausgabe: 0 + +// Bemerkung: für mehrdeutige Elemente werden multisets verwendet. +// Für hash-Sets sollten unordered_set´s verwendet werden, da diese +// wesentlich effizienter sind, allerdings keiner Ordnung folgen. +// Verfügbar sind diese Features ab C++11. + +// Map +// Maps speichern Elemente, welche einer Kombination aus "Key" +// und "Value" folgen. + +#include<map> +map<char, int> mymap; // Initialisierung der Map: char -> Key, int -> Value. + +mymap.insert(pair<char,int>('A',1)); // Einfügen des Werts "1" für den Key "A". + +mymap.insert(pair<char,int>('Z',26)); // Einfügen des Werts "26" für den Key "Z". + +// Das Iterieren über Maps: +map<char,int>::iterator it; +for (it=mymap.begin(); it!=mymap.end(); ++it) + std::cout << it->first << "->" << it->second << '\n'; + +// Ausgabe: +// A->1 +// Z->26 + +// Für das Finden des dazugehörigen Value des Keys. +it = mymap.find('Z'); +cout << it->second; + +// Ausabe: 26 + +// Bemerkung: für "hash maps" sollten die "unordered_map´s" verwendet werden. Diese +// sind effizienter und benötigen keine Reihenfolge. "unordered_maps" sind ab +// C++11 verfügbar. + +// Container für nicht-primitve Datentypen benötigen Vergleichsfunktionen im Objekt selbst, +// oder als Funktionspointer. Primitive Datentypen besitzen default-Vergleichsfunktionen. +// Allerdings können diese überschrieben werden. +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; + } +}; + +// Folgender Code ist nicht valide, könnte aber von einigen Compilern +// als valide angesehen werden: +// std::map<Foo, int> fooMap; +std::map<Foo, int, compareFunction> fooMap; +fooMap[Foo(1)] = 1; +fooMap.find(Foo(1)); // Wahr + + +/////////////////////////////////////// +// Lambda Ausdrücke (C++11 und höher) +/////////////////////////////////////// + +// Lambdas sind eine gängige Methodik um anonyme Funktionen an dem +// Ort der Verwendung zu definieren. Darüber hinaus auch bei der +// Verwendung von Funktionen als Argument einer Funktion. + +// Nehmen wir an es soll ein Vektor von "pairs" (Paaren) mithilfe +// des zweiten Werts des "pairs" sortiert werden. + +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)); + +// Übergabe des Lambda-Ausdrucks als drittes Argument für die nachfolgende Sortierfunktion. +sort(tester.begin(), tester.end(), [](const pair<int, int>& lhs, const pair<int, int>& rhs) +{ + return lhs.second < rhs.second; +}); + +// Beachte den Syntax von Lambda-Ausdrücken. +// Die [] im Lambda Ausdruck werden für die Variablen verwendet. +// Diese so genannte "Capture List" definiert, was außerhalb des Lambdas +// innerhalb der Funktion verfügbar sein soll und in welcher Form. +// Dies kann folgendes sein: +// 1. ein Wert [x] +// 2. eine Referenz [&x] +// 3. eine beliebige Variable, welche sich im Gültigkeitsbereich durch +// die Referenz [&] befindet. +// 4. wie bei 3. aber mithilfe des Werts [=] +// Beispiel: + +vector<int> dog_ids; + +for(int i = 0; i < 3; i++) +{ + dog_ids.push_back(i); +} + +int weight[3] = {30, 50, 10}; + +// Nehmen wir an wir möchten die "dog_ids" gemäß des Gewichts des Hundes sortieren. +// So sollten sich die "dog_ids" wie folgt verhalten: [2, 0, 1] + +// Hier werden Lambdas praktisch: +sort(dog_ids.begin(), dog_ids.end(), [&weight](const int &lhs, const int &rhs) +{ + return weight[lhs] < weight[rhs]; +}); + + +// Weiterführender Link über Lambda-Ausdrücke: +// http://stackoverflow.com/questions/7627098/what-is-a-lambda-expression-in-c11 + +/////////////////////////////// +// Range For (C++11 und höher) +/////////////////////////////// + +// Range-For Schleifen können verwendet werden, um über Container zu iterieren. +int arr[] = {1, 10, 3}; + +for(int elem: arr) +{ + cout << elem << endl; +} + +// Insofern "auto" verwendet wird, muss der Typ nicht weiter beachtet werden. + +for(auto elem: arr) +{ + // Anweisungen ... +} + +///////////////////// +// Weiteres: +///////////////////// + +// Einige Aspekte von C++ sind für Neueinsteiger häufig überraschend (aber auch für +// C++ Veteranen). +// Der nachfolgende Abschnitt ist leider nicht vollständig: +// C++ ist eine der Sprachen, bei der es ein leichtes ist sich selbst ins Bein zu schießen. + +// Private-Methoden können überschrieben werden +class Foo +{ + virtual void bar(); +}; + +class FooSub : public Foo +{ + virtual void bar(); // Überschreibt Foo::bar! +}; + + +// 0 == false == NULL +bool* pt = new bool; +*pt = 0; // Setzt den Wert des Pointers 'pt' auf false. +pt = 0; // Setzt 'pt' auf den "null-pointer". Keine Compiler-Warnung. + +// nullptr sollte dieses Problem nicht lösen: +int* pt2 = new int; +*pt2 = nullptr; // Kompiliert nicht. +pt2 = nullptr; // Setzt pt2 auf null. + +// Eine Ausnahme bilden bools. +// Dies erlaubt es "null-pointer" zu testen: if(!ptr) +// Die Konsequenz ist jedoch, dass dem nullptr ein bool zugewiesen werden kann. +*pt = nullptr; // Kompiliert auch wenn '*pt' ein bool ist! + + +// '=' != '=' != '='! +// Ruft Foo::Foo(const Foo&) auf, oder den Kopierkonstruktor +Foo f2; +Foo f1 = f2; + +// Ruft Foo::Foo(const Foo&) auf, aber kopiert lediglich den "Foo" Teil von +// "fooSub". Alle zusätzlichen Member werden verworfen. Diese eigenartige Verhalten +// wird auch "object slicing" genannt. +FooSub fooSub; +Foo f1 = fooSub; + +// Ruft Foo::operator=(Foo&) oder eine andere Variante auf. +Foo f1; +f1 = f2; + +/////////////////////////////////////// +// Tuple (C++11 und höher) +/////////////////////////////////////// + +#include<tuple> + +// Konzeptionell sind Tuples alten Datenstrukturen sehr ähnlich, allerdings haben diese keine +// benamten Daten-Member, sondern werden durch die Reihenfolge angesprochen. + +// Erstellen des Tuples und das Einfügen eines Werts. +auto first = make_tuple(10, 'A'); +const int maxN = 1e9; +const int maxL = 15; +auto second = make_tuple(maxN, maxL); + +// Ausgabe der Elemente des "first" Tuple. +cout << get<0>(first) << " " << get<1>(first) << "\n"; // Ausgabe : 10 A + +// Ausgabe der Elemente des "second" Tuple. +cout << get<0>(second) << " " << get<1>(second) << "\n"; // Ausgabe: 1000000000 15 + +int first_int; +char first_char; +tie(first_int, first_char) = first; +cout << first_int << " " << first_char << "\n"; // Ausgabe : 10 A + +// Tuple können auch wie folgt erzeugt werden: + +tuple<int, char, double> third(11, 'A', 3.14141); +// tuple_size gibt die Anzahl der Elemente in einem Tuple zurück. +// Als "constexpr". + +cout << tuple_size<decltype(third)>::value << "\n"; // prints: 3 + +// tuple_cat fügt die Elemente eines Tuples aneinander (in der selben Reihenfolge). + +auto concatenated_tuple = tuple_cat(first, second, third); +// concatenated_tuple wird zu = (10, 'A', 1e9, 15, 11, 'A', 3.14141) + +cout << get<0>(concatenated_tuple) << "\n"; // Ausgabe: 10 +cout << get<3>(concatenated_tuple) << "\n"; // Ausgabe: 15 +cout << get<5>(concatenated_tuple) << "\n"; // Ausgabe: 'A' + + +/////////////////////////////////// +// Logische- und Bitoperatoren +////////////////////////////////// + +// Die meisten Operatoren in C++ entsprechen denen aus anderen Sprachen + +// Logische Operatoren. + +// C++ verwendet so genannte "Short-circuit" Evaluierung für boolean-Ausdrücke. +// Das zweite Argument wird ausgeführt bzw. evaluiert, wenn das erste Argument genügt, +// um den Ausdruck zu bestimmen. + +true && false // Führt **logisches und** aus. +true || false // Führt **logisches oder** aus. +! true // Führt **logisches nicht** aus. + +// Anstelle von Symbolen können auch Schlüsselwörter verwendet werden. +true and false // Führt **logisches und** aus. +true or false // Führt **logisches oder** aus. +not true // Führt **logisches nicht** aus. + +// Bitoperationen + +// **<<** Links-Shift +// **>>** Rechts-Shift + +~4 // Führt bitweises nicht aus. +4 | 3 // Führt bitweises oder aus. +4 & 3 // Führt bitweises und aus. +4 ^ 3 // Führt bitweises xor aus. + +// Gleichwertige Schlüsselwörter: +compl 4 // Führt bitweises nicht aus. +4 bitor 3 // Führt bitweises oder aus. +4 bitand 3 // Führt bitweises und aus. +4 xor 3 // Führt bitweises xor aus. + + +``` +Weiterführende Literatur: + +* Aktuelle Sprachen-Referenz [CPP Reference](http://cppreference.com/w/cpp). +* Zusätzliches: [CPlusPlus](http://cplusplus.com). +* Grundlagen Tutorial: [TheChernoProject - C++](https://www.youtube.com/playlist?list=PLlrATfBNZ98dudnM48yfGUldqGD0S4FFb). diff --git a/de-de/git-de.html.markdown b/de-de/git-de.html.markdown index 7c68d785..0896f513 100644 --- a/de-de/git-de.html.markdown +++ b/de-de/git-de.html.markdown @@ -49,7 +49,7 @@ Ein Repository besteht in Git aus dem .git-Verzeichnis und dem Arbeitsverzeichni ### .git-Verzeichnis (Teil des Repositorys) -Das .git-Verzeichnis enthält alle Einstellung, Logs, Branches, den HEAD und mehr. +Das .git-Verzeichnis enthält alle Einstellungen, Logs, Branches, den HEAD und mehr. [Ausführliche Übersicht](http://gitready.com/advanced/2009/03/23/whats-inside-your-git-directory.html) ### Arbeitsverzeichnis (Teil des Repositorys) diff --git a/de-de/make-de.html.markdown b/de-de/make-de.html.markdown index bc5c7bcb..cf90dc29 100644 --- a/de-de/make-de.html.markdown +++ b/de-de/make-de.html.markdown @@ -1,5 +1,6 @@ ---
-language: make
+category: tool
+tool: make
contributors:
- ["Robert Steed", "https://github.com/robochat"]
- ["Stephan Fuhrmann", "https://github.com/sfuhrm"]
diff --git a/de-de/markdown-de.html.markdown b/de-de/markdown-de.html.markdown index cccf5e68..729e883c 100644 --- a/de-de/markdown-de.html.markdown +++ b/de-de/markdown-de.html.markdown @@ -144,7 +144,7 @@ indem du eine Zeile mit vier Leerzeichen oder einem Tabulator einrückst --> puts item end -<!-- Innerhalb normalen Texts kannst du Code mit Backticks ` auszeichnen --> +<!-- Innerhalb normalen Texts kannst du Code mit Backticks \` auszeichnen --> Hermann hatte nicht die leiseste Ahnung, was dieses `go_to()` bedeuten könnte! diff --git a/de-de/python-de.html.markdown b/de-de/python-de.html.markdown index ae29d6f9..ee77683e 100644 --- a/de-de/python-de.html.markdown +++ b/de-de/python-de.html.markdown @@ -386,25 +386,73 @@ filter(lambda x: x > 5, [3, 4, 5, 6, 7]) #=> [6, 7] [add_10(i) for i in [1, 2, 3]] #=> [11, 12, 13] [x for x in [3, 4, 5, 6, 7] if x > 5] #=> [6, 7] + #################################################### -## 5. Klassen +## 5. Module #################################################### -# Wir bilden die Unterklasse eines Objekts, um Klassen zu erhalten. +# Wir können Module importieren +import math +print math.sqrt(16) #=> 4.0 + +# Wir können auch nur spezielle Funktionen eines Moduls importieren +from math import ceil, floor +print ceil(3.7) #=> 4.0 +print floor(3.7) #=> 3.0 + +# Wir können auch alle Funktionen eines Moduls importieren +# Warnung: Dies wird nicht empfohlen +from math import * + +# Wir können Modulnamen abkürzen +import math as m +math.sqrt(16) == m.sqrt(16) #=> True + +# Module sind in Python nur gewöhnliche Dateien. Wir +# können unsere eigenen schreiben und importieren. Der Name des +# Moduls ist der Dateiname. + +# Wir können herausfinden, welche Funktionen und Attribute in einem +# Modul definiert sind. +import math +dir(math) + +# Wenn Sie ein Python-Skript namens math.py im selben Ordner +# wie Ihr aktuelles Skript haben, wird die Datei math.py +# anstelle des integrierten Python-Moduls geladen. +# Dies geschieht, weil der lokale Ordner Vorrang +# vor den in Python integrierten Bibliotheken hat. + + +#################################################### +## 6. Klassen +#################################################### + +# Wir verwenden das Schlüsselwort "class" um eine Klasse zu erzeugen. class Human(object): # Ein Klassenattribut. Es wird von allen Instanzen einer Klasse geteilt species = "H. sapiens" - # Ein simpler Konstruktor + # Ein simpler Konstruktor, wird aufgerufen, wenn diese Klasse instanziiert wird. + # Beachten Sie, dass die doppelten vorangestellten und nachgestellten + # Unterstriche Objekte oder Attribute bezeichnen, die von Python verwendet werden, + # aber in benutzergesteuerten Namespaces leben. + # Methoden (oder Objekte oder Attribute) wie: __init__, __str__, __repr__ usw. + # werden als Sondermethoden (oder manchmal als Dundermethoden bezeichnet) bezeichnet. + # Sie sollten solche Namen nicht selbst erfinden. def __init__(self, name): # Wir weisen das Argument name dem name-Attribut der Instanz zu self.name = name - # Eine Instanzmethode. Alle Methoden erhalten self als erstes Argument. + # Eine Instanzmethode. Alle Methoden erhalten "self" als erstes Argument. def say(self, msg): return "%s: %s" % (self.name, msg) + # Eine weitere Instanzmethode + def sing(self): + return 'yo... yo... microphone check... one two... one two...' + # Eine Klassenmethode wird von allen Instanzen geteilt. # Sie werden mit der aufrufenden Klasse als erstem Argument aufgerufen @classmethod @@ -416,56 +464,287 @@ class Human(object): def grunt(): return "*grunt*" + # Eine Eigenschaft (Property) ist wie ein Getter. + # Es verwandelt die Methode age() in ein schreibgeschütztes Attribut mit demselben Namen. + # Es ist jedoch nicht nötig, triviale Getter und Setter in Python zu schreiben. + @property + def age(self): + return self._age + + # Damit kann die Eigenschaft festgelegt werden + @age.setter + def age(self, age): + self._age = age + + # Damit kann die Eigenschaft gelöscht werden + @age.deleter + def age(self): + del self._age + +# Wenn ein Python-Interpreter eine Quelldatei liest, führt er den gesamten Code aus. +# Diese __name__-Prüfung stellt sicher, dass dieser Codeblock nur ausgeführt wird, +# wenn dieses Modul das Hauptprogramm ist. +if __name__ == '__main__': + # Eine Instanz einer Klasse erstellen + i = Human(name="Ian") + i.say("hi") # "Ian: hi" + j = Human("Joel") + j.say("hello") # "Joel: hello" + # i und j sind Instanzen des Typs Mensch, oder anders ausgedrückt: Sie sind Objekte des Menschen + + # Rufen wir unsere Klassenmethode auf + i.say(i.get_species()) # "Ian: H. sapiens" + + # Ändern wir das gemeinsame Attribut + Human.species = "H. neanderthalensis" + i.say(i.get_species()) # => "Ian: H. neanderthalensis" + j.say(j.get_species()) # => "Joel: H. neanderthalensis" + + # Aufruf der statischen Methode + print(Human.grunt()) # => "*grunt*" + + # Kann keine statische Methode mit Instanz des Objekts aufrufen, + # da i.grunt () automatisch "self" (das Objekt i) als Argument verwendet + print(i.grunt()) # => TypeError: grunt() takes 0 positional arguments but 1 was given + + # Die Eigenschaft für diese Instanz aktualisieren + i.age = 42 + # die Eigenschaft auslesen + i.say(i.age) # => "Ian: 42" + j.say(j.age) # => "Joel: 0" + # die Eigenschaft löschen + del i.age + # i.age # => würde einen AttributeError werfen + +#################################################### +## 6.1 Inheritance +#################################################### + +# Vererbung ermöglicht die Definition neuer untergeordneter Klassen, +# die Methoden und Variablen von ihrer übergeordneten Klasse erben. + +# Wenn Sie die oben definierte Human-Klasse als Basis- oder Elternklasse verwenden, +# können Sie eine untergeordnete Klasse, Superhero, definieren, die die Klassenvariablen +# wie "species", "name" und "age" sowie Methoden wie "sing" und "grunzen" aus der Klasse Human erbt. +# Die Untergeordnete Klasse kann aber auch eigene Eigenschaften haben. + +# Um von der Modularisierung per Datei zu profitieren, können Sie die Klassen +# in ihren eigenen Dateien platzieren, z. B. human.py + +# Um Funktionen aus anderen Dateien zu importieren, verwenden Sie das folgende Format +# from "Dateiname-ohne-Erweiterung" impotr "Funktion-oder-Klasse" + +from human import Human + +# Geben Sie die übergeordnete(n) Klasse(n) als Parameter für die Klassendefinition an +class Superhero(Human): + + # Wenn die untergeordnete Klasse alle Definitionen des übergeordneten Elements + # ohne Änderungen erben soll, können Sie einfach das Schlüsselwort "pass" + # (und nichts anderes) verwenden. In diesem Fall wird jedoch auskommentiert, + # um eine eindeutige untergeordnete Klasse zuzulassen: + # pass + + # Kindklassen können die Attribute ihrer Eltern überschreiben + species = 'Superhuman' + + # Kinder erben automatisch den Konstruktor ihrer übergeordneten Klasse + # einschließlich ihrer Argumente, können aber auch zusätzliche Argumente oder + # Definitionen definieren und ihre Methoden zB den Klassenkonstruktor überschreiben. + # Dieser Konstruktor erbt das Argument "name" von der Klasse "Human" und + # fügt die Argumente "superpowers" und "movie" hinzu: + def __init__(self, name, movie=False, + superpowers=["super strength", "bulletproofing"]): + + # zusätzliche Klassenattribute hinzufügen: + self.fictional = True + self.movie = movie + # Beachten Sie die veränderlichen Standardwerte, da die Standardwerte gemeinsam genutzt werden + self.superpowers = superpowers + + # Mit der Funktion "super" können Sie auf die Methoden der übergeordneten Klasse + # zugreifen, die vom untergeordneten Objekt überschrieben werden, + # in diesem Fall die Methode __init__. + # Dies ruft den Konstruktor der übergeordneten Klasse auf: + super().__init__(name) + + # überschreiben der "sing" Methode + def sing(self): + return 'Dun, dun, DUN!' + + # eine zusätzliche Instanzmethode hinzufügen + def boast(self): + for power in self.superpowers: + print("I wield the power of {pow}!".format(pow=power)) + +if __name__ == '__main__': + sup = Superhero(name="Tick") + + # Instanztypprüfungen + if isinstance(sup, Human): + print('I am human') + if type(sup) is Superhero: + print('I am a superhero') + + # Die Reihenfolge der Methodenauflösung (MRO = Method Resolution Order) anzeigen, die sowohl von getattr() als auch von super() verwendet wird. + # Dieses Attribut ist dynamisch und kann aktualisiert werden. + print(Superhero.__mro__) # => (<class '__main__.Superhero'>, + # => <class 'human.Human'>, <class 'object'>) + + # Ruft die übergeordnete Methode auf, verwendet jedoch das eigene Klassenattribut + print(sup.get_species()) # => Superhuman + + # Ruft die überschriebene Methode auf + print(sup.sing()) # => Dun, dun, DUN! + + # Ruft die Methode von Human auf + sup.say('Spoon') # => Tick: Spoon + + # Aufruf einer Methode, die nur in Superhero existiert + sup.boast() # => I wield the power of super strength! + # => I wield the power of bulletproofing! + + # Vererbtes Klassenattribut + sup.age = 31 + print(sup.age) # => 31 + + # Attribut, das nur in Superhero existiert + print('Am I Oscar eligible? ' + str(sup.movie)) + +#################################################### +## 6.2 Multiple Inheritance +#################################################### -# Eine Instanz einer Klasse erstellen -i = Human(name="Ian") -print i.say("hi") # gibt "Ian: hi" aus +# Eine weitere Klassendefinition +# bat.py -j = Human("Joel") -print j.say("hello") #gibt "Joel: hello" aus +class Bat: -# Rufen wir mal unsere Klassenmethode auf -i.get_species() #=> "H. sapiens" + species = 'Baty' -# Ändern wir mal das gemeinsame Attribut -Human.species = "H. neanderthalensis" -i.get_species() #=> "H. neanderthalensis" -j.get_species() #=> "H. neanderthalensis" + def __init__(self, can_fly=True): + self.fly = can_fly -# Aufruf der statischen Methode -Human.grunt() #=> "*grunt*" + # This class also has a say method + def say(self, msg): + msg = '... ... ...' + return msg + # And its own method as well + def sonar(self): + return '))) ... (((' +if __name__ == '__main__': + b = Bat() + print(b.say('hello')) + print(b.fly) + +# Und noch eine andere Klassendefinition, die von Superhero und Bat erbt +# superhero.py +from superhero import Superhero +from bat import Bat + +# Definieren Sie Batman als eine Kindklasse, das von Superheld und Bat erbt +class Batman(Superhero, Bat): + + def __init__(self, *args, **kwargs): + # In der Regel müssen Sie super aufrufen, um Attribute zu erben: + # super (Batman, selbst) .__ init__ (* args, ** kwargs) + # Allerdings handelt es sich hier um Mehrfachvererbung, und super() + # funktioniert nur mit der nächsten Basisklasse in der MRO-Liste. + # Stattdessen rufen wir explizit __init__ für alle Vorfahren auf. + # Die Verwendung von *args und **kwargs ermöglicht die saubere Übergabe von + # Argumenten, wobei jedes übergeordnete Element eine Schicht der Zwiebel "abschält". + Superhero.__init__(self, 'anonymous', movie=True, + superpowers=['Wealthy'], *args, **kwargs) + Bat.__init__(self, *args, can_fly=False, **kwargs) + # überschreibt den Wert für das Namensattribut + self.name = 'Sad Affleck' + + def sing(self): + return 'nan nan nan nan nan batman!' + +if __name__ == '__main__': + sup = Batman() + + # Die Reihenfolge der Methodenauflösung (MRO = Method Resolution Order) anzeigen, + # die sowohl von getattr() als auch von super() verwendet wird. + # Dieses Attribut ist dynamisch und kann aktualisiert werden. + print(Batman.__mro__) # => (<class '__main__.Batman'>, + # => <class 'superhero.Superhero'>, + # => <class 'human.Human'>, + # => <class 'bat.Bat'>, <class 'object'>) + + # Ruft die übergeordnete Methode auf, verwendet jedoch das eigene Klassenattribut + print(sup.get_species()) # => Superhuman + + # Ruft die überschriebene Methode auf + print(sup.sing()) # => nan nan nan nan nan batman! + + # Ruft die Methode von Human auf, weil die Reihenfolge der Vererbung wichtig ist + sup.say('I agree') # => Sad Affleck: I agree + + # Aufrufmethode, die nur im 2. Vorfahren existiert + print(sup.sonar()) # => ))) ... ((( + + # Vererbtes Klassenattribut + sup.age = 100 + print(sup.age) # => 100 + + # Vererbtes Attribut vom 2. Vorfahren, dessen Standardwert überschrieben wurde. + print('Can I fly? ' + str(sup.fly)) # => Can I fly? False + + #################################################### -## 6. Module -#################################################### - -# Wir können Module importieren -import math -print math.sqrt(16) #=> 4 +## 7. Fortgeschrittenes +#################################################### + +# Generatoren helfen Ihnen, lazy Code zu erstellen. +def double_numbers(iterable): + for i in iterable: + yield i + i + +# Generatoren sind speichereffizient, da sie nur die Daten laden, +# die zur Verarbeitung des nächsten Werts in der iterierbaren Komponente +# erforderlich sind. Dadurch können sie ansonsten unzulässig große Wertebereiche ausführen. +# HINWEIS: `range` ersetzt` xrange` in Python 3. +for i in double_numbers(range(1, 900000000)): # `range` ist ein Generator. + print(i) + if i >= 30: + break + +# Genauso wie Sie ein 'list comprehension' (Listen Abstraktion) erstellen können, können Sie auch 'generator comprehension' (Generator Abstraktion) erstellen. +values = (-x for x in [1,2,3,4,5]) +for x in values: + print(x) # prints -1 -2 -3 -4 -5 to console/terminal + +# Sie können eine Generator Abstraktion auch direkt in eine Liste umwandeln (casten). +values = (-x for x in [1,2,3,4,5]) +gen_to_list = list(values) +print(gen_to_list) # => [-1, -2, -3, -4, -5] -# Wir können auch nur spezielle Funktionen eines Moduls importieren -from math import ceil, floor -print ceil(3.7) #=> 4.0 -print floor(3.7) #=> 3.0 +# Decorators +# In diesem Beispiel umschliesst "beg" "say". Wenn say_please True ist, wird die zurückgegebene Nachricht geändert. +from functools import wraps -# Wir können auch alle Funktionen eines Moduls importieren -# Warnung: Dies wird nicht empfohlen -from math import * +def beg(target_function): + @wraps(target_function) + def wrapper(*args, **kwargs): + msg, say_please = target_function(*args, **kwargs) + if say_please: + return "{} {}".format(msg, "Please! I am poor :(") + return msg -# Wir können Modulnamen abkürzen -import math as m -math.sqrt(16) == m.sqrt(16) #=> True + return wrapper -# Module sind in Python nur gewöhnliche Dateien. Wir -# können unsere eigenen schreiben und importieren. Der Name des -# Moduls ist der Dateiname. +@beg +def say(say_please=False): + msg = "Can you buy me a beer?" + return msg, say_please -# Wir können auch die Funktionen und Attribute eines -# Moduls herausfinden. -import math -dir(math) +print(say()) # Can you buy me a beer? +print(say(say_please=True)) # Can you buy me a beer? Please! I am poor :( ``` diff --git a/de-de/python3-de.html.markdown b/de-de/python3-de.html.markdown index b313727c..c383d742 100644 --- a/de-de/python3-de.html.markdown +++ b/de-de/python3-de.html.markdown @@ -555,7 +555,7 @@ Human.grunt() #=> "*grunt*" # Wir können Module importieren import math -print(math.sqrt(16)) #=> 4 +print(math.sqrt(16)) #=> 4.0 # Wir können auch nur spezielle Funktionen eines Moduls importieren from math import ceil, floor diff --git a/de-de/yaml-de.html.markdown b/de-de/yaml-de.html.markdown index d0e3471a..ff45dc8d 100644 --- a/de-de/yaml-de.html.markdown +++ b/de-de/yaml-de.html.markdown @@ -111,7 +111,7 @@ python_komplexe_Zahlen: !!python/komplex 1+2j # EXTRA YAML TYPEN # #################### -# Strings and Zahlen sind nicht die einzigen Skalare, welche YAML versteht. +# Strings und Zahlen sind nicht die einzigen Skalare, welche YAML versteht. # ISO-formatierte Datumsangaben and Zeiangaben können ebenso geparsed werden. DatumZeit: 2001-12-15T02:59:43.1Z DatumZeit_mit_Leerzeichen: 2001-12-14 21:59:43.10 -5 diff --git a/dynamic-programming.html.markdown b/dynamic-programming.html.markdown index f5f1743c..c73b1845 100644 --- a/dynamic-programming.html.markdown +++ b/dynamic-programming.html.markdown @@ -49,3 +49,5 @@ for i=0 to n-1 ## Online Resources * [codechef](https://www.codechef.com/wiki/tutorial-dynamic-programming) +* [InterviewBit](https://www.interviewbit.com/courses/programming/topics/dynamic-programming/) + diff --git a/elisp.html.markdown b/elisp.html.markdown index 518ad985..f839dac0 100644 --- a/elisp.html.markdown +++ b/elisp.html.markdown @@ -281,7 +281,7 @@ filename: learn-emacs-lisp.el ;; should stop searching at some point in the buffer, and whether it ;; should silently fail when nothing is found: -;; (search-forward "Hello" nil 't) does the trick: +;; (search-forward "Hello" nil t) does the trick: ;; The `nil' argument says: the search is not bound to a position. ;; The `'t' argument says: silently fail when nothing is found. @@ -295,7 +295,7 @@ filename: learn-emacs-lisp.el (mapcar 'hello list-of-names) (goto-char (point-min)) ;; Replace "Hello" by "Bonjour" - (while (search-forward "Hello" nil 't) + (while (search-forward "Hello" nil t) (replace-match "Bonjour")) (other-window 1)) @@ -306,7 +306,7 @@ filename: learn-emacs-lisp.el (defun boldify-names () (switch-to-buffer-other-window "*test*") (goto-char (point-min)) - (while (re-search-forward "Bonjour \\(.+\\)!" nil 't) + (while (re-search-forward "Bonjour \\(.+\\)!" nil t) (add-text-properties (match-beginning 1) (match-end 1) (list 'face 'bold))) diff --git a/elixir.html.markdown b/elixir.html.markdown index e82509e7..7af29202 100644 --- a/elixir.html.markdown +++ b/elixir.html.markdown @@ -452,7 +452,7 @@ Agent.update(my_agent, fn colors -> ["blue" | colors] end) ## References * [Getting started guide](http://elixir-lang.org/getting-started/introduction.html) from the [Elixir website](http://elixir-lang.org) -* [Elixir Documentation](http://elixir-lang.org/docs/master/) +* [Elixir Documentation](https://elixir-lang.org/docs.html) * ["Programming Elixir"](https://pragprog.com/book/elixir/programming-elixir) by Dave Thomas * [Elixir Cheat Sheet](http://media.pragprog.com/titles/elixir/ElixirCheat.pdf) * ["Learn You Some Erlang for Great Good!"](http://learnyousomeerlang.com/) by Fred Hebert diff --git a/es-es/awk-es.html.markdown b/es-es/awk-es.html.markdown index 0516ea92..8da8f024 100644 --- a/es-es/awk-es.html.markdown +++ b/es-es/awk-es.html.markdown @@ -1,5 +1,6 @@ --- -language: awk +category: tool +tool: awk filename: learnawk-es.awk contributors: - ["Marshall Mason", "http://github.com/marshallmason"] diff --git a/es-es/common-lisp-es.html.markdown b/es-es/common-lisp-es.html.markdown new file mode 100644 index 00000000..526ea621 --- /dev/null +++ b/es-es/common-lisp-es.html.markdown @@ -0,0 +1,692 @@ +--- + +language: "Common Lisp" +filename: commonlisp-es.lisp +contributors: + - ["Paul Nathan", "https://github.com/pnathan"] + - ["Rommel Martinez", "https://ebzzry.io"] +translators: + - ["ivanchoff", "https://github.com/ivanchoff"] + - ["Andre Polykanine", "https://github.com/Menelion"] +lang: es-es +--- + +Common Lisp es un lenguaje de proposito general y multiparadigma adecuado para una amplia variedad +de aplicaciones en la industria. Es frecuentemente referenciado como un lenguaje de programación +programable. + +EL punto de inicio clásico es [Practical Common Lisp](http://www.gigamonkeys.com/book/). Otro libro +popular y reciente es [Land of Lisp](http://landoflisp.com/). Un nuevo libro acerca de las mejores +prácticas, [Common Lisp Recipes](http://weitz.de/cl-recipes/), fue publicado recientemente. + +```lisp + +;;;----------------------------------------------------------------------------- +;;; 0. Sintaxis +;;;----------------------------------------------------------------------------- + +;;; Forma general + +;;; CL tiene dos piezas fundamentales en su sintaxis: ATOM y S-EXPRESSION. +;;; Típicamente, S-expressions agrupadas son llamadas `forms`. + +10 ; un atom; se evalua a sí mismo +:thing ; otro atom; evaluando el símbolo :thing +t ; otro atom, denotando true +(+ 1 2 3 4) ; una s-expression +'(4 :foo t) ; otra s-expression + + +;;; Comentarios + +;;; comentarios de una sola línea empiezan con punto y coma; usa cuatro para +;;; comentarios a nivel de archivo, tres para descripciones de sesiones, dos +;;; adentro de definiciones, y una para líneas simples. Por ejemplo, + +;;;; life.lisp + +;;; Foo bar baz, porque quu quux. Optimizado para máximo krakaboom y umph. +;;; Requerido por la función LINULUKO. + +(defun sentido (vida) + "Retorna el sentido de la vida calculado" + (let ((meh "abc")) + ;; llama krakaboom + (loop :for x :across meh + :collect x))) ; guarda valores en x, luego lo retorna + +;;; Comentarios de bloques, por otro lado, permiten comentarios de forma libre. estos son +;;; delimitados con #| y |# + +#| Este es un comentario de bloque el cual + puede abarcar multiples líneas y + #| + estos pueden ser anidados + |# +|# + + +;;; Entorno + +;;; Existe una variedad de implementaciones; La mayoría son conformes a los estándares. SBCL +;;; es un buen punto de inicio. Bibliotecas de terceros pueden instalarse fácilmente con +;;; Quicklisp + +;;; CL es usualmente desarrollado y un bucle de Lectura-Evaluación-Impresión (REPL), corriendo +;;; al mismo tiempo. El REPL permite la exploración interactiva del programa mientras este esta +;;; corriendo + + +;;;----------------------------------------------------------------------------- +;;; 1. Operadores y tipos de datos primitivos +;;;----------------------------------------------------------------------------- + +;;; Símbolos + +'foo ; => FOO Note que el símbolo es pasado a mayúsculas automáticamente. + +;;; INTERN manualmente crea un símbolo a partir de una cadena. + +(intern "AAAA") ; => AAAA +(intern "aaa") ; => |aaa| + +;;; Números + +9999999999999999999999 ; enteros +#b111 ; binario=> 7 +#o111 ; octal => 73 +#x111 ; hexadecimal => 273 +3.14159s0 ; simple +3.14159d0 ; double +1/2 ; proporciones +#C(1 2) ; números complejos + +;;; las funciones son escritas como (f x y z ...) donde f es una función y +;;; x, y, z, ... son los argumentos. + +(+ 1 2) ; => 3 + +;;; Si deseas crear datos literales use QUOTE para prevenir que estos sean evaluados + +(quote (+ 1 2)) ; => (+ 1 2) +(quote a) ; => A + +;;; La notación abreviada para QUOTE es ' + +'(+ 1 2) ; => (+ 1 2) +'a ; => A + +;;; Operaciones aritméticas básicas + +(+ 1 1) ; => 2 +(- 8 1) ; => 7 +(* 10 2) ; => 20 +(expt 2 3) ; => 8 +(mod 5 2) ; => 1 +(/ 35 5) ; => 7 +(/ 1 3) ; => 1/3 +(+ #C(1 2) #C(6 -4)) ; => #C(7 -2) + +;;; Boleanos + +t ; true; cualquier valor non-NIL es true +nil ; false; también, la lista vacia: () +(not nil) ; => T +(and 0 t) ; => T +(or 0 nil) ; => 0 + +;;; Caracteres + +#\A ; => #\A +#\λ ; => #\GREEK_SMALL_LETTER_LAMDA +#\u03BB ; => #\GREEK_SMALL_LETTER_LAMDA + +;;; Cadenas son arreglos de caracteres de longitud fija + +"Hello, world!" +"Benjamin \"Bugsy\" Siegel" ; la barra invertida es un carácter de escape + +;;; Las cadenas pueden ser concatenadas + +(concatenate 'string "Hello, " "world!") ; => "Hello, world!" + +;;; Una cadena puede ser tratada como una secuencia de caracteres + +(elt "Apple" 0) ; => #\A + +;;; FORMAT es usado para crear salidas formateadas, va desde simple interpolación de cadenas +;;; hasta bucles y condicionales. El primer argumento de FORMAT determina donde irá la cadena +;;; formateada. Si este es NIL, FORMAT simplemente retorna la cadena formateada como un valor; +;;; si es T, FORMAT imprime a la salida estándar, usualmente la pantalla, luego este retorna NIL. + +(format nil "~A, ~A!" "Hello" "world") ; => "Hello, world!" +(format t "~A, ~A!" "Hello" "world") ; => NIL + + +;;;----------------------------------------------------------------------------- +;;; 2. Variables +;;;----------------------------------------------------------------------------- + +;;; Puedes crear una variable global (ámbito dinámico) usando DEFVAR y DEFPARAMETER +;;; el nombre de la variable puede usar cualquier carácter excepto: ()",'`;#|\ + +;;; La diferencia entre DEFVAR y DEFPARAMETER es que reevaluando una expresión +;;; DEFVAR no cambia el valor de la variable. DEFPARAMETER, por otro lado sí lo hace. + +;;; Por convención, variables de ámbito dinámico tienen "orejeras" en sus nombres. + +(defparameter *some-var* 5) +*some-var* ; => 5 + +;;; Puedes usar también caracteres unicode. +(defparameter *AΛB* nil) + +;;; Accediendo a una variable sin asignar tienen como resultado el error +;;; UNBOUND-VARIABLE, sin embargo este es el comportamiento definido. no lo hagas + +;;; puedes crear enlaces locales con LET. en el siguiente código, `me` es asignado +;;; con "dance with you" solo dentro de (let ...). LET siempre retorna el valor +;;; del último `form`. + +(let ((me "dance with you")) me) ; => "dance with you" + + +;;;-----------------------------------------------------------------------------; +;;; 3. Estructuras y colecciones +;;;-----------------------------------------------------------------------------; + + +;;; Estructuras + +(defstruct dog name breed age) +(defparameter *rover* + (make-dog :name "rover" + :breed "collie" + :age 5)) +*rover* ; => #S(DOG :NAME "rover" :BREED "collie" :AGE 5) +(dog-p *rover*) ; => T +(dog-name *rover*) ; => "rover" + +;;; DOG-P, MAKE-DOG, y DOG-NAME son creados automáticamente por DEFSTRUCT + + +;;; Pares + +;;; CONS crea pares. CAR y CDR retornan la cabeza y la cola de un CONS-pair + +(cons 'SUBJECT 'VERB) ; => '(SUBJECT . VERB) +(car (cons 'SUBJECT 'VERB)) ; => SUBJECT +(cdr (cons 'SUBJECT 'VERB)) ; => VERB + + +;;; Listas + +;;; Listas son estructuras de datos de listas enlazadas, hechas de pares CONS y terminan con un +;;; NIL (o '()) para marcar el final de la lista + +(cons 1 (cons 2 (cons 3 nil))) ; => '(1 2 3) + +;;; LIST es una forma conveniente de crear listas + +(list 1 2 3) ; => '(1 2 3) + +;;; Cuando el primer argumento de CONS es un atom y el segundo argumento es una lista, +;;; CONS retorna un nuevo par CONS con el primer argumento como el primer elemento y el +;;; segundo argumento como el resto del par CONS + +(cons 4 '(1 2 3)) ; => '(4 1 2 3) + +;;; Use APPEND para unir listas + +(append '(1 2) '(3 4)) ; => '(1 2 3 4) + +;;; o CONCATENATE + +(concatenate 'list '(1 2) '(3 4)) ; => '(1 2 3 4) + +;;; las listas son un tipo de datos centrales en CL, por lo tanto hay una gran variedad +;;; de funcionalidades para ellas, algunos ejemplos son: + +(mapcar #'1+ '(1 2 3)) ; => '(2 3 4) +(mapcar #'+ '(1 2 3) '(10 20 30)) ; => '(11 22 33) +(remove-if-not #'evenp '(1 2 3 4)) ; => '(2 4) +(every #'evenp '(1 2 3 4)) ; => NIL +(some #'oddp '(1 2 3 4)) ; => T +(butlast '(subject verb object)) ; => (SUBJECT VERB) + + +;;; Vectores + +;;; Vectores literales son arreglos de longitud fija + +#(1 2 3) ; => #(1 2 3) + +;;; Use CONCATENATE para juntar vectores + +(concatenate 'vector #(1 2 3) #(4 5 6)) ; => #(1 2 3 4 5 6) + + +;;; Arreglos + +;;; Vectores y cadenas son casos especiales de arreglos. + +;;; Arreglos bidimensionales + +(make-array (list 2 2)) ; => #2A((0 0) (0 0)) +(make-array '(2 2)) ; => #2A((0 0) (0 0)) +(make-array (list 2 2 2)) ; => #3A(((0 0) (0 0)) ((0 0) (0 0))) + +;;; Precaución: los valores iniciales por defecto de MAKE-ARRAY son implementaciones definidas +;;; para definirlos explícitamente: + +(make-array '(2) :initial-element 'unset) ; => #(UNSET UNSET) + +;;; Para acceder al elemento en 1, 1, 1: + +(aref (make-array (list 2 2 2)) 1 1 1) ; => 0 + +;;; Este valor es definido por implementación: +;;; NIL en ECL, 0 en SBCL and CCL. + +;;; vectores ajustables + +;;; los vectores ajustables tienen la misma representación en la impresión como los vectores literales +;;; de longitud fija. + +(defparameter *adjvec* (make-array '(3) :initial-contents '(1 2 3) + :adjustable t :fill-pointer t)) +*adjvec* ; => #(1 2 3) + +;;; Agregando nuevos elementos + +(vector-push-extend 4 *adjvec*) ; => 3 +*adjvec* ; => #(1 2 3 4) + + +;;; Conjuntos, ingenuamente son listas: + +(set-difference '(1 2 3 4) '(4 5 6 7)) ; => (3 2 1) +(intersection '(1 2 3 4) '(4 5 6 7)) ; => 4 +(union '(1 2 3 4) '(4 5 6 7)) ; => (3 2 1 4 5 6 7) +(adjoin 4 '(1 2 3 4)) ; => (1 2 3 4) + +;;; Sin embargo, necesitarás una mejor estructura de datos que listas enlazadas +;;; cuando trabajes con conjuntos de datos grandes + +;;; Los Diccionarios son implementados como tablas hash. + +;;; Crear tablas hash + +(defparameter *m* (make-hash-table)) + +;;; definir valor + +(setf (gethash 'a *m*) 1) + +;;; obtener valor + +(gethash 'a *m*) ; => 1, T + +;;; las expresiones en CL tienen la facultad de retornar multiples valores. + +(values 1 2) ; => 1, 2 + +;;; los cuales pueden ser asignados con MULTIPLE-VALUE-BIND + +(multiple-value-bind (x y) + (values 1 2) + (list y x)) + +; => '(2 1) + +;;; GETHASH es un ejemplo de una función que retorna multiples valores. El primer +;;; valor es el valor de la llave en la tabla hash: si la llave no existe retorna NIL. + +;;; El segundo valor determina si la llave existe en la tabla hash. si la llave no existe +;;; en la tabla hash retorna NIL. Este comportamiento permite verificar si el valor de una +;;; llave es actualmente NIL. + +;;; Obteniendo un valor no existente retorna NIL + +(gethash 'd *m*) ;=> NIL, NIL + +;;; Puedes declarar un valor por defecto para las llaves inexistentes + +(gethash 'd *m* :not-found) ; => :NOT-FOUND + +;;; Vamos a manejar los multiples valores de retornno en el código. + +(multiple-value-bind (a b) + (gethash 'd *m*) + (list a b)) +; => (NIL NIL) + +(multiple-value-bind (a b) + (gethash 'a *m*) + (list a b)) +; => (1 T) + + +;;;----------------------------------------------------------------------------- +;;; 3. Funciones +;;;----------------------------------------------------------------------------- + +;;; Use LAMBDA para crear funciones anónimas. las funciones siempre retornan el valor +;;; de la última expresión. la representación imprimible de una función varia entre +;;; implementaciones. + +(lambda () "Hello World") ; => #<FUNCTION (LAMBDA ()) {1004E7818B}> + +;;; Use FUNCALL para llamar funciones anónimas. + +(funcall (lambda () "Hello World")) ; => "Hello World" +(funcall #'+ 1 2 3) ; => 6 + +;;; Un llamado a FUNCALL es también realizado cuando la expresión lambda es el CAR de +;;; una lista. + +((lambda () "Hello World")) ; => "Hello World" +((lambda (val) val) "Hello World") ; => "Hello World" + +;;; FUNCALL es usado cuando los argumentos son conocidos de antemano. +;;; de lo contrario use APPLY + +(apply #'+ '(1 2 3)) ; => 6 +(apply (lambda () "Hello World") nil) ; => "Hello World" + +;;; Para nombrar una funcion use DEFUN + +(defun hello-world () "Hello World") +(hello-world) ; => "Hello World" + +;;; Los () en la definición anterior son la lista de argumentos + +(defun hello (name) (format nil "Hello, ~A" name)) +(hello "Steve") ; => "Hello, Steve" + +;;; las functiones pueden tener argumentos opcionales; por defecto son NIL + +(defun hello (name &optional from) + (if from + (format t "Hello, ~A, from ~A" name from) + (format t "Hello, ~A" name))) + +(hello "Jim" "Alpacas") ; => Hello, Jim, from Alpacas + +;;; Los valores por defecto pueden ser especificados + + +(defun hello (name &optional (from "The world")) + (format nil "Hello, ~A, from ~A" name from)) + +(hello "Steve") ; => Hello, Steve, from The world +(hello "Steve" "the alpacas") ; => Hello, Steve, from the alpacas + +;;; Las funciones también tienen argumentos llaves para permitir argumentos no positionados + +(defun generalized-greeter (name &key (from "the world") (honorific "Mx")) + (format t "Hello, ~A ~A, from ~A" honorific name from)) + +(generalized-greeter "Jim") +; => Hello, Mx Jim, from the world + +(generalized-greeter "Jim" :from "the alpacas you met last summer" :honorific "Mr") +; => Hello, Mr Jim, from the alpacas you met last summer + + +;;;----------------------------------------------------------------------------- +;;; 4. Igualdad +;;;----------------------------------------------------------------------------- + +;;; CL tiene un sistema sofisticado de igualdad. Una parte es tratada aquí. + +;;; Para números use `=` +(= 3 3.0) ; => T +(= 2 1) ; => NIL + +;;; Para identidad de objetos (aproximadamente) use EQL +(eql 3 3) ; => T +(eql 3 3.0) ; => NIL +(eql (list 3) (list 3)) ; => NIL + +;;; para listas, cadenas y bit vectores use EQUAL +(equal (list 'a 'b) (list 'a 'b)) ; => T +(equal (list 'a 'b) (list 'b 'a)) ; => NIL + + +;;;----------------------------------------------------------------------------- +;;; 5. Control de flujo +;;;----------------------------------------------------------------------------- + +;;; Condicionales + +(if t ; testar expresión + "this is true" ; then expression + "this is false") ; else expression +; => "this is true" + +;;; En condicionales, todo valor non-NIL es tratado como true + +(member 'Groucho '(Harpo Groucho Zeppo)) ; => '(GROUCHO ZEPPO) +(if (member 'Groucho '(Harpo Groucho Zeppo)) + 'yep + 'nope) +; => 'YEP + +;;; COND en cadena una serie de pruebas para seleccionar un resultado +(cond ((> 2 2) (error "wrong!")) + ((< 2 2) (error "wrong again!")) + (t 'ok)) ; => 'OK + +;;; TYPECASE evalua sobre el tipo del valor +(typecase 1 + (string :string) + (integer :int)) +; => :int + + +;;; Bucles + +;;; Recursión + +(defun fact (n) + (if (< n 2) + 1 + (* n (fact(- n 1))))) + +(fact 5) ; => 120 + +;;; Iteración + +(defun fact (n) + (loop :for result = 1 :then (* result i) + :for i :from 2 :to n + :finally (return result))) + +(fact 5) ; => 120 + +(loop :for x :across "abcd" :collect x) +; => (#\a #\b #\c #\d) + +(dolist (i '(1 2 3 4)) + (format t "~A" i)) +; => 1234 + + +;;;----------------------------------------------------------------------------- +;;; 6. Mutación +;;;----------------------------------------------------------------------------- + +;;; use SETF para asignar un valor nuevo a una variable existente. Esto fue demostrado +;;; previamente en el ejemplo de la tabla hash. + +(let ((variable 10)) + (setf variable 2)) +; => 2 + +;;; Un estilo bueno de lisp es minimizar el uso de funciones destructivas y prevenir +;;; la mutación cuando sea posible. + + +;;;----------------------------------------------------------------------------- +;;; 7. Clases y objetos +;;;----------------------------------------------------------------------------- + +;;; No más clases de animales, tengamos transportes mecánicos impulsados por el humano + +(defclass human-powered-conveyance () + ((velocity + :accessor velocity + :initarg :velocity) + (average-efficiency + :accessor average-efficiency + :initarg :average-efficiency)) + (:documentation "A human powered conveyance")) + +;;; Los argumentos de DEFCLASS, en orden son: +;;; 1. nombre de la clase +;;; 2. lista de superclases +;;; 3. slot list +;;; 4. Especificadores opcionales + +;;; cuando no hay lista de superclase, la lista vacia indica clase de +;;; objeto estándar, esto puede ser cambiado, pero no mientras no sepas +;;; lo que estas haciendo. revisar el arte del protocolo de meta-objetos +;;; para más información. + +(defclass bicycle (human-powered-conveyance) + ((wheel-size + :accessor wheel-size + :initarg :wheel-size + :documentation "Diameter of the wheel.") + (height + :accessor height + :initarg :height))) + +(defclass recumbent (bicycle) + ((chain-type + :accessor chain-type + :initarg :chain-type))) + +(defclass unicycle (human-powered-conveyance) nil) + +(defclass canoe (human-powered-conveyance) + ((number-of-rowers + :accessor number-of-rowers + :initarg :number-of-rowers))) + +;;; Invocando DESCRIBE en la clase HUMAN-POWERED-CONVEYANCE en REPL obtenemos: + +(describe 'human-powered-conveyance) + +; COMMON-LISP-USER::HUMAN-POWERED-CONVEYANCE +; [symbol] +; +; HUMAN-POWERED-CONVEYANCE names the standard-class #<STANDARD-CLASS +; HUMAN-POWERED-CONVEYANCE>: +; Documentation: +; A human powered conveyance +; Direct superclasses: STANDARD-OBJECT +; Direct subclasses: UNICYCLE, BICYCLE, CANOE +; Not yet finalized. +; Direct slots: +; VELOCITY +; Readers: VELOCITY +; Writers: (SETF VELOCITY) +; AVERAGE-EFFICIENCY +; Readers: AVERAGE-EFFICIENCY +; Writers: (SETF AVERAGE-EFFICIENCY) + +;;; Tenga en cuenta el comportamiento reflexivo disponible. CL fue diseñado +;;; para ser un systema interactivo + +;;; para definir un método, encontremos la circunferencia de la rueda usando +;;; la ecuación C = d * pi + +(defmethod circumference ((object bicycle)) + (* pi (wheel-size object))) + +;;; PI es definido internamente en CL + +;;; Supongamos que descubrimos que el valor de eficiencia del número de remeros +;;; en una canoa es aproximadamente logarítmico. Esto probablemente debería +;;; establecerse en el constructor / inicializador. + +;;; Para inicializar su instancia después de que CL termine de construirla: + +(defmethod initialize-instance :after ((object canoe) &rest args) + (setf (average-efficiency object) (log (1+ (number-of-rowers object))))) + +;;; luego para construir una instancia y revisar la eficiencia promedio + +(average-efficiency (make-instance 'canoe :number-of-rowers 15)) +; => 2.7725887 + + +;;;----------------------------------------------------------------------------- +;;; 8. Macros +;;;----------------------------------------------------------------------------- + +;;; las Macros le permiten extender la sintaxis del lenguaje, CL no viene con +;;; un bucle WHILE, por lo tanto es facil escribirlo, Si obedecemos nuestros +;;; instintos de ensamblador, terminamos con: + +(defmacro while (condition &body body) + "While `condition` is true, `body` is executed. +`condition` is tested prior to each execution of `body`" + (let ((block-name (gensym)) (done (gensym))) + `(tagbody + ,block-name + (unless ,condition + (go ,done)) + (progn + ,@body) + (go ,block-name) + ,done))) + +;;; revisemos la versión de alto nivel para esto: + +(defmacro while (condition &body body) + "While `condition` is true, `body` is executed. +`condition` is tested prior to each execution of `body`" + `(loop while ,condition + do + (progn + ,@body))) + +;;; Sin embargo, con un compilador moderno, esto no es necesario; El LOOP se +;;; compila igualmente bien y es más fácil de leer. + +;;; Tenga en cuenta que se utiliza ```, así como `,` y `@`. ``` es un operador +;;; de tipo de cita conocido como quasiquote; permite el uso de `,` . `,` permite +;;; variables "entre comillas". @ interpola las listas. + +;;; GENSYM crea un símbolo único que garantiza que no existe en ninguna otra parte +;;; del sistema. Esto se debe a que las macros se expanden en el momento de la compilación +;;; y las variables declaradas en la macro pueden colisionar con las variables utilizadas +;;; en un código regular. + +;;; Consulte Practical Common Lisp y On Lisp para obtener más información sobre macros. +``` + + +## Otras Lecturas + +- [Practical Common Lisp](http://www.gigamonkeys.com/book/) +- [Common Lisp: A Gentle Introduction to Symbolic Computation](https://www.cs.cmu.edu/~dst/LispBook/book.pdf) + + +## Información extra + +- [CLiki](http://www.cliki.net/) +- [common-lisp.net](https://common-lisp.net/) +- [Awesome Common Lisp](https://github.com/CodyReichert/awesome-cl) +- [Lisp Lang](http://lisp-lang.org/) + + +## Creditos + +Muchas Gracias a la gente de Scheme por proveer un gran punto de inicio +el cual puede ser movido fácilmente a Common Lisp + +- [Paul Khuong](https://github.com/pkhuong) para un buen repaso. diff --git a/es-es/kotlin-es.html.markdown b/es-es/kotlin-es.html.markdown index 045f92d1..80d7a4bb 100644 --- a/es-es/kotlin-es.html.markdown +++ b/es-es/kotlin-es.html.markdown @@ -2,6 +2,7 @@ language: kotlin contributors: - ["S Webber", "https://github.com/s-webber"] +- ["Aitor Escolar", "https://github.com/aiescola"] translators: - ["Ivan Alburquerque", "https://github.com/AlburIvan"] lang: es-es @@ -40,6 +41,12 @@ fun main(args: Array<String>) { Podemos declarar explícitamente el tipo de una variable así: */ val foo: Int = 7 + + /* + A diferencia de JavaScript, aunque el tipo se infiera, es tipado, por lo que no se puede cambiar el tipo a posteriori + */ + var fooInt = 14 // Se infiere tipo Int + fooInt = "Cadena" // ERROR en tiempo de compilación: Type mismatch /* Las cadenas pueden ser representadas de la misma manera que Java. @@ -84,7 +91,6 @@ fun main(args: Array<String>) { println(fooNullable?.length) // => null println(fooNullable?.length ?: -1) // => -1 - /* Las funciones pueden ser declaras usando la palabra clave "fun". Los argumentos de las funciones son especificados entre corchetes despues del nombre de la función. @@ -122,6 +128,40 @@ fun main(args: Array<String>) { fun even(x: Int) = x % 2 == 0 println(even(6)) // => true println(even(7)) // => false + + /* + Kotlin permite el uso de lambdas, o funciones anónimas + */ + + // Sin lambda: + interface MyListener { + fun onClick(foo: Foo) + } + + fun listenSomething(listener: MyListener) { + listener.onClick(Foo()) + } + + listenSomething(object: MyListener { + override fun onClick(foo: Foo) { + //... + } + }) + + // Con lambda: + fun listenSomethingLambda(listener: (Foo) -> Unit) { + listener(Foo()) + } + + listenSomethingLambda { + //Se recibe foo + } + + // el operador typealias permite, entre otras cosas, simplificar las expresiones con lambdas + typealias MyLambdaListener = (Foo) -> Unit + fun listenSomethingLambda(listener: MyLambdaListener) { + listener(Foo()) + } // Las funciones pueden tomar funciones como argumentos y // retornar funciones. @@ -219,6 +259,11 @@ fun main(args: Array<String>) { val fooMap = mapOf("a" to 8, "b" to 7, "c" to 9) // Se puede acceder a los valores del mapa por su llave. println(fooMap["a"]) // => 8 + + // Tanto Map como cualquier colección iterable, tienen la función de extensión forEach + fooMap.forEach { + println("${it.key} ${it.value}") + } /* Las secuencias representan colecciones evaluadas diferidamente. @@ -245,7 +290,7 @@ fun main(args: Array<String>) { val y = fibonacciSequence().take(10).toList() println(y) // => [1, 1, 2, 3, 5, 8, 13, 21, 34, 55] - // Kotlin provee funciones de Orden-Mayor para trabajar con colecciones. + // Kotlin provee funciones de orden superior para trabajar con colecciones. val z = (1..9).map {it * 3} .filter {it < 20} .groupBy {it % 2 == 0} @@ -305,17 +350,11 @@ fun main(args: Array<String>) { ese tipo sin convertido de forma explícita. */ fun smartCastExample(x: Any) : Boolean { - if (x is Boolean) { - // x es automaticamente convertido a Boolean - return x - } else if (x is Int) { - // x es automaticamente convertido a Int - return x > 0 - } else if (x is String) { - // x es automaticamente convertido a String - return x.isNotEmpty() - } else { - return false + return when (x) { + is Boolean -> x // x es automaticamente convertido a Boolean + is Int -> x > 0 // x es automaticamente convertido a Int + is String -> x.isNotEmpty() // x es automaticamente convertido a String + else -> false } } println(smartCastExample("Hola, mundo!")) // => true @@ -345,7 +384,8 @@ enum class EnumExample { /* La palabra clave "object" se puede utilizar para crear objetos únicos. No podemos asignarlo a una variable, pero podemos hacer referencia a ella por su nombre. -Esto es similar a los objetos únicos de Scala +Esto es similar a los objetos únicos de Scala. +En la mayoría de ocasiones, los objetos únicos se usan como alternativa a los Singleton. */ object ObjectExample { fun hello() : String { diff --git a/es-es/python-es.html.markdown b/es-es/python-es.html.markdown index a27203d1..2b8f498a 100644 --- a/es-es/python-es.html.markdown +++ b/es-es/python-es.html.markdown @@ -467,7 +467,7 @@ Humano.roncar() #=> "*roncar*" # Puedes importar módulos import math -print math.sqrt(16) #=> 4 +print math.sqrt(16) #=> 4.0 # Puedes obtener funciones específicas desde un módulo from math import ceil, floor diff --git a/es-es/pythonstatcomp-es.html.markdown b/es-es/pythonstatcomp-es.html.markdown index 0130b72a..b3d2f0ff 100644 --- a/es-es/pythonstatcomp-es.html.markdown +++ b/es-es/pythonstatcomp-es.html.markdown @@ -1,5 +1,6 @@ --- -language: Statistical computing with Python +category: tool +tool: Statistical Computing with Python contributors: - ["e99n09", "https://github.com/e99n09"] filename: pythonstatcomp-es.py diff --git a/es-es/visualbasic-es.html.markdown b/es-es/visualbasic-es.html.markdown index ca00626b..c677c20f 100644 --- a/es-es/visualbasic-es.html.markdown +++ b/es-es/visualbasic-es.html.markdown @@ -4,8 +4,6 @@ contributors: - ["Brian Martin", "http://brianmartin.biz"] translators: - ["Adolfo Jayme Barrientos", "https://github.com/fitojb"] -author: Brian Martin -author_url: https://github.com/fitojb filename: learnvisualbasic-es.vb lang: es-es --- diff --git a/fr-fr/awk-fr.html.markdown b/fr-fr/awk-fr.html.markdown new file mode 100644 index 00000000..75c48811 --- /dev/null +++ b/fr-fr/awk-fr.html.markdown @@ -0,0 +1,377 @@ +--- +category: tool +tool: awk +filename: learnawk-fr.awk +contributors: + - ["Marshall Mason", "http://github.com/marshallmason"] +translators: + - ["GannonTdW", "https://github.com/GannonTdW"] +lang: fr-fr + +--- + +AWK est un outil standard présent dans chaque système UNIX conforme aux normes POSIX. +C’est un outil en ligne de commande qui ressemble au Perl et qui est excellent dans les tâches de traitement de fichiers texte. +Vous pouvez l’appeler à partir d’un script shell, ou l’utiliser comme un langage de script autonome. + +Pourquoi utiliser AWK au lieu du langage Perl ? +Principalement, car AWK fait partie d'UNIX et est donc présent par défaut sur une très grande partie des systèmes d'exploitation UNIX et Linux. +AWK est aussi plus facile à lire que le langage Perl ; et est l'outil idéal pour ce qui concerne le traitement de texte simple. Notamment le traitement de ceux qui necéssitent de lire des fichiers ligne par ligne ; chaque ligne comportant des champs séparés par des délimiteur. + + +```awk +#!/usr/bin/awk -f + +# Les commentaires commencent par un # + + +# les programmes AWK consistent en une collection de règles et d'actions +règle1 { action; } +règle2 { action; } + +# AWK lit et analyse automatiquement chaque ligne de chaque fichier fourni. +# Chaque ligne est divisée par un délimiteur FS qui est par défaut l'espace (plusieurs espaces ou une tabulation comptent pour un espace). Ce délimiteur peut être changer grâce à l'option -F ou être renseigné au début d'un bloc (exemple: FS = " "). + +# BEGIN est une règle spécifique exécutée au début du programme. C'est à cet endroit que vous mettrez tout le code à exécuter avant de traiter les fichiers texte. Si vous ne disposez pas de fichiers texte, considérez BEGIN comme le point d’entrée principal du script. +# A l'opposé de BEGIN, il existe la règle END. Cette règle est présente après chaque fin de fichier (EOF : End Of File). + +BEGIN { + + # Les variables sont globales. Pas besoin de les déclarer. + count = 0; + + # les opérateurs sont identiques au langage C et aux langages similaires (exemple: C#, C++) + a = count + 1; # addition + b = count - 1; # soustraction + c = count * 1; # multiplication + d = count / 1; # division entière + e = count % 1; # modulo, reste de la division entière + f = count ^ 1; # exponentiel + + a += 1; + b -= 1; + c *= 1; + d /= 1; + e %= 1; + f ^= 1; + + # Incrémenter et décrémenter par un + a++; + b--; + + # En tant qu'opérateur préfixé, c'est la valeur incrémentée qui est retournée + ++a; + --b; + + # Instruction de contrôle + if (conteur == 0) + print "Nombre de départ 0"; + else + print "Hein?"; + + # Vous pouvez aussi utiliser l'opérateur ternaire + print (compteur == 0) ? "Nombre de départ 0" : "Hein?"; + + # Les blocs sont composés d'une multitude de lignes entre accolades + while (a < 10) { + print "La concaténation de chaînes de caractères" " se fait avec des séries de chaînes " " séparées par des espaces"; + print a; + + a++; + } + + for (i = 0; i < 10; i++) + print "le bon vieux for pour les boucles"; + + # Les opérateurs de comparaison sont standard + # a < b # plus petit que + # a <= b # plus petit ou égale à + # a != b # non égale + # a == b # égale + # a > b # Plus grand que + # a >= b # Plus grand ou égale à + + # Les opérateurs logiques sont + # a && b # ET + # a || b # OU + + # En plus, il y a les expressions régulières + if ("foo" ~ "^fo+$") + print "Fooey!"; + if ("boo" !~ "^fo+$") + print "Boo!"; + + # Les Tableaux + arr[0] = "foo"; + arr[1] = "bar"; + + # Vous pouvez aussi initialiser un tableau avec la fonction split() + + n = split("foo:bar:baz", arr, ":"); + + # Il y a aussi les tableaux associatifs + assoc["foo"] = "bar"; + assoc["bar"] = "baz"; + + # et les tableaux multi-dimentions, avec certaines limitations que l'on ne mentionnera pas ici + multidim[0,0] = "foo"; + multidim[0,1] = "bar"; + multidim[1,0] = "baz"; + multidim[1,1] = "boo"; + + # Vous pouvez tester l'appartenance à un tableau + if ("foo" in assoc) + print "Fooey!"; + + # Vous pouvez aussi utilisez l'opérateur 'in' pour parcourir les clés d'un tableau + for (key in assoc) + print assoc[key]; + + # La ligne de commande est dans un tableau spécifique appelé ARGV + for (argnum in ARGV) + print ARGV[argnum]; + + # Vous pouvez supprimer des éléments d'un tableau + # C'est utile pour empêcher AWK de supposer que certains arguments soient des fichiers à traiter. + delete ARGV[1]; + + # Le nombre d'arguments de la ligne de commande est dans une variable appellée ARGC + print ARGC; + + # AWK inclue trois catégories de fonction. + # On les examinera plus tard + + return_value = arithmetic_functions(a, b, c); + string_functions(); + io_functions(); +} + +# Voici comment définir une fonction +function arithmetic_functions(a, b, c, d) { + + # La partie la plus ennuieuse de AWK est probablement l’absence de variables locales. + # Tout est global. Pour les scripts courts, c'est très utile, mais pour les scripts plus longs, + # cela peut poser problème. + + # Il y a cepandant une solution de contournement (enfin ... une bidouille). + # Les arguments d'une fonction sont locaux à cette fonction. + # Et AWK vous permet de définir plus d'arguments à la fonction que nécessaire. + # Il suffit donc de mettre une variable locale dans la déclaration de fonction, + # comme ci-dessus. La convention veut que vous mettiez quelques espaces supplémentaires + # pour faire la distinction entre les paramètres réels et les variables locales. + # Dans cet exemple, a, b et c sont des paramètres réels, + # alors que d est simplement une variable locale. + + # Maintenant, les fonctions arithmétiques + + # La plupart des implémentations de AWK ont des fonctions trigonométriques standards + localvar = sin(a); + localvar = cos(a); + localvar = atan2(b, a); # arc tangente de b / a + + # Les exponentiels et logarithmes décimaux sont aussi là + localvar = exp(a); + localvar = log(a); + + # Les racines carrées + localvar = sqrt(a); + + # Tronquer un nombre décimal en nombre entier + localvar = int(5.34); # localvar => 5 + + # Les nombres aléatoires + srand(); + # L'argument de la fonction srand() est la valeur de départ pour générer + # les nombres aléatoires . Par défaut, il utilise l'heure du système + + localvar = rand(); # Nombre aléatoire entre 0 et 1. + + # Maintenant on retourne la valeur + return localvar; +} + +function string_functions( localvar, arr) { + + # AWK a plusieurs fonctions pour le traitement des chaînes de caractères, + # dont beaucoup reposent sur des expressions régulières. + + # Chercher et remplacer, la première occurence (sub) ou toutes les occurences (gsub) + # Les deux renvoient le nombre de correspondances remplacées + 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" + + # Rechercher une chaîne de caractères qui correspond à une expression régulière + # index() fait la même chose, mais n'autorise pas les expressions régulières + match(localvar, "t"); # => 4, puisque 't' est le quatrième caractère + + # Séparer par un délimiteur + n = split("foo-bar-baz", arr, "-"); # a[1] = "foo"; a[2] = "bar"; a[3] = "baz"; n = 3 + + # Autre astuces utiles + 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) { + + # Vous avez déjà vu print + print "Hello world"; + + # Mais il y a aussi printf + printf("%s %d %d %d\n", "Testing", 1, 2, 3); + + # AWK n'a pas de descripteur de fichier en soi. Il ouvrira automatiquement + # un descripteur de fichier lorsque vous utilisez quelque chose qui en a besoin. + # La chaîne de caractères que vous avez utilisée pour cela peut être traitée + # comme un descripteur de fichier à des fins d'entrée / sortie. + + outfile = "/tmp/foobar.txt"; + + print "foobar" > outfile; + + # Maintenant, la chaîne de caractères "outfile" est un descripteur de fichier. + # Vous pouvez le fermer + close(outfile); + + # Voici comment exécuter quelque chose dans le shell + system("echo foobar"); # => affiche foobar + + # Lire quelque chose depuis l'entrée standard et la stocker dans une variable locale + getline localvar; + + # Lire quelque chose à partir d'un pipe (encore une fois, utilisez une chaine de caractère + # que vous fermerez proprement) + "echo foobar" | getline localvar # localvar => "foobar" + close("echo foobar") + + # Lire une ligne d'un fichier et la stocker dans une variable locale + infile = "/tmp/foobar.txt"; + getline localvar < infile; + close(infile); +} + +# Comme dit au début, AWK consiste en une collection de règles et d'actions. +# Vous connaissez déjà les règles BEGIN et END. Les autres règles ne sont utilisées que si vous traitez +# des lignes à partir de fichiers ou l'entrée standard (stdin). +# Quand vous passez des arguments à AWK, ils sont considérés comme des noms de fichiers à traiter. +# AWK les traitera tous dans l'ordre. Voyez les comme dans à une boucle implicite, +# parcourant les lignes de ces fichiers. +# Ces règles et ces actions ressemblent à des instructions switch dans la boucle. + +/^fo+bar$/ { + + # Cette action sera exécutée pour chaque ligne qui correspond à l'expression régulière, + # /^fo+bar$/, et sera ignorée pour toute ligne qui n'y correspond pas. + # Imprimons simplement la ligne: + + print; + + # Pas d'argument ! C'est parce que print a un défaut : $0. + # $0 est le nom de la ligne en cours de traitement. Il est créé automatiquement. + + # Vous devinez probablement qu'il existe d'autres variables $. + # Chaque ligne est divisée implicitement avant que chaque action soit exécutée, comme + # le fait le shell. Et, comme le shell, chaque champ est accessible avec un signe dollar + + # Ceci affichera les deuxième et quatrième champs de la ligne. + print $2, $4; + + # AWK défini automatiquement beaucoup d'autres variables qui peuvent vous aider + # à inspecter et traiter chaque ligne. La plus importante est NF + + # Affiche le nombre de champs de la ligne + print NF; + + # Afficher le dernier champ de la ligne + print $NF; +} + +# Chaque règle est en réalité un test conditionel. + +a > 0 { + # Ceci s’exécutera une fois pour chaque ligne, tant que le test est positif +} + +# Les expressions régulières sont également des tests conditionels. +#Si le test de l'expression régulières n'est pas vrais alors le bloc n'est pas executé +$0 /^fobar/ { + print "la ligne commance par fobar" +} + +# Dans le cas où vous voulez tester votre chaine de caractères sur la ligne en cours de traitement +# $0 est optionnelle. + +/^[a-zA-Z0-9]$/ { + print "La ligne courante ne contient que des caractères alphanumériques."; +} + + +# AWK peut parcourir un fichier texte ligne par ligne et exécuter des actions en fonction de règles établies +# Cela est si courant sous UNIX qu'AWK est un langage de script. + +# Ce qui suit est un exemple rapide d'un petit script, pour lequel AWK est parfait. +# Le script lit un nom à partir de l'entrée standard, puis affiche l'âge moyen de toutes les +# personnes portant ce prénom. +# Supposons que vous fournissiez comme argument le nom d'un fichier comportant ces données: +# +# Bob Jones 32 +# Jane Doe 22 +# Steve Stevens 83 +# Bob Smith 29 +# Bob Barker 72 +# +# Le script est le suivant : + +BEGIN { + + # Premièrement, on demande à l'utilisateur le prénom voulu + print "Pour quel prénom vouldriez vous savoir l'age moyen ?"; + + # On récupère la ligne à partir de l'entrée standard, pas de la ligne de commande + getline name < "/dev/stdin"; +} + +# Maintenant, pour chaque ligne dont le premier champ est le prénom donné +$1 == name { + + # Ici, nous avons accès à un certain nombre de variables utiles déjà préchargées : + # $0 est la ligne entière + # $3 est le troisième champ. Ici il correspond à l'age qui nous intéresse + # NF est le nombre de champs et vaut 3 + # NR est le nombre d'enregistrements (lignes) vus jusqu'à présent + # FILENAME est le nom du fichier en cours de traitement + # FS est séparateur de champs, ici c'est " " (un espace) + # ...etc. Et beaucoup d'autre que vous pouvez connaître dans le manuel de man. + # Pour cela exécutez "man awk" dans votre terminal + + # Garder une trace du total accumulé et du nombre de lignes correspondant. + sum += $3; + nlines++; +} + +# Un autre motif spécial est END. Il fonctionnera après le traitement de tous +# les fichiers texte. Contrairement à BEGIN, il ne fonctionne que si vous lui +# donnez une entrée à traiter. Il sera exécuté une fois que tous les fichiers +# auront été lus et traités conformément aux règles et aux actions que vous +# avez fournies. Le but est généralement de produire un rapport final +# ou de faire quelque chose avec l'ensemble des données que vous avez +# accumulées au cours du script. + + +END { + if (nlines) + print "L'age moyen pour le prénom " name " est " sum / nlines; +} + +``` +Pour plus d'informations : + +* [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 est dans la majorité des systèmes Linux. +* [AWK one-liner collection](http://tuxgraphics.org/~guido/scripts/awk-one-liner.html) diff --git a/fr-fr/erlang-fr.html.markdown b/fr-fr/erlang-fr.html.markdown index 55453c56..1073d6ad 100644 --- a/fr-fr/erlang-fr.html.markdown +++ b/fr-fr/erlang-fr.html.markdown @@ -28,7 +28,7 @@ lang: fr-fr %% 1. Variables et filtrage par motif %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -(L'équivalent anglais de *filtrage par motif* est *pattern patching*.) +(L'équivalent anglais de *filtrage par motif* est *pattern matching*.) Nb = 42. % Chaque nom de variable doit commencer par une lettre majuscule. @@ -64,7 +64,7 @@ Point = {point, 10, 45}. {point, X, Y} = Point. % X = 10, Y = 45 % On peut utiliser `_` comme caractère joker pour les variables qui ne nous -% intéressent pas. Le symbol `_` est appelé variable muette. Contrairement +% intéressent pas. Le symbole `_` est appelé variable muette. Contrairement % aux variables normales, de multiples apparitions de `_` dans un même motif % ne lient pas nécessairement à la même valeur. Personne = {personne, {nom, {prenom, joe}, {famille, armstrong}}, diff --git a/fr-fr/make-fr.html.markdown b/fr-fr/make-fr.html.markdown index 48d24549..7b4864b5 100644 --- a/fr-fr/make-fr.html.markdown +++ b/fr-fr/make-fr.html.markdown @@ -1,5 +1,6 @@ --- -language: make +category: tool +tool: make contributors: - ["Robert Steed", "https://github.com/robochat"] translators: diff --git a/fr-fr/markdown-fr.html.markdown b/fr-fr/markdown-fr.html.markdown index b3b7de85..26c2546a 100644 --- a/fr-fr/markdown-fr.html.markdown +++ b/fr-fr/markdown-fr.html.markdown @@ -350,7 +350,7 @@ ne sont pas tres agréable d'utilisation. Mais si vous en avez besoin : ```md | Col1 | Col2 | Col3 | | :----------- | :------: | ------------: | -| Alignement Gauche | Centé | Alignement Droite | +| Alignement Gauche | Centré | Alignement Droite | | bla | bla | bla | ``` diff --git a/fr-fr/python-fr.html.markdown b/fr-fr/python-fr.html.markdown index d78291be..0ae410de 100644 --- a/fr-fr/python-fr.html.markdown +++ b/fr-fr/python-fr.html.markdown @@ -444,7 +444,7 @@ Human.grunt() #=> "*grunt*" # On peut importer des modules import math -print math.sqrt(16) #=> 4 +print math.sqrt(16) #=> 4.0 # Et récupérer des fonctions spécifiques d'un module from math import ceil, floor diff --git a/fsharp.html.markdown b/fsharp.html.markdown index 59461eed..24044d76 100644 --- a/fsharp.html.markdown +++ b/fsharp.html.markdown @@ -194,7 +194,7 @@ module ListExamples = | [] -> printfn "the list is empty" | [first] -> printfn "the list has one element %A " first | [first; second] -> printfn "list is %A and %A" first second - | _ -> printfn "the list has more than two elements" + | first :: _ -> printfn "the list has more than two elements, first element %A" first listMatcher [1; 2; 3; 4] listMatcher [1; 2] diff --git a/haxe.html.markdown b/haxe.html.markdown index afb9d1a3..a31728e1 100644 --- a/haxe.html.markdown +++ b/haxe.html.markdown @@ -7,17 +7,18 @@ contributors: --- Haxe is a web-oriented language that provides platform support for C++, C#, -Swf/ActionScript, Javascript, Java, and Neko byte code (also written by the -Haxe author). Note that this guide is for Haxe version 3. Some of the guide -may be applicable to older versions, but it is recommended to use other -references. +Swf/ActionScript, Javascript, Java, PHP, Python, Lua, HashLink, and Neko byte code +(the latter two being also written by the Haxe author). Note that this guide is for +Haxe version 3. Some of the guide may be applicable to older versions, but it is +recommended to use other references. ```csharp /* Welcome to Learn Haxe 3 in 15 minutes. http://www.haxe.org This is an executable tutorial. You can compile and run it using the haxe compiler, while in the same directory as LearnHaxe.hx: - $> haxe -main LearnHaxe3 -x out + + $ haxe -main LearnHaxe3 --interp Look for the slash-star marks surrounding these paragraphs. We are inside a "Multiline comment". We can leave some notes here that will get ignored @@ -26,16 +27,14 @@ references. Multiline comments are also used to generate javadoc-style documentation for haxedoc. They will be used for haxedoc if they immediately precede a class, class function, or class variable. - */ -// Double slashes like this will give a single-line comment - +// Double slashes like this will give a single-line comment. /* This is your first actual haxe code coming up, it's declaring an empty - package. A package isn't necessary, but it's useful if you want to create a - namespace for your code (e.g. org.yourapp.ClassName). + package. A package isn't necessary, but it's useful if you want to create + a namespace for your code (e.g. org.yourapp.ClassName). Omitting package declaration is the same as declaring an empty package. */ @@ -47,8 +46,9 @@ package; // empty package, no namespace. must be lower case while module names are capitalized. A module contain one or more types whose names are also capitalized. - E.g, the class "org.yourapp.Foo" should have the folder structure org/module/Foo.hx, - as accessible from the compiler's working directory or class path. + E.g, the class "org.yourapp.Foo" should have the folder structure + org/module/Foo.hx, as accessible from the compiler's working directory or + class path. If you import code from other files, it must be declared before the rest of the code. Haxe provides a lot of common default classes to get you started: @@ -64,34 +64,27 @@ import Lambda.array; // you can also use "*" to import all static fields import Math.*; -/* - You can also import classes in a special way, enabling them to extend the - functionality of other classes like a "mixin". More on 'using' later. - */ +// You can also import classes in a special way, enabling them to extend the +// functionality of other classes like a "mixin". More on 'using' later. using StringTools; -/* - Typedefs are like variables... for types. They must be declared before any - code. More on this later. - */ +// Typedefs are like variables... for types. They must be declared before any +// code. More on this later. typedef FooString = String; // Typedefs can also reference "structural" types, more on that later as well. typedef FooObject = { foo: String }; -/* - Here's the class definition. It's the main class for the file, since it has - the same name (LearnHaxe3). - */ -class LearnHaxe3{ +// Here's the class definition. It's the main class for the file, since it has +// the same name (LearnHaxe3). +class LearnHaxe3 { /* If you want certain code to run automatically, you need to put it in a static main function, and specify the class in the compiler arguments. In this case, we've specified the "LearnHaxe3" class in the compiler arguments above. */ - static function main(){ - + static function main() { /* Trace is the default method of printing haxe expressions to the screen. Different targets will have different methods of @@ -103,17 +96,13 @@ class LearnHaxe3{ */ trace("Hello World, with trace()!"); - /* - Trace can handle any type of value or object. It will try to print - a representation of the expression as best it can. You can also - concatenate strings with the "+" operator: - */ - trace( " Integer: " + 10 + " Float: " + 3.14 + " Boolean: " + true); + // Trace can handle any type of value or object. It will try to print + // a representation of the expression as best it can. You can also + // concatenate strings with the "+" operator: + trace("Integer: " + 10 + " Float: " + 3.14 + " Boolean: " + true); - /* - In Haxe, it's required to separate expressions in the same block with - semicolons. But, you can put two expressions on one line: - */ + // In Haxe, it's required to separate expressions in the same block with + // semicolons. But, you can put two expressions on one line: trace('two expressions..'); trace('one line'); @@ -122,14 +111,11 @@ class LearnHaxe3{ ////////////////////////////////////////////////////////////////// trace("***Types & Variables***"); - /* - You can save values and references to data structures using the - "var" keyword: - */ + // You can save values and references to data structures using the + // "var" keyword: var an_integer:Int = 1; trace(an_integer + " is the value for an_integer"); - /* Haxe is statically typed, so "an_integer" is declared to have an "Int" type, and the rest of the expression assigns the value "1" to @@ -150,46 +136,36 @@ class LearnHaxe3{ Haxe uses platform precision for Int and Float sizes. It also uses the platform behavior for overflow. (Other numeric types and behavior are possible using special - libraries) - */ - - /* + libraries.) + In addition to simple values like Integers, Floats, and Booleans, Haxe provides standard library implementations for common data structures like strings, arrays, lists, and maps: */ - var a_string = "some" + 'string'; // strings can have double or single quotes + // Strings can have double or single quotes. + var a_string = "some" + 'string'; trace(a_string + " is the value for a_string"); - /* - Strings can be "interpolated" by inserting variables into specific - positions. The string must be single quoted, and the variable must - be preceded with "$". Expressions can be enclosed in ${...}. - */ + // Strings can be "interpolated" by inserting variables into specific + // positions. The string must be single quoted, and the variable must + // be preceded with "$". Expressions can be enclosed in ${...}. var x = 1; var an_interpolated_string = 'the value of x is $x'; var another_interpolated_string = 'the value of x + 1 is ${x + 1}'; - /* - Strings are immutable, instance methods will return a copy of - parts or all of the string. - (See also the StringBuf class). - */ + // Strings are immutable, instance methods will return a copy of + // parts or all of the string. (See also the StringBuf class). var a_sub_string = a_string.substr(0,4); trace(a_sub_string + " is the value for a_sub_string"); - /* - Regexes are also supported, but there's not enough space to go into - much detail. - */ + // Regexes are also supported, but there's not enough space here to go + // into much detail. var re = ~/foobar/; trace(re.match('foo') + " is the value for (~/foobar/.match('foo')))"); - /* - Arrays are zero-indexed, dynamic, and mutable. Missing values are - defined as null. - */ + // Arrays are zero-indexed, dynamic, and mutable. Missing values are + // defined as null. var a = new Array<String>(); // an array that contains Strings a[0] = 'foo'; trace(a.length + " is the value for a.length"); @@ -197,20 +173,17 @@ class LearnHaxe3{ trace(a.length + " is the value for a.length (after modification)"); trace(a[3] + " is the value for a[3]"); //null - /* - Arrays are *generic*, so you can indicate which values they contain - with a type parameter: - */ + // Arrays are *generic*, so you can indicate which values they contain + // with a type parameter: var a2 = new Array<Int>(); // an array of Ints var a3 = new Array<Array<String>>(); // an Array of Arrays (of Strings). - /* - Maps are simple key/value data structures. The key and the value - can be of any type. - */ - var m = new Map<String, Int>(); // The keys are strings, the values are Ints. + // Maps are simple key/value data structures. The key and the value + // can be of any type. + // Here, the keys are strings, and the values are Ints: + var m = new Map<String, Int>(); m.set('foo', 4); - // You can also use array notation; + // You can also use array notation: m['bar'] = 5; trace(m.exists('bar') + " is the value for m.exists('bar')"); trace(m.get('bar') + " is the value for m.get('bar')"); @@ -219,19 +192,15 @@ class LearnHaxe3{ var m2 = ['foo' => 4, 'baz' => 6]; // Alternative map syntax trace(m2 + " is the value for m2"); - /* - Remember, you can use type inference. The Haxe compiler will - decide the type of the variable the first time you pass an - argument that sets a type parameter. - */ + // Remember, you can use type inference. The Haxe compiler will + // decide the type of the variable the first time you pass an + // argument that sets a type parameter. var m3 = new Map(); m3.set(6, 'baz'); // m3 is now a Map<Int,String> trace(m3 + " is the value for m3"); - /* - Haxe has some more common datastructures in the haxe.ds module, such as - List, Stack, and BalancedTree - */ + // Haxe has some more common datastructures in the haxe.ds module, such + // as List, Stack, and BalancedTree. ////////////////////////////////////////////////////////////////// @@ -243,11 +212,11 @@ class LearnHaxe3{ trace((4 + 3) + " is the value for (4 + 3)"); trace((5 - 1) + " is the value for (5 - 1)"); trace((2 * 4) + " is the value for (2 * 4)"); - trace((8 / 3) + " is the value for (8 / 3) (division always produces Floats)"); + // Division always produces Floats. + trace((8 / 3) + " is the value for (8 / 3) (a Float)"); trace((12 % 4) + " is the value for (12 % 4)"); - - //basic comparison + // basic comparison trace((3 == 2) + " is the value for 3 == 2"); trace((3 != 2) + " is the value for 3 != 2"); trace((3 > 2) + " is the value for 3 > 2"); @@ -257,22 +226,23 @@ class LearnHaxe3{ // standard bitwise operators /* - ~ Unary bitwise complement - << Signed left shift - >> Signed right shift - >>> Unsigned right shift - & Bitwise AND - ^ Bitwise exclusive OR - | Bitwise inclusive OR + ~ Unary bitwise complement + << Signed left shift + >> Signed right shift + >>> Unsigned right shift + & Bitwise AND + ^ Bitwise exclusive OR + | Bitwise inclusive OR */ - //increments + // increments var i = 0; trace("Increments and decrements"); - trace(i++); //i = 1. Post-Incrementation - trace(++i); //i = 2. Pre-Incrementation - trace(i--); //i = 1. Post-Decrementation - trace(--i); //i = 0. Pre-Decrementation + trace(i++); // i = 1. Post-Increment + trace(++i); // i = 2. Pre-Increment + trace(i--); // i = 1. Post-Decrement + trace(--i); // i = 0. Pre-Decrement + ////////////////////////////////////////////////////////////////// // Control Structures @@ -281,21 +251,19 @@ class LearnHaxe3{ // if statements var j = 10; - if (j == 10){ + if (j == 10) { trace("this is printed"); - } else if (j > 10){ + } else if (j > 10) { trace("not greater than 10, so not printed"); } else { trace("also not printed."); } // there is also a "ternary" if: - (j == 10) ? trace("equals 10") : trace("not equals 10"); + (j == 10) ? trace("equals 10") : trace("not equals 10"); - /* - Finally, there is another form of control structures that operates - at compile time: conditional compilation. - */ + // Finally, there is another form of control structure that operates + // at compile time: conditional compilation. #if neko trace('hello from neko'); #elseif js @@ -303,43 +271,40 @@ class LearnHaxe3{ #else trace('hello from another platform!'); #end - /* - The compiled code will change depending on the platform target. - Since we're compiling for neko (-x or -neko), we only get the neko - greeting. - */ + + // The compiled code will change depending on the platform target. + // Since we're compiling for neko (-x or -neko), we only get the neko + // greeting. trace("Looping and Iteration"); // while loop var k = 0; - while(k < 100){ + while (k < 100) { // trace(counter); // will print out numbers 0-99 k++; } // do-while loop var l = 0; - do{ + do { trace("do statement always runs at least once"); } while (l > 0); // for loop - /* - There is no c-style for loop in Haxe, because they are prone - to error, and not necessary. Instead, Haxe has a much simpler - and safer version that uses Iterators (more on those later). - */ - var m = [1,2,3]; - for (val in m){ + // There is no c-style for loop in Haxe, because they are prone + // to error, and not necessary. Instead, Haxe has a much simpler + // and safer version that uses Iterators (more on those later). + var m = [1, 2, 3]; + for (val in m) { trace(val + " is the value for val in the m array"); } // Note that you can iterate on an index using a range // (more on ranges later as well) var n = ['foo', 'bar', 'baz']; - for (val in 0...n.length){ + for (val in 0...n.length) { trace(val + " is the value for val (an index for n)"); } @@ -354,8 +319,11 @@ class LearnHaxe3{ var modified_n = [for (val in n) val += '!']; trace(modified_n + " is the value for modified_n"); - var filtered_and_modified_n = [for (val in n) if (val != "foo") val += "!"]; - trace(filtered_and_modified_n + " is the value for filtered_and_modified_n"); + var filtered_and_modified_n + = [for (val in n) if (val != "foo") val += "!"]; + trace(filtered_and_modified_n + + " is the value for filtered_and_modified_n"); + ////////////////////////////////////////////////////////////////// // Switch Statements (Value Type) @@ -366,33 +334,32 @@ class LearnHaxe3{ Switch statements in Haxe are very powerful. In addition to working on basic values like strings and ints, they can also work on the generalized algebraic data types in enums (more on enums later). - Here's some basic value examples for now: + Here are some basic value examples for now: */ var my_dog_name = "fido"; var favorite_thing = ""; - switch(my_dog_name){ + switch(my_dog_name) { case "fido" : favorite_thing = "bone"; case "rex" : favorite_thing = "shoe"; case "spot" : favorite_thing = "tennis ball"; default : favorite_thing = "some unknown treat"; - // case _ : favorite_thing = "some unknown treat"; // same as default + // same as default: + // case _ : favorite_thing = "some unknown treat"; } - // The "_" case above is a "wildcard" value - // that will match anything. + // The "_" case above is a "wildcard" value that will match anything. trace("My dog's name is " + my_dog_name + ", and his favorite thing is a: " + favorite_thing); + ////////////////////////////////////////////////////////////////// // Expression Statements ////////////////////////////////////////////////////////////////// trace("***EXPRESSION STATEMENTS***"); - /* - Haxe control statements are very powerful because every statement - is also an expression, consider: - */ + // Haxe control statements are very powerful because every statement + // is also an expression, consider: // if statements var k = if (true) 10 else 20; @@ -410,6 +377,7 @@ class LearnHaxe3{ + ", and his other favorite thing is a: " + other_favorite_thing); + ////////////////////////////////////////////////////////////////// // Converting Value Types ////////////////////////////////////////////////////////////////// @@ -418,14 +386,14 @@ class LearnHaxe3{ // You can convert strings to ints fairly easily. // string to integer - Std.parseInt("0"); // returns 0 - Std.parseFloat("0.4"); // returns 0.4; + Std.parseInt("0"); // returns 0 + Std.parseFloat("0.4"); // returns 0.4 // integer to string - Std.string(0); // returns "0"; + Std.string(0); // returns "0" // concatenation with strings will auto-convert to string. - 0 + ""; // returns "0"; - true + ""; // returns "true"; + 0 + ""; // returns "0" + true + ""; // returns "true" // See documentation for parsing in Std for more details. @@ -434,14 +402,13 @@ class LearnHaxe3{ ////////////////////////////////////////////////////////////////// /* - As mentioned before, Haxe is a statically typed language. All in all, static typing is a wonderful thing. It enables precise autocompletions, and can be used to thoroughly check the correctness of a program. Plus, the Haxe compiler is super fast. - *HOWEVER*, there are times when you just wish the compiler would let - something slide, and not throw a type error in a given case. + *HOWEVER*, there are times when you just wish the compiler would + let something slide, and not throw a type error in a given case. To do this, Haxe has two separate keywords. The first is the "Dynamic" type: @@ -456,11 +423,10 @@ class LearnHaxe3{ The other more extreme option is the "untyped" keyword: */ - - untyped { - var x:Int = 'foo'; // this can't be right! - var y:String = 4; // madness! - } + untyped { + var x:Int = 'foo'; // This can't be right! + var y:String = 4; // Madness! + } /* The untyped keyword operates on entire *blocks* of code, skipping @@ -474,74 +440,66 @@ class LearnHaxe3{ of the type models work should you resort to "Dynamic" or "untyped". */ + ////////////////////////////////////////////////////////////////// // Basic Object Oriented Programming ////////////////////////////////////////////////////////////////// trace("***BASIC OBJECT ORIENTED PROGRAMMING***"); - - /* - Create an instance of FooClass. The classes for this are at the - end of the file. - */ + // Create an instance of FooClass. The classes for this are at the + // end of the file. var foo_instance = new FooClass(3); // read the public variable normally - trace(foo_instance.public_any + " is the value for foo_instance.public_any"); + trace(foo_instance.public_any + + " is the value for foo_instance.public_any"); // we can read this variable - trace(foo_instance.public_read + " is the value for foo_instance.public_read"); - // but not write it - // foo_instance.public_read = 4; // this will throw an error if uncommented: + trace(foo_instance.public_read + + " is the value for foo_instance.public_read"); + // but not write it; this will throw an error if uncommented: + // foo_instance.public_read = 4; // trace(foo_instance.public_write); // as will this. - // calls the toString method: + // Calls the toString method: trace(foo_instance + " is the value for foo_instance"); // same thing: - trace(foo_instance.toString() + " is the value for foo_instance.toString()"); - + trace(foo_instance.toString() + + " is the value for foo_instance.toString()"); - /* - The foo_instance has the "FooClass" type, while acceptBarInstance - has the BarClass type. However, since FooClass extends BarClass, it - is accepted. - */ + // The foo_instance has the "FooClass" type, while acceptBarInstance + // has the BarClass type. However, since FooClass extends BarClass, it + // is accepted. BarClass.acceptBarInstance(foo_instance); - /* - The classes below have some more advanced examples, the "example()" - method will just run them here. - */ + // The classes below have some more advanced examples, the "example()" + // method will just run them here. SimpleEnumTest.example(); ComplexEnumTest.example(); TypedefsAndStructuralTypes.example(); UsingExample.example(); - } - } -/* - This is the "child class" of the main LearnHaxe3 Class - */ -class FooClass extends BarClass implements BarInterface{ +// This is the "child class" of the main LearnHaxe3 Class. +class FooClass extends BarClass implements BarInterface { public var public_any:Int; // public variables are accessible anywhere public var public_read (default, null): Int; // enable only public read public var public_write (null, default): Int; // or only public write - public var property (get, set): Int; // use this style to enable getters/setters + // Use this style to enable getters/setters: + public var property (get, set): Int; // private variables are not available outside the class. // see @:allow for ways around this. var _private:Int; // variables are private if they are not marked public // a public constructor - public function new(arg:Int){ + public function new(arg:Int) { // call the constructor of the parent object, since we extended BarClass: super(); this.public_any = 0; this._private = arg; - } // getter for _private @@ -555,47 +513,40 @@ class FooClass extends BarClass implements BarInterface{ return val; } - // special function that is called whenever an instance is cast to a string. - public function toString(){ + // Special function that is called whenever an instance is cast to a string. + public function toString() { return _private + " with toString() method!"; } // this class needs to have this function defined, since it implements // the BarInterface interface. - public function baseFunction(x: Int) : String{ + public function baseFunction(x: Int) : String { // convert the int to string automatically return x + " was passed into baseFunction!"; } } -/* - A simple class to extend -*/ +// A simple class to extend. class BarClass { var base_variable:Int; - public function new(){ + public function new() { base_variable = 4; } - public static function acceptBarInstance(b:BarClass){ - } + public static function acceptBarInstance(b:BarClass) {} } -/* - A simple interface to implement -*/ -interface BarInterface{ +// A simple interface to implement +interface BarInterface { public function baseFunction(x:Int):String; } + ////////////////////////////////////////////////////////////////// // Enums and Switch Statements ////////////////////////////////////////////////////////////////// -/* - Enums in Haxe are very powerful. In their simplest form, enums - are a type with a limited number of states: - */ - +// Enums in Haxe are very powerful. In their simplest form, enums +// are a type with a limited number of states: enum SimpleEnum { Foo; Bar; @@ -603,12 +554,12 @@ enum SimpleEnum { } // Here's a class that uses it: - -class SimpleEnumTest{ - public static function example(){ - var e_explicit:SimpleEnum = SimpleEnum.Foo; // you can specify the "full" name +class SimpleEnumTest { + public static function example() { + // You can specify the "full" name, + var e_explicit:SimpleEnum = SimpleEnum.Foo; var e = Foo; // but inference will work as well. - switch(e){ + switch(e) { case Foo: trace("e was Foo"); case Bar: trace("e was Bar"); case Baz: trace("e was Baz"); // comment this line to throw an error. @@ -621,18 +572,16 @@ class SimpleEnumTest{ You can also specify a default for enum switches as well: */ - switch(e){ + switch(e) { case Foo: trace("e was Foo again"); default : trace("default works here too"); } } } -/* - Enums go much further than simple states, we can also enumerate - *constructors*, but we'll need a more complex enum example - */ -enum ComplexEnum{ +// Enums go much further than simple states, we can also enumerate +// *constructors*, but we'll need a more complex enum example. +enum ComplexEnum { IntEnum(i:Int); MultiEnum(i:Int, j:String, k:Float); SimpleEnumEnum(s:SimpleEnum); @@ -641,14 +590,12 @@ enum ComplexEnum{ // Note: The enum above can include *other* enums as well, including itself! // Note: This is what's called *Algebraic data type* in some other languages. -class ComplexEnumTest{ - public static function example(){ +class ComplexEnumTest { + public static function example() { var e1:ComplexEnum = IntEnum(4); // specifying the enum parameter - /* - Now we can switch on the enum, as well as extract any parameters - it might of had. - */ - switch(e1){ + // Now we can switch on the enum, as well as extract any parameters + // it might have had. + switch(e1) { case IntEnum(x) : trace('$x was the parameter passed to e1'); default: trace("Shouldn't be printed"); } @@ -662,34 +609,28 @@ class ComplexEnumTest{ // enums all the way down var e3 = ComplexEnumEnum(ComplexEnumEnum(MultiEnum(4, 'hi', 4.3))); - switch(e3){ - // You can look for certain nested enums by specifying them explicitly: + switch(e3) { + // You can look for certain nested enums by specifying them + // explicitly: case ComplexEnumEnum(ComplexEnumEnum(MultiEnum(i,j,k))) : { trace('$i, $j, and $k were passed into this nested monster'); } default: trace("Shouldn't be printed"); } - /* - Check out "generalized algebraic data types" (GADT) for more details - on why these are so great. - */ + // Check out "generalized algebraic data types" (GADT) for more details + // on why these are so great. } } class TypedefsAndStructuralTypes { - public static function example(){ - /* - Here we're going to use typedef types, instead of base types. - At the top we've declared the type "FooString" to mean a "String" type. - */ + public static function example() { + // Here we're going to use typedef types, instead of base types. + // At the top we've declared the type "FooString" to mean a "String" type. var t1:FooString = "some string"; - /* - We can use typedefs for "structural types" as well. These types are - defined by their field structure, not by class inheritance. Here's - an anonymous object with a String field named "foo": - */ - + // We can use typedefs for "structural types" as well. These types are + // defined by their field structure, not by class inheritance. Here's + // an anonymous object with a String field named "foo": var anon_obj = { foo: 'hi' }; /* @@ -699,8 +640,7 @@ class TypedefsAndStructuralTypes { that structure, we can use it anywhere that a "FooObject" type is expected. */ - - var f = function(fo:FooObject){ + var f = function(fo:FooObject) { trace('$fo was passed in to this function'); } f(anon_obj); // call the FooObject signature function with anon_obj. @@ -712,9 +652,7 @@ class TypedefsAndStructuralTypes { ?optionalString: String, requiredInt: Int } - */ - /* Typedefs work well with conditional compilation. For instance, we could have included this at the top of the file: @@ -728,15 +666,14 @@ class TypedefsAndStructuralTypes { typedef Surface = java.awt.geom.GeneralPath; #end - That would give us a single "Surface" type to work with across - all of those platforms. + That would give us a single "Surface" type to work with across + all of those platforms. */ } } class UsingExample { public static function example() { - /* The "using" import keyword is a special type of class import that alters the behavior of any static methods in the class. diff --git a/html.html.markdown b/html.html.markdown index 4d225aca..f01f139c 100644 --- a/html.html.markdown +++ b/html.html.markdown @@ -167,7 +167,7 @@ useful tips. HTML is written in files ending with `.html` or `.htm`. The mime type is `text/html`. - +**HTML is NOT a programming language** ## To Learn More * [wikipedia](https://en.wikipedia.org/wiki/HTML) diff --git a/hu-hu/python-hu.html.markdown b/hu-hu/python-hu.html.markdown index 9b55f8e2..01f1c414 100644 --- a/hu-hu/python-hu.html.markdown +++ b/hu-hu/python-hu.html.markdown @@ -656,7 +656,7 @@ i.age # => AttributeError hibát dob # Modulokat így lehet importálni import math -print math.sqrt(16) # => 4 +print math.sqrt(16) # => 4.0 # Lehetséges csak bizonyos függvényeket importálni egy modulból from math import ceil, floor diff --git a/it-it/logtalk-it.html.markdown b/it-it/logtalk-it.html.markdown index 7f1e9eeb..5cc53e6f 100644 --- a/it-it/logtalk-it.html.markdown +++ b/it-it/logtalk-it.html.markdown @@ -43,7 +43,7 @@ Un oggetto incapsula le dichiarazioni e le definizioni dei predicati. Gli oggett :- end_object. ``` -# Compilazione dei file sorgenti +# Compilazione e il caricamento dei file sorgenti Supponendo che il codice di cui sopra per l'oggetto `list` venga salvato in un file` list.lgt`, esso può essere compilato e caricato utilizzando il predicato predefiniti `logtalk_load/1` o la sua abbreviazione `{}/1`, con il percorso del file come argomento (l'estensione può essere omessa): @@ -52,6 +52,9 @@ Supponendo che il codice di cui sopra per l'oggetto `list` venga salvato in un f yes ``` +In generale, le entità potrebbero avere dipendenze sulle entità definite in altri file di origine (ad esempio le entità di biblioteca). Per caricare un file e tutte le sue dipendenze, la soluzione consigliata consiste nel definire un file _loader_ che carica tutti i file necessari per un'applicazione. Un file loader è semplicemente un file di origine, in genere denominato `loader.lgt`, che effettua chiamate ai predicati built-in `logtalk_load/1-2`, di solito +da una direttiva `initialization/1` per la portabilità e conformità agli standard. Caricatore file vengono forniti per tutte le librerie, strumenti ed esempi. + # Inviare un messaggio ad un oggetto L'operatore infisso `::/2` è usato per inviare messaggi ad un oggetto. Analogamente al Prolog, è possibile fare backtracking per le soluzioni alternative: diff --git a/it-it/python-it.html.markdown b/it-it/python-it.html.markdown index e81d1676..794e7a70 100644 --- a/it-it/python-it.html.markdown +++ b/it-it/python-it.html.markdown @@ -640,7 +640,7 @@ i.age # => Emette un AttributeError # Puoi importare moduli import math -print math.sqrt(16) # => 4 +print math.sqrt(16) # => 4.0 # Puoi ottenere specifiche funzione da un modulo from math import ceil, floor diff --git a/it-it/rust-it.html.markdown b/it-it/rust-it.html.markdown index 6b379f93..e4b7c33f 100644 --- a/it-it/rust-it.html.markdown +++ b/it-it/rust-it.html.markdown @@ -130,14 +130,14 @@ fn main() { ///////////// // Strutture - struct Point { + struct Punto { x: i32, y: i32, } let origine: Punto = Punto { x: 0, y: 0 }; - // Ana struct con campi senza nome, chiamata ‘tuple struct’ + // Una struct con campi senza nome, chiamata ‘tuple struct’ struct Punto2(i32, i32); let origine2 = Punto2(0, 0); diff --git a/javascript.html.markdown b/javascript.html.markdown index ecaf02c5..c466c09b 100644 --- a/javascript.html.markdown +++ b/javascript.html.markdown @@ -510,6 +510,7 @@ for (var x in myObj){ // Hello world! // 43 // [Function: myFunc] +// true // To only consider properties attached to the object itself // and not its prototypes, use the `hasOwnProperty()` check. diff --git a/julia.html.markdown b/julia.html.markdown index 69b6aa0c..5e9ef1b8 100644 --- a/julia.html.markdown +++ b/julia.html.markdown @@ -46,6 +46,13 @@ div(5, 2) # => 2 # for a truncated result, use div # Enforce precedence with parentheses (1 + 3) * 2 # => 8 +# Julia (unlike Python for instance) has integer under/overflow +10^19 # => -8446744073709551616 +# use bigint or floating point to avoid this +big(10)^19 # => 10000000000000000000 +1e19 # => 1.0e19 +10.0^19 # => 1.0e19 + # Bitwise Operators ~2 # => -3 # bitwise not 3 & 5 # => 1 # bitwise and @@ -93,21 +100,22 @@ ascii("This is a string")[1] # Julia indexes from 1 # Otherwise, iterating over strings is recommended (map, for loops, etc). +# String can be compared lexicographically +"good" > "bye" # => true +"good" == "good" # => true +"1 + 2 = 3" == "1 + 2 = $(1 + 2)" # => true + # $ can be used for string interpolation: "2 + 2 = $(2 + 2)" # => "2 + 2 = 4" # You can put any Julia expression inside the parentheses. +# Printing is easy +println("I'm Julia. Nice to meet you!") # => I'm Julia. Nice to meet you! + # Another way to format strings is the printf macro from the stdlib Printf. using Printf @printf "%d is less than %f\n" 4.5 5.3 # => 5 is less than 5.300000 -# Printing is easy -println("I'm Julia. Nice to meet you!") # => I'm Julia. Nice to meet you! - -# String can be compared lexicographically -"good" > "bye" # => true -"good" == "good" # => true -"1 + 2 = 3" == "1 + 2 = $(1 + 2)" # => true #################################################### ## 2. Variables and Collections diff --git a/ko-kr/python-kr.html.markdown b/ko-kr/python-kr.html.markdown index ed377a99..0145754d 100644 --- a/ko-kr/python-kr.html.markdown +++ b/ko-kr/python-kr.html.markdown @@ -441,7 +441,7 @@ Human.grunt() #=> "*grunt*" # 다음과 같이 모듈을 임포트할 수 있습니다. import math -print math.sqrt(16) #=> 4 +print math.sqrt(16) #=> 4.0 # 모듈의 특정 함수를 호출할 수 있습니다. from math import ceil, floor diff --git a/kotlin.html.markdown b/kotlin.html.markdown index 9bc8b420..9336d217 100644 --- a/kotlin.html.markdown +++ b/kotlin.html.markdown @@ -109,7 +109,7 @@ fun helloWorld(val name : String) { /* When a function consists of a single expression then the curly brackets can - be omitted. The body is specified after a = symbol. + be omitted. The body is specified after the = symbol. */ fun odd(x: Int): Boolean = x % 2 == 1 println(odd(6)) // => false @@ -306,7 +306,7 @@ fun helloWorld(val name : String) { println(result) /* - We can check if an object is a particular type by using the "is" operator. + We can check if an object is of a particular type by using the "is" operator. If an object passes a type check then it can be used as that type without explicitly casting it. */ @@ -346,11 +346,6 @@ fun helloWorld(val name : String) { return this.filter {it != c} } println("Hello, world!".remove('l')) // => Heo, word! - - println(EnumExample.A) // => A - println(ObjectExample.hello()) // => hello - - testOperator() } // Enum classes are similar to Java enum types. @@ -358,6 +353,8 @@ enum class EnumExample { A, B, C } +fun printEnum() = println(EnumExample.A) // => A + /* The "object" keyword can be used to create singleton objects. We cannot instantiate it but we can refer to its unique instance by its name. @@ -367,11 +364,18 @@ object ObjectExample { fun hello(): String { return "hello" } + + override fun toString(): String { + return "Hello, it's me, ${ObjectExample::class.simpleName}" + } } -fun useObject() { - ObjectExample.hello() - val someRef: Any = ObjectExample // we use objects name just as is + +fun useSingletonObject() { + println(ObjectExample.hello()) // => hello + // In Kotlin, "Any" is the root of the class hierarchy, just like "Object" is in Java + val someRef: Any = ObjectExample + println(someRef) // => Hello, it's me, ObjectExample } @@ -381,69 +385,54 @@ throws an exception if the value is null. var b: String? = "abc" val l = b!!.length -/* You can add many custom operations using symbol like +, to particular instance -by overloading the built-in kotlin operator, using "operator" keyword - -below is the sample class to add some operator, and the most basic example -*/ -data class SomeClass(var savedValue: Int = 0) +data class Counter(var value: Int) { + // overload Counter += Int + operator fun plusAssign(increment: Int) { + this.value += increment + } -// instance += valueToAdd -operator fun SomeClass.plusAssign(valueToAdd: Int) { - this.savedValue += valueToAdd -} + // overload Counter++ and ++Counter + operator fun inc() = Counter(value + 1) -// -instance -operator fun SomeClass.unaryMinus() = SomeClass(-this.savedValue) + // overload Counter + Counter + operator fun plus(other: Counter) = Counter(this.value + other.value) -// ++instance or instance++ -operator fun SomeClass.inc() = SomeClass(this.savedValue + 1) + // overload Counter * Counter + operator fun times(other: Counter) = Counter(this.value * other.value) -// instance * other -operator fun SomeClass.times(other: SomeClass) = - SomeClass(this.savedValue * other.savedValue) + // overload Counter * Int + operator fun times(value: Int) = Counter(this.value * value) -// an overload for multiply -operator fun SomeClass.times(value: Int) = SomeClass(this.savedValue * value) + // overload Counter in Counter + operator fun contains(other: Counter) = other.value == this.value -// other in instance -operator fun SomeClass.contains(other: SomeClass) = - other.savedValue == this.savedValue + // overload Counter[Int] = Int + operator fun set(index: Int, value: Int) { + this.value = index + value + } -// instance[dummyIndex] = valueToSet -operator fun SomeClass.set(dummyIndex: Int, valueToSet: Int) { - this.savedValue = valueToSet + dummyIndex -} + // overload Counter instance invocation + operator fun invoke() = println("The value of the counter is $value") -// instance() -operator fun SomeClass.invoke() { - println("instance invoked by invoker") } - -/* return type must be Integer, -so that, it can be translated to "returned value" compareTo 0 - -for equality (==,!=) using operator will violates overloading equals function, -since it is already defined in Any class -*/ -operator fun SomeClass.compareTo(other: SomeClass) = - this.savedValue - other.savedValue - -fun testOperator() { - var x = SomeClass(4) - - println(x) // => "SomeClass(savedValue=4)" - x += 10 - println(x) // => "SomeClass(savedValue=14)" - println(-x) // => "SomeClass(savedValue=-14)" - println(++x) // => "SomeClass(savedValue=15)" - println(x * SomeClass(3)) // => "SomeClass(savedValue=45)" - println(x * 2) // => "SomeClass(savedValue=30)" - println(SomeClass(15) in x) // => true - x[2] = 10 - println(x) // => "SomeClass(savedValue=12)" - x() // => "instance invoked by invoker" - println(x >= 15) // => false +/* You can also overload operators through an extension methods */ +// overload -Counter +operator fun Counter.unaryMinus() = Counter(-this.value) + +fun operatorOverloadingDemo() { + var counter1 = Counter(0) + var counter2 = Counter(5) + counter1 += 7 + println(counter1) // => Counter(value=7) + println(counter1 + counter2) // => Counter(value=12) + println(counter1 * counter2) // => Counter(value=35) + println(counter2 * 2) // => Counter(value=10) + println(counter1 in Counter(5)) // => false + println(counter1 in Counter(7)) // => true + counter1[26] = 10 + println(counter1) // => Counter(value=36) + counter1() // => The value of the counter is 36 + println(-counter2) // => Counter(value=-5) } ``` diff --git a/lambda-calculus.html.markdown b/lambda-calculus.html.markdown index 3d080de7..53a7a7cd 100644 --- a/lambda-calculus.html.markdown +++ b/lambda-calculus.html.markdown @@ -85,7 +85,7 @@ Using `IF`, we can define the basic boolean logic operators: `a OR b` is equivalent to: `λab.IF a T b` -`a NOT b` is equivalent to: `λa.IF a F T` +`NOT a` is equivalent to: `λa.IF a F T` *Note: `IF a b c` is essentially saying: `IF((a b) c)`* @@ -111,7 +111,7 @@ we use the successor function `S(n) = n + 1` which is: Using successor, we can define add: -`ADD = λab.(a S)n` +`ADD = λab.(a S)b` **Challenge:** try defining your own multiplication function! @@ -139,6 +139,7 @@ Take the church number 2 for example: `2 = λf.λx.f(f x)` For the inner part `λx.f(f x)`: + ``` λx.f(f x) = S (λx.f) (λx.(f x)) (case 3) @@ -147,6 +148,7 @@ For the inner part `λx.f(f x)`: ``` So: + ``` 2 = λf.λx.f(f x) @@ -156,6 +158,7 @@ So: ``` For the first argument `λf.(S (K f))`: + ``` λf.(S (K f)) = S (λf.S) (λf.(K f)) (case 3) @@ -164,6 +167,7 @@ For the first argument `λf.(S (K f))`: ``` For the second argument `λf.(S (K f) I)`: + ``` λf.(S (K f) I) = λf.((S (K f)) I) @@ -174,6 +178,7 @@ For the second argument `λf.(S (K f) I)`: ``` Merging them up: + ``` 2 = S (λf.(S (K f))) (λf.(S (K f) I)) diff --git a/latex.html.markdown b/latex.html.markdown index 874efeeb..c980f5e5 100644 --- a/latex.html.markdown +++ b/latex.html.markdown @@ -95,7 +95,7 @@ to the source code. Separate paragraphs by empty lines. -You need to add a dot after abbreviations (if not followed by a comma), because otherwise the spacing after the dot is too large: +You need to add a backslash after abbreviations (if not followed by a comma), because otherwise the spacing after the dot is too large: E.g., i.e., etc.\ are are such abbreviations. \section{Lists} diff --git a/logtalk.html.markdown b/logtalk.html.markdown index 5a52bd3c..ce907ee3 100644 --- a/logtalk.html.markdown +++ b/logtalk.html.markdown @@ -40,7 +40,7 @@ An object encapsulates predicate declarations and definitions. Objects can be cr :- end_object. ``` -# Compiling source files +# Compiling and loading source files Assuming that the code above for the `list` object is saved in a `list.lgt` file, it can be compiled and loaded using the `logtalk_load/1` built-in predicate or its abbreviation, `{}/1`, with the file path as argument (the extension can be omitted): @@ -49,6 +49,11 @@ Assuming that the code above for the `list` object is saved in a `list.lgt` file yes ``` +In general, entities may have dependencies on entities defined in other source files (e.g. library entities). To load a file and all its dependencies, the advised solution is to define a +_loader_ file that loads all the necessary files for an application. A loader file is simply a source file, typically named `loader.lgt`, that makes calls to the `logtalk_load/1-2` +built-in predicates, usually from an `initialization/1` directive for portability and +standards compliance. Loader files are provided for all libraries, tools, and examples. + # Sending a message to an object The `::/2` infix operator is used to send a message to an object. As in Prolog, we can backtrack for alternative solutions: diff --git a/m.html.markdown b/m.html.markdown index d0879ab6..96828ae5 100644 --- a/m.html.markdown +++ b/m.html.markdown @@ -125,7 +125,7 @@ w !,^cars w !,^cars("Tesla") ; null value - there's no value assigned to this node but it has children w !,^cars("Tesla",1,"Name") -; Model X +; Model 3 ``` Arrays are automatically sorted in order. Take advantage of the built-in sorting by setting your value of interest as the last child subscript of an array rather than its value. diff --git a/make.html.markdown b/make.html.markdown index 45d020e9..eecc96bf 100644 --- a/make.html.markdown +++ b/make.html.markdown @@ -1,5 +1,6 @@ ---
-language: make
+category: tool
+tool: make
contributors:
- ["Robert Steed", "https://github.com/robochat"]
- ["Stephan Fuhrmann", "https://github.com/sfuhrm"]
diff --git a/ocaml.html.markdown b/ocaml.html.markdown index 74eb7993..b631df0a 100644 --- a/ocaml.html.markdown +++ b/ocaml.html.markdown @@ -161,7 +161,7 @@ let my_lambda = fun x -> x * x ;; (*** Operators ***) -(* There is little distintion between operators and functions. +(* There is little distinction between operators and functions. Every operator can be called as a function. *) (+) 3 4 (* Same as 3 + 4 *) diff --git a/p5.html.markdown b/p5.html.markdown new file mode 100644 index 00000000..be22d3e5 --- /dev/null +++ b/p5.html.markdown @@ -0,0 +1,53 @@ +--- +category: tool +tool: p5 +contributors: + - ['Amey Bhavsar', 'https://github.com/ameybhavsar24'] + - ['Claudio Busatto', 'https://github.com/cjcbusatto'] +filename: p5.js +--- + +p5.js is a JavaScript library that starts with the original goal of [Processing](http://processing.org"), to make coding accessible for artists, designers, educators, and beginners, and reinterprets this for today's web. +Since p5 is a JavaScript library, you should learn [Javascript](https://learnxinyminutes.com/docs/javascript/) first. + +```js +/////////////////////////////////// +// p5.js has two important functions to work with. + +function setup() { + // the setup function gets executed just once when the window is loaded +} +function draw() { + // the draw function gets called every single frame. This means that for a frameRate(30) it would get called 30 times per second. +} + +// the following code explains all features + +function setup() { + createCanvas(640, 480); // creates a new canvas element with 640px as width as 480px as height + background(128); // changes the background color of the canvas, can accept rgb values like background(100,200,20) else grayscale values like background(0) = black or background(255) = white +} + +function draw() { + ellipse(10, 10, 50, 50); // creates a ellipse at the 10px from the left and 10px from the top with width adn height as 50 each, so its basically a circle. + //remember in p5.js the origin is at the top-left corner of the canvas + + if (mouseIsPressed) { + // mouseIsPressed is a boolean variable that changes to true if the mouse buttton is pressed down at that instant + + fill(0); // fill refers to the innner color or filling color of whatever shape you are going to draw next + } else { + fill(255); // you can give in rgb values like fill(72, 240, 80) to get colors, else a single values determines the grayscale where fill(255) stands for #FFF(white) and fill(0) stands for #000(black) + } + + ellipse(mouseX, mouseY, 80, 80); + // mouseX is the x-coordinate of the mouse's current position and mouseY is the y-coordinate of the mouse's current position + + // the above code creates a circle wherever mouse's current position and fills it either black or white based on the mouseIsPressed +} +``` + +## Further Reading + +- [p5.js | get started](http://p5js.org/get-started/) The official documentation +- [Code! Programming for Beginners with p5.js - YouTube](https://www.youtube.com/watch?v=yPWkPOfnGsw&vl=en) Introduction and Coding challenges using Processing and p5.js by Coding Train diff --git a/pascal.html.markdown b/pascal.html.markdown index 28dcc10f..9fb51c3b 100644 --- a/pascal.html.markdown +++ b/pascal.html.markdown @@ -66,7 +66,7 @@ program Learn_More; const PI = 3.141592654; - GNU = 'GNU's Not Unix'; + GNU = 'GNU''s Not Unix'; // constants are conventionally named using CAPS // their values are fixed and cannot be changed during runtime // holds any standard data type (integer, real, boolean, char, string) diff --git a/perl.html.markdown b/perl.html.markdown index 17a538e3..08001ab0 100644 --- a/perl.html.markdown +++ b/perl.html.markdown @@ -152,7 +152,7 @@ while (condition) { ... } - +my $max = 5; # for loops and iteration for my $i (0 .. $max) { print "index is $i"; diff --git a/perl6-pod.html.markdown b/perl6-pod.html.markdown new file mode 100644 index 00000000..80a501b8 --- /dev/null +++ b/perl6-pod.html.markdown @@ -0,0 +1,622 @@ +--- +language: Pod +contributors: + - ["Luis F. Uceta", "https://uzluisf.gitlab.io/"] +filename: learnpod.pod6 +--- + +Pod is an easy-to-use and purely descriptive mark-up language, +with no presentational components. Besides its use for documenting +Raku Perl 6 programs and modules, Pod can be utilized to write language +documentation, blogs, and other types of document composition as well. + +Pod documents can be easily converted to HTML and many other formats +(e.g., Markdown, Latex, plain text, etc.) by using the corresponding +variant of the `Pod::To` modules (e.g. `Pod::To::HTML` for HTML conversion). + +- [General Info](#general-info) +- [Pod Basics](#pod-basics) + - [Basic Text Formatting](#basic-text-formatting) + - [Headings](#headings) + - [Ordinary Paragraphs](#ordinary-paragraphs) + - [Lists](#lists) + - [Code Blocks](#code-blocks) + - [Comments](#comments) + - [Links](#links) + - [Tables](#tables) +- [Block Structures](#block-structures) + - [Abbreviated Blocks](#abbreviated-blocks) + - [Delimited Blocks](#delimited-blocks) + - [Paragraph Blocks](#paragraph-blocks) +- [Configuration Data](#configuration-data) + - [Standard Configuration Options](#standard-configuration-options) + - [Block Pre-configuration](#block-pre-configuration) +- [Semantic Blocks](#semantic-blocks) +- [Miscellaneous](#miscellaneous) + - [Notes](#notes) + - [Keyboard Input](#keyboard-input) + - [Terminal Output](#terminal-output) + - [Unicode](#unicode) +- [Rendering Pod](#rendering-pod) +- [Accessing Pod](#accessing-pod) + +## General Info + +Every Pod document has to begin with `=begin pod` and end with `=end pod`. +Everything between these two delimiters will be processed and used to +generate documentation. + +``` +=begin pod + +A very simple Raku Perl 6 Pod document. All the other directives go here! + +=end pod +``` + +Pod documents usually coexist with Raku Perl 6 code. If by themselves, +Pod files often have the `.pod6` suffix. Moving forward, it's assumed that +the constructs being discussed are surrounded by the `=begin pod ... =end pod` +directives. + +## Pod Basics + +### Basic Text Formatting + +Text can be easily styled as bold, italic, underlined or verbatim (for code +formatting) using the following formatting codes: `B<>`, `I<>`, `U<>` +and `C<>`. + +``` +B<This text is in Bold.> + +I<This text is in Italics.> + +U<This text is Underlined.> + +The function C<sub sum { $^x + $^y}> is treated as verbatim. +``` + +There are more formatting codes (e.g., `L<>`, `T<>`, etc.) but they'll be +discussed later throughout the document. You'll recognize them because they're +just a single capital letter followed immediately by a set of single or double +angle brackets. The Unicode variant («») of the angle brackets can also be +used. + +### Headings + +Headings are created by using the `=headN` directive where `N` is the +heading level. + +``` +=head1 This is level 1 +=head2 This is level 2 +=head3 This is level 3 +=head4 This is level 4 +=head5 This is level 5 +=head6 This is level 6 +``` + +### Ordinary Paragraphs + +Ordinary paragraphs consist of one or more adjacent lines of text, each of +which starts with a non-whitespace character. Any paragraph is terminated +by the first blank line or block directive. + +``` +=head1 First level heading block + +=head2 Paragraph 1 + +This is an ordinary paragraph. Its text will be squeezed and +short lines filled. It is terminated by the first blank line. + +=head2 Paragraph 2 + +This is another ordinary paragraph albeit shorter. +``` + +Alternatively, the `=para` directive can be used to explicitly mark adjacent +lines of text as a paragraph. + +``` +=head1 First level heading block + +=head2 Paragraph 1 + +=para +This is an ordinary paragraph. Its text will be squeezed and +short lines filled. It is terminated by the first blank line. + +=head2 Paragraph 2 + +=para +This is another ordinary paragraph albeit shorter. +``` + +### Lists + +Unordered lists can be created using the `=item` directive. + +``` +=item Item +=item Item +=item Another item +``` + +Sublists are achieved with items at each level specified using the `=item1`, +`=item2`, `=item3`, `...`, `=itemN` etc. directives. The `=item` directive +defaults to `=item1`. + +``` +=item1 Item one +=item1 Item two +=item1 Item three + =item2 Sub-item + =item2 Sub-item +=item1 Item four +``` + +Definition lists that define terms or commands use the `=defn` directive. +This is equivalent to the `<dl>` element in HTML. + +``` +=defn Beast of Bodmin +A large feline inhabiting Bodmin Moor. + +=defn Morgawr +A sea serpent. + +=defn Owlman +A giant owl-like creature. +``` + +### Code Blocks + +A code block is created (which uses the HTML `<code>` element) by starting each +line with one or more whitespace characters. + +``` + #`( this is comment ) + my $sum = -> $x, $y { $x + $y } + say $sum(12, 5); +``` + +As shown in the [Basic Text Formatting](#basic-text-formatting) section, +inline code can be created using the `C<>` code. + +``` +In Raku Perl 6, there are several functions/methods to output text. Some of them +are C<print>, C<put> and C<say>. +``` + +### Comments + +Although Pod blocks are ignored by the Raku Perl 6 compiler, everything +indentified as a Pod block will be read and interpreted by Pod renderers. In +order to prevent Pod blocks from being rendered by any renderer, use the +`=comment` directive. + +``` +=comment Add more here about the algorithm. + +=comment Pod comments are great for documenting the documentation. +``` + +To create inline comments, use the `Z<>` code. + +``` +Pod is awesome Z<Of course it is!>. And Raku Perl 6 too! +``` + +Given that the Perl interpreter never executes embedded Pod blocks, +comment blocks can also be used as an alternative form of nestable block +comments in Raku Perl 6. + +### Links + +Creating links in Pod is quite easy and is done by enclosing them in +a `L<>` code. The general format is `L<Label|Url>` with `Label` +being optional. + +``` +Raku Perl 6 homepage is L<https://perl6.org>. +L<Click me!|http://link.org/>. +``` + +Relative paths work too. + +``` +L<Go to music|/music/>. +``` + +Linking to a section in the same document works as well. + +``` +L<Link to Headings|#Headings> +``` + +### Tables + +The Pod specifications are not completely handled properly yet and this +includes the handling of table. For simplicity's sake, only one way of +constructing tables is shown here. To learn about good practices and see +examples of both good and bad tables, please visit +<https://docs.perl6.org/language/tables>. + +``` +=begin table +Option | Description +============|================ +data | path to data files. +engine | engine to be used for processing templates. +ext | extension to be used for dest files. +=end table +``` + +## Block Structures + +As mentioned earlier, Pod documents are specified using directives, which are +used to delimit blocks of textual content and declare optional +[configuration information](#configuration-data). Every directive starts with +an equals sign (`=`) in the first column. The content of a document is +specified within one or more blocks. Every Pod block may be declared in any of +three equivalent forms: delimited style, paragraph style, or abbreviated style. + +Up to this point, we have only used the abbreviated style for the block +types (e.g., `=head1`, `=para`, `=comment`, `=item`, etc). + +### Abbreviated Blocks + +Abbreviated blocks are introduced by an `=` sign in the first column, which +is followed immediately by the `typename` of the block and then the content. +The rest of the line is treated as block data, rather than as configuration. +The content terminates at the next Pod directive or the first blank line +(which is not part of the block data). The general syntax is + +``` +=BLOCK_TYPE BLOCK_DATA +``` +For example: + +``` +=head1 Top level heading +``` + +### Delimited Blocks + +Delimited blocks are bounded by `=begin` and `=end` markers, both of which are +followed by a valid Pod identifier, which is the `typename` of the block. +The general syntax is + +``` +=begin BLOCK_TYPE +BLOCK_DATA +=end BLOCK_TYPE +``` + +For example: + +``` +=begin head1 +Top level heading +=end head1 +``` + +This type of blocks is useful for creating headings, list items, code blocks, +etc. with multiple paragraphs. For example, + +* a multiline item of a list + +``` +=begin item +This is a paragraph in list item. + +This is another paragraph in the same list item. +=end item +``` + +* a code block + +``` +=begin code +#`( +A non-efficient recursive implementation of a power function using multi subs. +) + +multi pow( Real $base, 0 ) { 1 } + +multi pow( Real $base, Int $exp where * ≥ 0) { + $base * pow($base, $exp - 1) +} + +multi pow( Real $base ) { + pow($base, 2) +} + +say pow(3, 0); #=> 1 +say pow(4.2, 2); #=> 17.64 +say pow(6); #=> 36 +=end code +``` + +### Paragraph Blocks + +Paragraph blocks are introduced by a `=for` marker and terminated by +the next Pod directive or the first blank line (which is not considered to +be part of the block's contents). The `=for` marker is followed by the +`typename` of the block. The general syntax is + +``` +=for BLOCK_TYPE +BLOCK DATA +``` + +For example: + +``` +=for head1 +Top level heading +``` + +## Configuration Data + +Except for abbreviated blocks, both delimited blocks and paragraph +blocks can be supplied with configuration information about their +contents right after the `typename` of the block. Thus the following +are more general syntaxes for these blocks: + +* Delimited blocks + +``` +=begin BLOCK_TYPE OPTIONAL_CONFIG_INFO += ADDITIONAL_CONFIG_INFO +BLOCK_DATA +=end BLOCK_TYPE +``` + +* Paragraph blocks + +``` +=for BLOCK_TYPE OPTIONAL_CONFIG_INFO += ADDITIONAL_CONFIG_INFO +BLOCK DATA +``` + +The configuration information is provided in a format akin to the +["colon pair"](https://docs.perl6.org/language/glossary#index-entry-Colon_Pair) +syntax in Raku Perl 6. The following table is a simplified version of the +different ways in which configuration info can be supplied. Please go to +<https://docs.perl6.org/language/pod#Configuration_information> for a more +thorough treatment of the subject. + +| Value | Specify with... | Example | +| :-------- | :------ | :------ | +| List | :key($elem1, $elem2, ...) | :tags('Pod', 'Perl6') | +| Hash | :key{$key1 => $value1, ...} | :feeds{url => 'perl6.org'} | +| Boolean | :key/:key(True) | :skip-test(True) | +| Boolean | :!key/:key(False) | :!skip-test | +| String | :key('string') | :nonexec-reason('SyntaxError') | +| Int | :key(2) | :post-number(6) | + + +### Standard Configuration Options + +Pod provides a small number of standard configuration options that can +be applied uniformly to built-in block types. Some of them are: + +* `:numbered` + +This option specifies that the block is to be numbered. The most common +use of this option is to create numbered headings and ordered lists, but it +can be applied to any block. + +For example: + +``` +=for head1 :numbered +The Problem +=for head1 :numbered +The Solution +=for head2 :numbered +Analysis +=for head3 :numbered +Overview +``` + +* `:allow` + +The value of the `:allow` option must be a list of the (single-letter) names +of one or more formatting codes. Those codes will then remain active inside +the code block. The option is most often used on `=code` blocks to allow +mark-up within those otherwise verbatim blocks, though it can be used in any +block that contains verbatim text. + +Given the following snippet: + +``` +=begin code :allow('B', 'I') +B<sub> greet( $name ) { + B<say> "Hello, $nameI<!>"; +} +=end code +``` + +we get the following output: + +<pre><strong>sub</strong> greet( $name ) { + <strong>say</strong> "Hello, $name<em>!</em>"; +} +</pre> + +This is highly dependent on the format output. For example, while this works +when Pod is converted to HTML, it might not be preserved when converted +to Markdown. + +### Block Pre-configuration + +The `=config` directive allows you to prespecify standard configuration +information that is applied to every block of a particular type. +The general syntax for configuration directives is: + +``` +=config BLOCK_TYPE CONFIG OPTIONS += ADDITIONAL_CONFIG_INFO +``` + +For example, to specify that every heading level 1 be numbered, bold +and underlined, you preconfigure the `=head1` as follows: + +``` +=config head1 :formatted('B', 'U') :numbered +``` + +## Semantic Blocks + +All uppercase block typenames are reserved for specifying standard +documentation, publishing, source components, or meta-information. +Some of them are: + +``` +=NAME +=AUTHOR +=VERSION +=CREATED +=SYNOPSIS +=DESCRIPTION +=USAGE +``` + +Most of these blocks would typically be used in their full +delimited forms. For example, + +``` +=NAME B<Doc::Magic> + +=begin DESCRIPTION +This module helps you generate documentation automagically. +Not source code needed! Most of it is outsourced from a black hole. +=end DESCRIPTION + +=begin SYNOPSIS +=begin code + use Doc::Magic; + + my Doc::Magic $doc .= new(); + + my $result = $doc.create-documentation($fh); +=end code +=end SYNOPSIS + +=AUTHOR Authorius Docus +=VERSION 42 +``` + +## Miscellaneous + +### Notes + +Notes are rendered as footnotes and created by enclosing a note in a +`N<>` code. + +``` +In addition, the language is also multi-paradigmatic N<According to Wikipedia, +this means that it supports procedural, object-oriented, and functional +programming.> +``` + +### Keyboard Input + +To flag text as keyboard input enclose it in a `K<>` code. + +``` +Enter your name K<John Doe> +``` + +### Terminal Output + +To flag text as terminal output enclose it in `T<>` code. + +``` +Hello, T<John Doe> +``` + +### Unicode + +To include Unicode code points or HTML5 character references in +a Pod document, enclose them in a `E<>` code. + +For example: + +``` +Raku Perl 6 makes considerable use of the E<171> and E<187> characters. +Raku Perl 6 makes considerable use of the E<laquo> and E<raquo> characters. +``` + +is rendered as: + +Raku Perl 6 makes considerable use of the « and » characters. +Raku Perl 6 makes considerable use of the « and » characters. + +## Rendering Pod + +To generate any output (i.e., Markdown, HTML, Text, etc.), you need to +have the Raku Perl 6 compiler installed. In addition, you must install +a module (e.g., `Pod::To::Markdown`, `Pod::To::HTML`, `Pod::To::Text`, etc.) +that generates your desired output from Pod. + +For instructions about installing Raku Perl 6, +[look here](https://perl6.org/downloads/). + +Run the following command to generate a certain output: + +``` +perl6 --doc=TARGET input.pod6 > output.html +``` + +with `TARGET` being `Markdown`, `HTML`, `Text`, etc. Thus to generate +Markdown from Pod, run this: + +``` +perl6 --doc=Markdown input.pod6 > output.html +``` + +## Accessing Pod + +In order to access Pod documentation from within a Raku Perl 6 program, +it is required to use the special `=` twigil (e.g., `$=pod`, `$=SYNOPSIS`,etc). + +The `$=` construct provides the introspection over the Pod structure, +producing a `Pod::Block` tree root from which it is possible to access +the whole structure of the Pod document. + +If we place the following piece of Raku Perl 6 code and the Pod documentation +in the section [Semantic blocks](#semantic-blocks) in the same file: + +``` +my %used-directives; +for $=pod -> $pod-item { + for $pod-item.contents -> $pod-block { + next unless $pod-block ~~ Pod::Block::Named; + %used-directives{$pod-block.name} = True; + } +} + +say %used-directives.keys.join("\n"); +``` + +we get the following output: + +``` +SYNOPSIS +NAME +VERSION +AUTHOR +DESCRIPTION +``` + +## Additional Information + +* <https://docs.perl6.org/language/pod> for the Pod documentation. +* <https://docs.perl6.org/language/tables> for advices about Pod tables. +* <https://design.perl6.org/S26.html> for the Pod specification. diff --git a/perl6.html.markdown b/perl6.html.markdown index 7c776db4..cb64b646 100644 --- a/perl6.html.markdown +++ b/perl6.html.markdown @@ -13,24 +13,28 @@ least the next hundred years. The primary Perl 6 compiler is called [Rakudo](http://rakudo.org), which runs on the JVM and [the MoarVM](http://moarvm.com). -Meta-note : double pound signs (##) are used to indicate paragraphs, while -single pound signs (#) indicate notes. +Meta-note: double pound signs (`##`) are used to indicate paragraphs, +while single pound signs (`#`) indicate notes. `#=>` represents the output of a command. ```perl6 -# Single line comment start with a pound +# Single line comments start with a pound sign. -#`( - Multiline comments use #` and a quoting construct. +#`( Multiline comments use #` and a quoting construct. (), [], {}, 「」, etc, will work. ) + +# Use the same syntax for multiline comments to embed comments. +for #`(each element in) @array { + put #`(or print element) $_ #`(with newline); +} ``` ## Variables ```perl6 -## In Perl 6, you declare a lexical variable using `my` +## In Perl 6, you declare a lexical variable using the `my` keyword: my $variable; ## Perl 6 has 3 basic types of variables: scalars, arrays, and hashes. ``` @@ -38,79 +42,81 @@ my $variable; ### Scalars ```perl6 -# Scalars represent a single value. They start with a `$` - +# Scalars represent a single value. They start with the `$` sigil: my $str = 'String'; -# double quotes allow for interpolation (which we'll see later): + +# Double quotes allow for interpolation (which we'll see later): my $str2 = "String"; ## Variable names can contain but not end with simple quotes and dashes, -## and can contain (and end with) underscores : -my $weird'variable-name_ = 5; # works ! +## and can contain (and end with) underscores: +my $person's-belongings = 'towel'; # this works! -my $bool = True; # `True` and `False` are Perl 6's boolean values. -my $inverse = !$bool; # You can invert a bool with the prefix `!` operator -my $forced-bool = so $str; # And you can use the prefix `so` operator - # which turns its operand into a Bool +my $bool = True; # `True` and `False` are Perl 6's boolean values. +my $inverse = !$bool; # Invert a bool with the prefix `!` operator. +my $forced-bool = so $str; # And you can use the prefix `so` operator +$forced-bool = ?$str; # to turn its operand into a Bool. Or use `?`. ``` ### Arrays and Lists ```perl6 -## Arrays represent multiple values. Their name start with `@`. -## Lists are similar but are an immutable type. +## Arrays represent multiple values. An array variable starts with the `@` +## sigil. Unlike lists, from which arrays inherit, arrays are mutable. my @array = 'a', 'b', 'c'; -# equivalent to : +# equivalent to: my @letters = <a b c>; # array of words, delimited by space. # Similar to perl5's qw, or Ruby's %w. -my @array = 1, 2, 3; +@array = 1, 2, 3; -say @array[2]; # Array indices start at 0 -- This is the third element +say @array[2]; # Array indices start at 0. Here the third element + # is being accessed. -say "Interpolate all elements of an array using [] : @array[]"; -#=> Interpolate all elements of an array using [] : 1 2 3 +say "Interpolate an array using []: @array[]"; +#=> Interpolate an array using []: 1 2 3 -@array[0] = -1; # Assign a new value to an array index -@array[0, 1] = 5, 6; # Assign multiple values +@array[0] = -1; # Assigning a new value to an array index +@array[0, 1] = 5, 6; # Assigning multiple values my @keys = 0, 2; @array[@keys] = @letters; # Assignment using an array containing index values -say @array; #=> a 6 b +say @array; #=> a 6 b ``` ### Hashes, or key-value Pairs. ```perl6 -## Hashes are pairs of keys and values. -## You can construct a Pair object using the syntax `Key => Value`. -## Hash tables are very fast for lookup, and are stored unordered. -## Keep in mind that keys get "flattened" in hash context, and any duplicated -## keys are deduplicated. -my %hash = 1 => 2, - 3 => 4; -my %hash = foo => "bar", # keys get auto-quoted - "some other" => "value", # trailing commas are okay - ; +## Hashes are pairs of keys and values. You can construct a `Pair` object +## using the syntax `Key => Value`. Hash tables are very fast for lookup, +## and are stored unordered. Keep in mind that keys get "flattened" in hash +## context, and any duplicated keys are deduplicated. +my %hash = 'a' => 1, 'b' => 2; + +%hash = a => 1, # keys get auto-quoted when => (fat comma) is used. + b => 2, # Trailing commas are okay. +; ## Even though hashes are internally stored differently than arrays, ## Perl 6 allows you to easily create a hash from an even numbered array: -my %hash = <key1 value1 key2 value2>; - -my %hash = key1 => 'value1', key2 => 'value2'; # same result as above - -## You can also use the "colon pair" syntax: -## (especially handy for named parameters that you'll see later) -my %hash = :w(1), # equivalent to `w => 1` - # this is useful for the `True` shortcut: - :truey, # equivalent to `:truey(True)`, or `truey => True` - # and for the `False` one: - :!falsey, # equivalent to `:falsey(False)`, or `falsey => False` - ; - -say %hash{'key1'}; # You can use {} to get the value from a key -say %hash<key2>; # If it's a string, you can actually use <> - # (`{key1}` doesn't work, as Perl6 doesn't have barewords) +%hash = <key1 value1 key2 value2>; # Or: +%hash = "key1", "value1", "key2", "value2"; + +%hash = key1 => 'value1', key2 => 'value2'; # same result as above + +## You can also use the "colon pair" syntax. This syntax is especially +## handy for named parameters that you'll see later. +%hash = :w(1), # equivalent to `w => 1` + :truey, # equivalent to `:truey(True)` or `truey => True` + :!falsey, # equivalent to `:falsey(False)` or `falsey => False` +; +## The :truey and :!falsey constructs are known as the +## `True` and `False` shortcuts respectively. + +say %hash{'key1'}; # You can use {} to get the value from a key. +say %hash<key2>; # If it's a string without spaces, you can actually use + # <> (quote-words operator). `{key1}` doesn't work, + # as Perl6 doesn't have barewords. ``` ## Subs @@ -120,112 +126,112 @@ say %hash<key2>; # If it's a string, you can actually use <> ## created with the `sub` keyword. sub say-hello { say "Hello, world" } -## You can provide (typed) arguments. -## If specified, the type will be checked at compile-time if possible, -## otherwise at runtime. -sub say-hello-to(Str $name) { +## You can provide (typed) arguments. If specified, the type will be checked +## at compile-time if possible, otherwise at runtime. +sub say-hello-to( Str $name ) { say "Hello, $name !"; } -## A sub returns the last value of the block. -sub return-value { - 5; -} -say return-value; # prints 5 -sub return-empty { -} -say return-empty; # prints Nil +## A sub returns the last value of the block. Similarly, the semicolon in +## the last can be omitted. +sub return-value { 5 } +say return-value; # prints 5 -## Some control flow structures produce a value, like if: +sub return-empty { } +say return-empty; # prints Nil + +## Some control flow structures produce a value, like `if`: sub return-if { - if True { - "Truthy"; - } + if True { "Truthy" } } -say return-if; # prints Truthy +say return-if; # prints Truthy -## Some don't, like for: +## Some don't, like `for`: sub return-for { - for 1, 2, 3 { } + for 1, 2, 3 { 'Hi' } } -say return-for; # prints Nil +say return-for; # prints Nil -## A sub can have optional arguments: -sub with-optional($arg?) { # the "?" marks the argument optional - say "I might return `(Any)` (Perl's 'null'-like value) if I don't have - an argument passed, or I'll return my argument"; +## Positional arguments are required by default. To make them optional, use +## the `?` after the parameters' names. +sub with-optional( $arg? ) { + # This sub returns `(Any)` (Perl's null-like value) if + # no argument is passed. Otherwise, it returns its argument. $arg; } -with-optional; # returns Any -with-optional(); # returns Any -with-optional(1); # returns 1 +with-optional; # returns Any +with-optional(); # returns Any +with-optional(1); # returns 1 -## You can also give them a default value when they're not passed: -sub hello-to($name = "World") { - say "Hello, $name !"; +## You can also give them a default value when they're not passed. +## Required parameters must come before optional ones. +sub greeting( $name, $type = "Hello" ) { + say "$type, $name!"; } -hello-to; #=> Hello, World ! -hello-to(); #=> Hello, World ! -hello-to('You'); #=> Hello, You ! + +greeting("Althea"); #=> Hello, Althea! +greeting("Arthur", "Good morning"); #=> Good morning, Arthur! ## You can also, by using a syntax akin to the one of hashes -## (yay unified syntax !), pass *named* arguments to a `sub`. -## They're optional, and will default to "Any". -sub with-named($normal-arg, :$named) { - say $normal-arg + $named; +## (yay unified syntax !), pass *named* arguments to a `sub`. They're +## optional, and will default to "Any". +sub with-named( $normal-arg, :$named ) { + say $normal-arg + $named; } with-named(1, named => 6); #=> 7 -## There's one gotcha to be aware of, here: -## If you quote your key, Perl 6 won't be able to see it at compile time, -## and you'll have a single Pair object as a positional parameter, -## which means this fails: -with-named(1, 'named' => 6); -with-named(2, :named(5)); #=> 7 +## There's one gotcha to be aware of, here: If you quote your key, Perl 6 +## won't be able to see it at compile time, and you'll have a single `Pair` +## object as a positional parameter, which means +## `with-named(1, 'named' => 6);` fails. + +with-named(2, :named(5)); #=> 7 -## To make a named argument mandatory, you can use `?`'s inverse, `!` -sub with-mandatory-named(:$str!) { - say "$str !"; +## To make a named argument mandatory, you can append `!` to the parameter, +## which is the inverse of `?`: +sub with-mandatory-named( :$str! ) { + say "$str!"; } -with-mandatory-named(str => "My String"); #=> My String ! -with-mandatory-named; # run time error: "Required named parameter not passed" -with-mandatory-named(3);# run time error:"Too many positional parameters passed" +with-mandatory-named(str => "My String"); #=> My String! +with-mandatory-named; # runtime error:"Required named parameter not passed" +with-mandatory-named(3);# runtime error:"Too many positional parameters passed" -## If a sub takes a named boolean argument ... -sub takes-a-bool($name, :$bool) { - say "$name takes $bool"; +## If a sub takes a named boolean argument... +sub takes-a-bool( $name, :$bool ) { + say "$name takes $bool"; } ## ... you can use the same "short boolean" hash syntax: -takes-a-bool('config', :bool); # config takes True -takes-a-bool('config', :!bool); # config takes False +takes-a-bool('config', :bool); #=> config takes True +takes-a-bool('config', :!bool); #=> config takes False -## You can also provide your named arguments with defaults: -sub named-def(:$def = 5) { - say $def; +## You can also provide your named arguments with default values: +sub named-def( :$def = 5 ) { + say $def; } -named-def; #=> 5 +named-def; #=> 5 named-def(def => 15); #=> 15 ## Since you can omit parenthesis to call a function with no arguments, -## you need "&" in the name to store `say-hello` in a variable. +## you need `&` in the name to store `say-hello` in a variable. This means +## `&say-hello` is a code object and not a subroutine call. my &s = &say-hello; -my &other-s = sub { say "Anonymous function !" } +my &other-s = sub { say "Anonymous function!" } -## A sub can have a "slurpy" parameter, or "doesn't-matter-how-many" -sub as-many($head, *@rest) { #`*@` (slurpy) will "take everything else" -## Note: you can have parameters *before* a slurpy one (like here), -## but not *after*. - say @rest.join(' / ') ~ " !"; +## A sub can have a "slurpy" parameter, or "doesn't-matter-how-many". For +## this, you must use `*@` (slurpy) which will "take everything else". You can +## have as many parameters *before* a slurpy one, but not *after*. +sub as-many($head, *@rest) { + say @rest.join(' / ') ~ " !"; } -say as-many('Happy', 'Happy', 'Birthday'); #=> Happy / Birthday ! - # Note that the splat (the *) did not - # consume the parameter before. +say as-many('Happy', 'Happy', 'Birthday');#=> Happy / Birthday ! + # Note that the splat (the *) did not + # consume the parameter before it. -## You can call a function with an array using the -## "argument list flattening" operator `|` -## (it's not actually the only role of this operator, but it's one of them) +## You can call a function with an array using the "argument list flattening" +## operator `|` (it's not actually the only role of this operator, +## but it's one of them). sub concat3($a, $b, $c) { - say "$a, $b, $c"; + say "$a, $b, $c"; } concat3(|@array); #=> a, b, c # `@array` got "flattened" as a part of the argument list @@ -234,159 +240,188 @@ concat3(|@array); #=> a, b, c ## Containers ```perl6 -## In Perl 6, values are actually stored in "containers". -## The assignment operator asks the container on the left to store the value on -## its right. When passed around, containers are marked as immutable. -## Which means that, in a function, you'll get an error if you try to -## mutate one of your arguments. -## If you really need to, you can ask for a mutable container using `is rw`: -sub mutate($n is rw) { - $n++; - say "\$n is now $n !"; +## In Perl 6, values are actually stored in "containers". The assignment +## operator asks the container on the left to store the value on its right. +## When passed around, containers are marked as immutable which means that, +## in a function, you'll get an error if you try to mutate one of your +## arguments. If you really need to, you can ask for a mutable container by +## using the `is rw` trait: +sub mutate( $n is rw ) { + $n++; } my $m = 42; -mutate $m; # $m is now 43 ! +mutate $m; #=> 43 +say $m; #=> 43 -## This works because we are passing the container $m to mutate. If we try -## to just pass a number instead of passing a variable it won't work because -## there is no container being passed and integers are immutable by themselves: +## This works because we are passing the container $m to the `mutate` sub. +## If we try to just pass a number instead of passing a variable it won't work +## because there is no container being passed and integers are immutable by +## themselves: mutate 42; # Parameter '$n' expected a writable container, but got Int value -## If what you want a copy instead, use `is copy`. +## Similar error would be obtained, if a bound variable is passed to +## to the subroutine: + +my $v := 50; # binding 50 to the variable $v +mutate $v; # Parameter '$n' expected a writable container, but got Int value + +## If what you want is a copy instead, use the `is copy` trait which will +## cause the argument to be copied and allow you to modify the argument +## inside the routine. ## A sub itself returns a container, which means it can be marked as rw: my $x = 42; sub x-store() is rw { $x } x-store() = 52; # in this case, the parentheses are mandatory # (else Perl 6 thinks `x-store` is an identifier) -say $x; #=> 52 +say $x; #=> 52 ``` ## Control Flow Structures + ### Conditionals ```perl6 ## - `if` ## Before talking about `if`, we need to know which values are "Truthy" -## (represent True), and which are "Falsey" (or "Falsy") -- represent False. -## Only these values are Falsey: 0, (), {}, "", Nil, A type (like `Str` or -## `Int`) and of course False itself. -## Every other value is Truthy. +## (represent True), and which are "Falsey" (represent False). Only these +## values are Falsey: 0, (), {}, "", Nil, A type (like `Str` or `Int`) and +## of course False itself. Any other value is Truthy. if True { - say "It's true !"; + say "It's true!"; } unless False { - say "It's not false !"; + say "It's not false!"; } -## As you can see, you don't need parentheses around conditions. -## However, you do need the brackets around the "body" block: -# if (true) say; # This doesn't work ! +## As you can see, you don't need parentheses around conditions. However, you +## do need the curly braces around the "body" block. For example, +## `if (true) say;` doesn't work. -## You can also use their postfix versions, with the keyword after: -say "Quite truthy" if True; +## You can also use their statement modifier (postfix) versions: +say "Quite truthy" if True; #=> Quite truthy +say "Quite falsey" unless False; #=> Quite falsey -## - Ternary conditional, "?? !!" (like `x ? y : z` in some other languages) -## returns $value-if-true if the condition is true and $value-if-false -## if it is false. -## my $result = $value condition ?? $value-if-true !! $value-if-false; +## - Ternary operator, "x ?? y !! z" +## This returns $value-if-true if the condition is true and $value-if-false +## if it is false. +## my $result = condition ?? $value-if-true !! $value-if-false; my $age = 30; say $age > 18 ?? "You are an adult" !! "You are under 18"; +#=> You are an adult ``` -### given/when, or switch +### given/when, or Perl 6's switch construct ```perl6 -## - `given`-`when` looks like other languages' `switch`, but is much more +## `given...when` looks like other languages' `switch`, but is much more ## powerful thanks to smart matching and Perl 6's "topic variable", $_. ## -## This variable contains the default argument of a block, -## a loop's current iteration (unless explicitly named), etc. +## The topic variable $_ contains the default argument of a block, a loop's +## current iteration (unless explicitly named), etc. ## ## `given` simply puts its argument into `$_` (like a block would do), ## and `when` compares it using the "smart matching" (`~~`) operator. ## ## Since other Perl 6 constructs use this variable (as said before, like `for`, -## blocks, etc), this means the powerful `when` is not only applicable along +## blocks, etc), this means the powerful `when` is not only applicable along ## with a `given`, but instead anywhere a `$_` exists. given "foo bar" { - say $_; #=> foo bar - when /foo/ { # Don't worry about smart matching yet – just know `when` uses it - # This is equivalent to `if $_ ~~ /foo/`. - say "Yay !"; - } - when $_.chars > 50 { # smart matching anything with True is True, - # i.e. (`$a ~~ True`) - # so you can also put "normal" conditionals. - # This `when` is equivalent to this `if`: - # if $_ ~~ ($_.chars > 50) {...} - # Which means: - # if $_.chars > 50 {...} - say "Quite a long string !"; - } - default { # same as `when *` (using the Whatever Star) - say "Something else" - } + say $_; #=> foo bar + when /foo/ { # Don't worry about smart matching yet. Just know + say "Yay !"; # `when` uses it. This is equivalent to `if $_ ~~ /foo/`. + + } + when $_.chars > 50 { # smart matching anything with True is True, + # i.e. (`$a ~~ True`) + # so you can also put "normal" conditionals. + # This `when` is equivalent to this `if`: + # `if $_ ~~ ($_.chars > 50) {...}` + # which means: `if $_.chars > 50 {...}` + say "Quite a long string !"; + } + default { # same as `when *` (using the Whatever Star) + say "Something else" + } } ``` ### Looping constructs ```perl6 -## - `loop` is an infinite loop if you don't pass it arguments, -## but can also be a C-style `for` loop: +## - `loop` is an infinite loop if you don't pass it arguments, but can also +## be a C-style `for` loop: loop { - say "This is an infinite loop !"; - last; # last breaks out of the loop, like the `break` keyword in other - # languages + say "This is an infinite loop !"; + last; # last breaks out of the loop, like + # the `break` keyword in other languages } loop (my $i = 0; $i < 5; $i++) { - next if $i == 3; # `next` skips to the next iteration, like `continue` + next if $i == 3; # `next` skips to the next iteration, like `continue` # in other languages. Note that you can also use postfix # conditionals, loops, etc. - say "This is a C-style for loop !"; + say "This is a C-style for loop!"; } -## - `for` - Passes through an array +## - `for` - Iterating through an array + +my @array = 1, 2, 6, 7, 3; + +## Accessing the array's elements with the topic variable $_. +for @array { + say "I've got $_ !"; +} + +## Accessing the array's elements with a "pointy block", `->`. +## Here each element is read-only. for @array -> $variable { - say "I've got $variable !"; + say "I've got $variable !"; } -## As we saw with given, for's default "current iteration" variable is `$_`. -## That means you can use `when` in a `for` just like you were in a `given`. +## Accessing the array's elements with a "doubly pointy block", `<->`. +## Here each element is read-write so mutating `$variable` mutates +## that element in the array. +for @array <-> $variable { + say "I've got $variable !"; +} + +## As we saw with given, a for loop's default "current iteration" variable +## is `$_`. That means you can use `when` in a `for`loop just like you were +## able to in a `given`. for @array { - say "I've got $_"; + say "I've got $_"; - .say; # This is also allowed. - # A dot call with no "topic" (receiver) is sent to `$_` by default - $_.say; # the above and this are equivalent. + .say; # This is also allowed. A dot call with no "topic" (receiver) + # is sent to `$_` by default + $_.say; # This is equivalent to the above statement. } for @array { - # You can... - next if $_ == 3; # Skip to the next iteration (`continue` in C-like languages) - redo if $_ == 4; # Re-do the iteration, keeping the same topic variable (`$_`) - last if $_ == 5; # Or break out of a loop (like `break` in C-like languages) + # You can... + next if $_ == 3; # Skip to the next iteration (`continue` in C-like lang.) + redo if $_ == 4; # Re-do iteration, keeping the same topic variable (`$_`) + last if $_ == 5; # Or break out of loop (like `break` in C-like lang.) } -## The "pointy block" syntax isn't specific to for. -## It's just a way to express a block in Perl6. +## The "pointy block" syntax isn't specific to the `for` loop. It's just a way +## to express a block in Perl 6. +sub long-computation { "Finding factors of large primes" } if long-computation() -> $result { - say "The result is $result"; + say "The result is $result."; } ``` ## Operators ```perl6 -## Since Perl languages are very much operator-based languages, -## Perl 6 operators are actually just funny-looking subroutines, in syntactic +## Since Perl languages are very much operator-based languages, Perl 6 +## operators are actually just funny-looking subroutines, in syntactic ## categories, like infix:<+> (addition) or prefix:<!> (bool not). ## The categories are: @@ -394,105 +429,127 @@ if long-computation() -> $result { ## - "postfix": after (like `++` in `$a++`). ## - "infix": in between (like `*` in `4 * 3`). ## - "circumfix": around (like `[`-`]` in `[1, 2]`). -## - "post-circumfix": around, after another term (like `{`-`}` in -## `%hash{'key'}`) +## - "post-circumfix": around, after another term (like `{`-`}` in +## `%hash{'key'}`) ## The associativity and precedence list are explained below. -## Alright, you're set to go ! +## Alright, you're set to go! -## * Equality Checking +## Equality Checking +##------------------ ## - `==` is numeric comparison -3 == 4; # False -3 != 4; # True +3 == 4; #=> False +3 != 4; #=> True ## - `eq` is string comparison -'a' eq 'b'; -'a' ne 'b'; # not equal -'a' !eq 'b'; # same as above +'a' eq 'b'; #=> False +'a' ne 'b'; #=> True, not equal +'a' !eq 'b'; #=> True, same as above ## - `eqv` is canonical equivalence (or "deep equality") -(1, 2) eqv (1, 3); +(1, 2) eqv (1, 3); #=> False +(1, 2) eqv (1, 2); #=> True +Int === Int #=> True -## - Smart Match Operator: `~~` +## - `~~` is the smart match operator ## Aliases the left hand side to $_ and then evaluates the right hand side. ## Here are some common comparison semantics: -## String or Numeric Equality - +## String or numeric equality 'Foo' ~~ 'Foo'; # True if strings are equal. -12.5 ~~ 12.50; # True if numbers are equal. +12.5 ~~ 12.50; # True if numbers are equal. ## Regex - For matching a regular expression against the left side. -## Returns a (Match) object, which evaluates as True if regexp matches. +## Returns a `Match` object, which evaluates as True if regexp matches. my $obj = 'abc' ~~ /a/; -say $obj; # 「a」 -say $obj.WHAT; # (Match) +say $obj; #=> 「a」 +say $obj.WHAT; #=> (Match) ## Hashes -'key' ~~ %hash; # True if key exists in hash - -## Type - Checks if left side "has type" (can check superclasses and roles) - -1 ~~ Int; # True +'key' ~~ %hash; # True if key exists in hash. -## Smart-matching against a boolean always returns that boolean (and will warn). +## Type - Checks if left side "is of type" (can check superclasses and +## roles). +say 1 ~~ Int; #=> True -1 ~~ True; # True -False ~~ True; # True +## Smart-matching against a boolean always returns that boolean +## (and will warn). +say 1 ~~ True; #=> True +say False ~~ True; #=> True -## General syntax is $arg ~~ &bool-returning-function; -## For a complete list of combinations, use this table: +## General syntax is `$arg ~~ &bool-returning-function;`. For a complete list +## of combinations, use this table: ## http://perlcabal.org/syn/S03.html#Smart_matching -## You also, of course, have `<`, `<=`, `>`, `>=`. -## Their string equivalent are also available : `lt`, `le`, `gt`, `ge`. -3 > 4; +## Of course, you also use `<`, `<=`, `>`, `>=` for numeric comparison. +## Their string equivalent are also available: `lt`, `le`, `gt`, `ge`. +3 > 4; # False +3 >= 4; # False +3 < 4; # True +3 <= 4; # True +'a' gt 'b'; # False +'a' ge 'b'; # False +'a' lt 'b'; # True +'a' le 'b'; # True + + +## Range constructor +##------------------ +3 .. 7; # 3 to 7, both included +3 ..^ 7; # 3 to 7, exclude right endpoint. +3 ^.. 7; # 3 to 7, exclude left endpoint. Same as `4..7`. +3 ^..^ 7; # 3 to 7, exclude both endpoints. Same as `4..6`. -## * Range constructors -3 .. 7; # 3 to 7, both included -## `^` on either side them exclusive on that side : -3 ^..^ 7; # 3 to 7, not included (basically `4 .. 6`) ## This also works as a shortcut for `0..^N`: -^10; # means 0..^10 +^10; # means 0..^10 ## This also allows us to demonstrate that Perl 6 has lazy/infinite arrays, ## using the Whatever Star: -my @array = 1..*; # 1 to Infinite ! `1..Inf` is the same. -say @array[^10]; # you can pass arrays as subscripts and it'll return - # an array of results. This will print - # "1 2 3 4 5 6 7 8 9 10" (and not run out of memory !) -## Note : when reading an infinite list, Perl 6 will "reify" the elements +my @array = 1..*; # 1 to Infinite! Equivalent to `1..Inf`. +say @array[^10]; # You can pass ranges as subscripts and it'll return + # an array of results. This will print + # "1 2 3 4 5 6 7 8 9 10" (and not run out of memory!) + +## Note: when reading an infinite list, Perl 6 will "reify" the elements ## it needs, then keep them in memory. They won't be calculated more than once. ## It also will never calculate more elements that are needed. -## Trying -## An array subscript can also be a closure. -## It'll be called with the length as the argument +## An array subscript can also be a closure. It'll be called with the length +## as the argument: say join(' ', @array[15..*]); #=> 15 16 17 18 19 ## which is equivalent to: say join(' ', @array[-> $n { 15..$n }]); + ## Note: if you try to do either of those with an infinite array, -## you'll trigger an infinite loop (your program won't finish) +## you'll trigger an infinite loop (your program won't finish). -## You can use that in most places you'd expect, even assigning to an array +## You can use that in most places you'd expect, even when assigning to +## an array: my @numbers = ^20; -## Here numbers increase by "6"; more on `...` operator later. -my @seq = 3, 9 ... * > 95; # 3 9 15 21 27 [...] 81 87 93 99; +## Here the numbers increase by 6, like an arithmetic sequence; more on the +## sequence (`...`) operator later. +my @seq = 3, 9 ... * > 95; # 3 9 15 21 27 [...] 81 87 93 99; @numbers[5..*] = 3, 9 ... *; # even though the sequence is infinite, # only the 15 needed values will be calculated. -say @numbers; #=> 0 1 2 3 4 3 9 15 21 [...] 81 87 - # (only 20 values) +say @numbers; #=> 0 1 2 3 4 3 9 15 21 [...] 81 87 + # (only 20 values) -## * And &&, Or || -3 && 4; # 4, which is Truthy. Calls `.Bool` on `4` and gets `True`. -0 || False; # False. Calls `.Bool` on `0` +## and (&&), or (||) +##------------------ +3 && 4; # 4, which is Truthy. Calls `.Bool` on both 3 and 4 and gets `True` + # so it returns 4 since both are `True`. +3 && 0; # 0 +0 && 4; # 0 -## * Short-circuit (and tight) versions of the above -# Returns the first argument that evaluates to False, or the last argument. +0 || False; # False. Calls `.Bool` on `0` and `False` which are both `False` + # so it retusns `False` since both are `False`. + +## Short-circuit (and tight) versions of the above +## Return the first argument that evaluates to False, or the last argument. my ( $a, $b, $c ) = 1, 0, 2; $a && $b && $c; # Returns 0, the first False value @@ -500,203 +557,242 @@ $a && $b && $c; # Returns 0, the first False value ## || Returns the first argument that evaluates to True $b || $a; # 1 -## And because you're going to want them, -## you also have compound assignment operators: -$a *= 2; # multiply and assignment. Equivalent to $a = $a * 2; -$b %%= 5; # divisible by and assignment +## And because you're going to want them, you also have compound assignment +## operators: +$a *= 2; # multiply and assignment. Equivalent to $a = $a * 2; +$b %%= 5; # divisible by and assignment. Equivalent to $b = $b %% 2; +$c div= 3; # return divisor and assignment. Equivalent to $c = $c div 3; +$d mod= 4; # return remainder and assignment. Equivalent to $d = $d mod 4; @array .= sort; # calls the `sort` method and assigns the result back ``` -## More on subs ! +## More on subs! ```perl6 -## As we said before, Perl 6 has *really* powerful subs. We're going to see -## a few more key concepts that make them better than in any other language :-). +## As we said before, Perl 6 has *really* powerful subs. We're going +## to see a few more key concepts that make them better than in any +## other language :-). ``` -### Unpacking ! +### Unpacking! ```perl6 -## It's the ability to "extract" arrays and keys (AKA "destructuring"). -## It'll work in `my`s and in parameter lists. +## Unpacking is the ability to "extract" arrays and keys +## (AKA "destructuring"). It'll work in `my`s and in parameter lists. my ($f, $g) = 1, 2; -say $f; #=> 1 -my ($, $, $h) = 1, 2, 3; # keep the non-interesting anonymous -say $h; #=> 3 +say $f; #=> 1 +my ($, $, $h) = 1, 2, 3; # keep the non-interesting values anonymous (`$`) +say $h; #=> 3 my ($head, *@tail) = 1, 2, 3; # Yes, it's the same as with "slurpy subs" my (*@small) = 1; -sub unpack_array(@array [$fst, $snd]) { - say "My first is $fst, my second is $snd ! All in all, I'm @array[]."; +sub unpack_array( @array [$fst, $snd] ) { + say "My first is $fst, my second is $snd! All in all, I'm @array[]."; # (^ remember the `[]` to interpolate the array) } -unpack_array(@tail); #=> My first is 2, my second is 3 ! All in all, I'm 2 3 +unpack_array(@tail); #=> My first is 2, my second is 3! All in all, I'm 2 3. ## If you're not using the array itself, you can also keep it anonymous, ## much like a scalar: -sub first-of-array(@ [$fst]) { $fst } +sub first-of-array( @ [$fst] ) { $fst } first-of-array(@small); #=> 1 -first-of-array(@tail); # Throws an error "Too many positional parameters passed" - # (which means the array is too big). +first-of-array(@tail); # Error: "Too many positional parameters passed" + # (which means the array is too big). -## You can also use a slurp ... +## You can also use a slurp... sub slurp-in-array(@ [$fst, *@rest]) { # You could keep `*@rest` anonymous - say $fst + @rest.elems; # `.elems` returns a list's length. - # Here, `@rest` is `(3,)`, since `$fst` holds the `2`. + say $fst + @rest.elems; # `.elems` returns a list's length. + # Here, `@rest` is `(3,)`, since `$fst` + # holds the `2`. } -slurp-in-array(@tail); #=> 3 +slurp-in-array(@tail); #=> 3 ## You could even extract on a slurpy (but it's pretty useless ;-).) -sub fst(*@ [$fst]) { # or simply : `sub fst($fst) { ... }` - say $fst; +sub fst(*@ [$fst]) { # or simply: `sub fst($fst) { ... }` + say $fst; } -fst(1); #=> 1 +fst(1); #=> 1 fst(1, 2); # errors with "Too many positional parameters passed" -## You can also destructure hashes (and classes, which you'll learn about later) -## The syntax is basically `%hash-name (:key($variable-to-store-value-in))`. +## You can also destructure hashes (and classes, which you'll learn about +## later). The syntax is basically the same as +## `%hash-name (:key($variable-to-store-value-in))`. ## The hash can stay anonymous if you only need the values you extracted. -sub key-of(% (:value($val), :qua($qua))) { - say "Got val $val, $qua times."; +sub key-of( % (:value($val), :qua($qua)) ) { + say "Got val $val, $qua times."; } -## Then call it with a hash: (you need to keep the brackets for it to be a hash) -key-of({value => 'foo', qua => 1}); +## Then call it with a hash. You need to keep the curly braces for it to be a +## hash or use `%()` instead to indicate a hash is being passed. +key-of({value => 'foo', qua => 1}); #=> Got val foo, 1 times. +key-of(%(value => 'foo', qua => 1)); #=> Got val foo, 1 times. #key-of(%hash); # the same (for an equivalent `%hash`) -## The last expression of a sub is returned automatically -## (though you may use the `return` keyword, of course): -sub next-index($n) { - $n + 1; +## The last expression of a sub is returned automatically (though you may +## indicate explicitly by using the `return` keyword, of course): +sub next-index( $n ) { + $n + 1; } my $new-n = next-index(3); # $new-n is now 4 -## This is true for everything, except for the looping constructs -## (due to performance reasons): there's reason to build a list -## if we're just going to discard all the results. -## If you still want to build one, you can use the `do` statement prefix: -## (or the `gather` prefix, which we'll see later) -sub list-of($n) { - do for ^$n { # note the use of the range-to prefix operator `^` (`0..^N`) - $_ # current loop iteration - } +## This is true for everything, except for the looping constructs (due to +## performance reasons): there's no reason to build a list if we're just going to +## discard all the results. If you still want to build one, you can use the +## `do` statement prefix or the `gather` prefix, which we'll see later: + +sub list-of( $n ) { + do for ^$n { # note the range-to prefix operator `^` (`0..^N`) + $_ # current loop iteration known as the "topic" variable + } } my @list3 = list-of(3); #=> (0, 1, 2) ``` -### lambdas +### lambdas (or anonymous subroutines) ```perl6 -## You can create a lambda with `-> {}` ("pointy block") or `{}` ("block") -my &lambda = -> $argument { "The argument passed to this lambda is $argument" } +## You can create a lambda with `-> {}` ("pointy block") , +## `{}` ("block") or `sub {}`. + +my &lambda1 = -> $argument { + "The argument passed to this lambda is $argument" +} + +my &lambda2 = { + "The argument passed to this lambda is $_" +} + +my &lambda3 = sub ($argument) { + "The argument passed to this lambda is $argument" +} + ## `-> {}` and `{}` are pretty much the same thing, except that the former can ## take arguments, and that the latter can be mistaken as a hash by the parser. -## We can, for example, add 3 to each value of an array using map: +## We can, for example, add 3 to each value of an array using the +## `map` function with a lambda: my @arrayplus3 = map({ $_ + 3 }, @array); # $_ is the implicit argument ## A sub (`sub {}`) has different semantics than a block (`{}` or `-> {}`): ## A block doesn't have a "function context" (though it can have arguments), -## which means that if you return from it, -## you're going to return from the parent function. Compare: -sub is-in(@array, $elem) { - # this will `return` out of the `is-in` sub - # once the condition evaluated to True, the loop won't be run anymore - map({ return True if $_ == $elem }, @array); -} -sub truthy-array(@array) { - # this will produce an array of `True` and `False`: - # (you can also say `anon sub` for "anonymous subroutine") - map(sub ($i) { if $i { return True } else { return False } }, @array); - # ^ the `return` only returns from the anonymous `sub` -} - -## You can also use the "whatever star" to create an anonymous function +## which means that if you return from it, you're going to return from the +## parent function. Compare: +sub is-in( @array, $elem ) { + # this will `return` out of the `is-in` sub once the condition evaluated + ## to True, the loop won't be run anymore. + map({ return True if $_ == $elem }, @array); +} +## with: +sub truthy-array( @array ) { + # this will produce an array of `True` and `False`: + # (you can also say `anon sub` for "anonymous subroutine") + map(sub ($i) { if $i { return True } else { return False } }, @array); + # ^ the `return` only returns from the anonymous `sub` +} + +## The `anon` declarator can be used to create an anonymous sub from a +## regular subroutine. The regular sub knows its name but its symbol is +## prevented from getting installed in the lexical scope, the method table +## and everywhere else. + +my $anon-sum = anon sub summation(*@a) { [+] *@a } +say $anon-sum.name; #=> summation +say $anon-sum(2, 3, 5); #=> 10 +#say summation; #=> Error: Undeclared routine: ... + +## You can also use the "whatever star" to create an anonymous subroutine. ## (it'll stop at the furthest operator in the current expression) -my @arrayplus3 = map(*+3, @array); # `*+3` is the same as `{ $_ + 3 }` +my @arrayplus3 = map(*+3, @array); # `*+3` is the same as `{ $_ + 3 }` my @arrayplus3 = map(*+*+3, @array); # Same as `-> $a, $b { $a + $b + 3 }` # also `sub ($a, $b) { $a + $b + 3 }` -say (*/2)(4); #=> 2 - # Immediately execute the function Whatever created. +say (*/2)(4); #=> 2 + # Immediately execute the function Whatever created. say ((*+3)/5)(5); #=> 1.6 - # works even in parens ! - -## But if you need to have more than one argument (`$_`) -## in a block (without wanting to resort to `-> {}`), -## you can also use the implicit argument syntax, `$^` : -map({ $^a + $^b + 3 }, @array); # equivalent to following: -map(sub ($a, $b) { $a + $b + 3 }, @array); # (here with `sub`) - -## Note : those are sorted lexicographically. -# `{ $^b / $^a }` is like `-> $a, $b { $b / $a }` + # It works even in parens! + +## But if you need to have more than one argument (`$_`) in a block (without +## wanting to resort to `-> {}`), you can also use the implicit argument +## syntax, `$^`: +map({ $^a + $^b + 3 }, @array); +# which is equivalent to the following which uses a `sub`: +map(sub ($a, $b) { $a + $b + 3 }, @array); + +## The parameters `$^a`, `$^b`, etc. are known as placeholder parameters or +## self-declared positional parameters. They're sorted lexicographically so +## `{ $^b / $^a }` is equivalent `-> $a, $b { $b / $a }`. ``` ### About types... ```perl6 -## Perl6 is gradually typed. This means you can specify the type -## of your variables/arguments/return types, or you can omit them -## and they'll default to "Any". -## You obviously get access to a few base types, like Int and Str. -## The constructs for declaring types are "class", "role", -## which you'll see later. - -## For now, let us examine "subset": -## a "subset" is a "sub-type" with additional checks. -## For example: "a very big integer is an Int that's greater than 500" -## You can specify the type you're subtyping (by default, Any), -## and add additional checks with the "where" keyword: +## Perl 6 is gradually typed. This means you can specify the type of your +## variables/arguments/return types, or you can omit the type annotations in +## in which case they'll default to `Any`. Obviously you get access to a few +## base types, like `Int` and `Str`. The constructs for declaring types are +## "subset", "class", "role", etc. which you'll see later. + +## For now, let us examine "subset" which is a "sub-type" with additional +## checks. For example, "a very big integer is an Int that's greater than 500". +## You can specify the type you're subtyping (by default, `Any`), and add +## additional checks with the `where` clause: subset VeryBigInteger of Int where * > 500; +## Or the set of the whole numbers: +subset WholeNumber of Int where * >= 0; ``` ### Multiple Dispatch ```perl6 ## Perl 6 can decide which variant of a `sub` to call based on the type of the -## arguments, or on arbitrary preconditions, like with a type or a `where`: +## arguments, or on arbitrary preconditions, like with a type or `where`: -## with types -multi sub sayit(Int $n) { # note the `multi` keyword here +## with types: +multi sub sayit( Int $n ) { # note the `multi` keyword here say "Number: $n"; } -multi sayit(Str $s) { # a multi is a `sub` by default +multi sayit( Str $s ) { # a multi is a `sub` by default say "String: $s"; } -sayit("foo"); # prints "String: foo" -sayit(True); # fails at *compile time* with - # "calling 'sayit' will never work with arguments of types ..." +sayit("foo"); #=> "String: foo" +sayit(25); #=> "Number: 25" +sayit(True); # fails at *compile time* with "calling 'sayit' will never + # work with arguments of types ..." -## with arbitrary precondition (remember subsets?): -multi is-big(Int $n where * > 50) { "Yes !" } # using a closure -multi is-big(Int $ where 10..50) { "Quite." } # Using smart-matching - # (could use a regexp, etc) +## with arbitrary preconditions (remember subsets?): +multi is-big(Int $n where * > 50) { "Yes!" } # using a closure +multi is-big(Int $n where {$_ > 50}) { "Yes!" } # similar to above +multi is-big(Int $ where 10..50) { "Quite." } # Using smart-matching + # (could use a regexp, etc) multi is-big(Int $) { "No" } subset Even of Int where * %% 2; - multi odd-or-even(Even) { "Even" } # The main case using the type. # We don't name the argument. -multi odd-or-even($) { "Odd" } # "else" +multi odd-or-even($) { "Odd" } # "everthing else" hence the $ variable -## You can even dispatch based on a positional's argument presence ! -multi with-or-without-you(:$with!) { # You need make it mandatory to - # be able to dispatch against it. - say "I can live ! Actually, I can't."; +## You can even dispatch based on the presence of positional and +## named arguments: +multi with-or-without-you($with) { + say "I wish I could but I can't"; +} +multi with-or-without-you(:$with) { + say "I can live! Actually, I can't."; } multi with-or-without-you { - say "Definitely can't live."; + say "Definitely can't live."; } -## This is very, very useful for many purposes, like `MAIN` subs (covered -## later), and even the language itself is using it in several places. + +## This is very, very useful for many purposes, like `MAIN` subs (covered +## later), and even the language itself uses it in several places. ## ## - `is`, for example, is actually a `multi sub` named `trait_mod:<is>`, ## and it works off that. ## - `is rw`, is simply a dispatch to a function with this signature: ## sub trait_mod:<is>(Routine $r, :$rw!) {} ## -## (commented because running this would be a terrible idea !) +## (commented out because running this would be a terrible idea!) ``` ## Scoping @@ -705,175 +801,207 @@ multi with-or-without-you { ## In Perl 6, unlike many scripting languages, (such as Python, Ruby, PHP), ## you must declare your variables before using them. The `my` declarator ## you have learned uses "lexical scoping". There are a few other declarators, -## (`our`, `state`, ..., ) which we'll see later. -## This is called "lexical scoping", where in inner blocks, -## you can access variables from outer blocks. +## (`our`, `state`, ..., ) which we'll see later. This is called +## "lexical scoping", where in inner blocks, you can access variables from +## outer blocks. my $file_scoped = 'Foo'; sub outer { - my $outer_scoped = 'Bar'; - sub inner { - say "$file_scoped $outer_scoped"; - } - &inner; # return the function + my $outer_scoped = 'Bar'; + sub inner { + say "$file_scoped $outer_scoped"; + } + &inner; # return the function } -outer()(); #=> 'Foo Bar' +outer()(); #=> 'Foo Bar' ## As you can see, `$file_scoped` and `$outer_scoped` were captured. -## But if we were to try and use `$bar` outside of `foo`, +## But if we were to try and use `$outer_scoped` outside the `outer` sub, ## the variable would be undefined (and you'd get a compile time error). ``` ## Twigils ```perl6 -## There are many special `twigils` (composed sigil's) in Perl 6. -## Twigils define the variables' scope. +## There are many special `twigils` (composed sigils) in Perl 6. Twigils +## define the variables' scope. ## The * and ? twigils work on standard variables: ## * Dynamic variable ## ? Compile-time variable ## The ! and the . twigils are used with Perl 6's objects: -## ! Attribute (class member) +## ! Attribute (instance attribute) ## . Method (not really a variable) -## `*` Twigil: Dynamic Scope -## These variables use the`*` twigil to mark dynamically-scoped variables. +## `*` twigil: Dynamic Scope +## These variables use the `*` twigil to mark dynamically-scoped variables. ## Dynamically-scoped variables are looked up through the caller, not through -## the outer scope +## the outer scope. my $*dyn_scoped_1 = 1; my $*dyn_scoped_2 = 10; sub say_dyn { - say "$*dyn_scoped_1 $*dyn_scoped_2"; + say "$*dyn_scoped_1 $*dyn_scoped_2"; } sub call_say_dyn { my $*dyn_scoped_1 = 25; # Defines $*dyn_scoped_1 only for this sub. - $*dyn_scoped_2 = 100; # Will change the value of the file scoped variable. - say_dyn(); #=> 25 100 $*dyn_scoped 1 and 2 will be looked for in the call. - # It uses the value of $*dyn_scoped_1 from inside this sub's - # lexical scope even though the blocks aren't nested (they're - # call-nested). -} -say_dyn(); #=> 1 10 + $*dyn_scoped_2 = 100; # Will change the value of the file scoped variable. + say_dyn(); #=> 25 100, $*dyn_scoped 1 and 2 will be looked + # for in the call. + # It uses the value of $*dyn_scoped_1 from inside + # this sub's lexical scope even though the blocks + # aren't nested (they're call-nested). +} +say_dyn(); #=> 1 10 call_say_dyn(); #=> 25 100 # Uses $*dyn_scoped_1 as defined in call_say_dyn even though # we are calling it from outside. -say_dyn(); #=> 1 100 We changed the value of $*dyn_scoped_2 in call_say_dyn - # so now its value has changed. +say_dyn(); #=> 1 100 We changed the value of $*dyn_scoped_2 in + # call_say_dyn so now its value has changed. ``` ## Object Model ```perl6 ## To call a method on an object, add a dot followed by the method name: -## => $object.method +## `$object.method` + ## Classes are declared with the `class` keyword. Attributes are declared -## with the `has` keyword, and methods declared with `method`. -## Every attribute that is private uses the ! twigil for example: `$!attr`. -## Immutable public attributes use the `.` twigil. -## (you can make them mutable with `is rw`) -## The easiest way to remember the `$.` twigil is comparing it to how methods -## are called. - -## Perl 6's object model ("SixModel") is very flexible, -## and allows you to dynamically add methods, change semantics, etc ... -## (these will not all be covered here, and you should refer to: +## with the `has` keyword, and methods declared with the `method` keyword. + +## Every attribute that is private uses the ! twigil. For example: `$!attr`. +## Immutable public attributes use the `.` twigil which creates a read-only +## method named after the attribute. In fact, declaring an attribute with `.` +## is equivalent to declaring the same attribute with `!` and then creating +## a read-only method with the attribute's name. However, this is done for us +## by Perl 6 automatically. The easiest way to remember the `$.` twigil is +## by comparing it to how methods are called. + +## Perl 6's object model ("SixModel") is very flexible, and allows you to +## dynamically add methods, change semantics, etc... Unfortunately, these will +## not all be covered here, and you should refer to: ## https://docs.perl6.org/language/objects.html. -class Attrib-Class { - has $.attrib; # `$.attrib` is immutable. - # From inside the class, use `$!attrib` to modify it. - has $.other-attrib is rw; # You can mark a public attribute `rw`. - has Int $!private-attrib = 10; - - method get-value { - $.attrib + $!private-attrib; - } +class Human { + has Str $.name; # `$.name` is immutable but with an accessor method. + has Str $.bcountry; # Use `$!bplace` to modify it inside the class. + has Str $.ccountry is rw; # This attribute can be modified from outside. + has Int $!age = 0; # A private attribute with default value. - method set-value($param) { # Methods can take parameters - $!attrib = $param; # This works, because `$!` is always mutable. - # $.attrib = $param; # Wrong: You can't use the `$.` immutable version. + method birthday { + $!age += 1; # Add a year to human's age + } - $.other-attrib = 5; # This works, because `$.other-attrib` is `rw`. - } + method get-age { + return $!age; + } - method !private-method { - say "This method is private to the class !"; - } + # This method is private to the class. Note the `!` before the + # method's name. + method !do-decoration { + return "$!name was born in $!bcountry and now lives in $!ccountry." + } + + # This method is public, just like `birthday` and `get-age`. + method get-info { + self.do-decoration; # Invoking a method on `self` inside the class. + # Use `self!priv-method` for private method. + # Use `self.publ-method` for public method. + } }; -## Create a new instance of Attrib-Class with $.attrib set to 5 : +## Create a new instance of Human class with $.attrib set to 5. ## Note: you can't set private-attribute from here (more later on). -my $class-obj = Attrib-Class.new(attrib => 5); -say $class-obj.get-value; #=> 15 -# $class-obj.attrib = 5; # This fails, because the `has $.attrib` is immutable -$class-obj.other-attrib = 10; # This, however, works, because the public - # attribute is mutable (`rw`). +my $person1 = Human.new( + name => "Jord", + bcountry = "Iceland", + ccountry => "Iceland" +); + +say $person1.name; #=> Jord +say $person1.bcountry; #=> Togo +say $person1.ccountry; #=> Togo + + +# $person1.bcountry = "Mali"; # This fails, because the `has $.bcountry` + # is immutable. Jord can't change his birthplace. +$person1.ccountry = "France"; # This works because the `$.ccountry` is mutable + # (`is rw`). Now Jord's current country is France. + +# Calling methods on the instance objects. +$person1.birthday; #=> 1 +$person1.get-info; #=> Jord was born in Togo and now lives in France. +$person1.do-decoration; # This fails since the method `do-decoration` is + # private. ``` ### Object Inheritance ```perl6 -## Perl 6 also has inheritance (along with multiple inheritance) -## While `method`'s are inherited, `submethod`'s are not. -## Submethods are useful for object construction and destruction tasks, -## such as BUILD, or methods that must be overridden by subtypes. -## We will learn about BUILD later on. +## Perl 6 also has inheritance (along with multiple inheritance). While +## methods are inherited, submethods are not. Submethods are useful for +## object construction and destruction tasks, such as BUILD, or methods that +## must be overridden by subtypes. We will learn about BUILD later on. class Parent { - has $.age; - has $.name; - # This submethod won't be inherited by Child. - submethod favorite-color { - say "My favorite color is Blue"; - } - # This method is inherited - method talk { say "Hi, my name is $!name" } + has $.age; + has $.name; + + # This submethod won't be inherited by the Child class. + submethod favorite-color { + say "My favorite color is Blue"; + } + + # This method is inherited + method talk { say "Hi, my name is $!name" } } + # Inheritance uses the `is` keyword class Child is Parent { - method talk { say "Goo goo ga ga" } - # This shadows Parent's `talk` method, This child hasn't learned to speak yet! + method talk { say "Goo goo ga ga" } + # This shadows Parent's `talk` method. + # This child hasn't learned to speak yet! } + my Parent $Richard .= new(age => 40, name => 'Richard'); -$Richard.favorite-color; #=> "My favorite color is Blue" -$Richard.talk; #=> "Hi, my name is Richard" -## $Richard is able to access the submethod, he knows how to say his name. +$Richard.favorite-color; #=> "My favorite color is Blue" +$Richard.talk; #=> "Hi, my name is Richard" +## $Richard is able to access the submethod and he knows how to say his name. my Child $Madison .= new(age => 1, name => 'Madison'); -$Madison.talk; # prints "Goo goo ga ga" due to the overridden method. -# $Madison.favorite-color # does not work since it is not inherited +$Madison.talk; #=> "Goo goo ga ga", due to the overridden method. +# $Madison.favorite-color # does not work since it is not inherited. ## When you use `my T $var`, `$var` starts off with `T` itself in it, ## so you can call `new` on it. ## (`.=` is just the dot-call and the assignment operator: -## `$a .= b` is the same as `$a = $a.b`) +## `$a .= b` is the same as `$a = $a.b`) ## Also note that `BUILD` (the method called inside `new`) -## will set parent properties too, so you can pass `val => 5`. +## will set parent's properties too, so you can pass `val => 5`. ``` ### Roles, or Mixins ```perl6 -## Roles are supported too (also called Mixins in other languages) +## Roles are supported too (which are called Mixins in other languages) role PrintableVal { - has $!counter = 0; - method print { - say $.val; - } + has $!counter = 0; + method print { + say $.val; + } } -## you "import" a mixin (a "role") with "does": +## you "apply" a role (or mixin) with `does` keyword: class Item does PrintableVal { - has $.val; + has $.val; - ## When `does`-ed, a `role` literally "mixes in" the class: - ## the methods and attributes are put together, which means a class can access - ## the private attributes/methods of its roles (but not the inverse !): - method access { - say $!counter++; - } + ## When `does`-ed, a `role` literally "mixes in" the class: + ## the methods and attributes are put together, which means a class + ## can access the private attributes/methods of its roles (but + ## not the inverse!): + method access { + say $!counter++; + } ## However, this: ## method print {} @@ -881,9 +1009,9 @@ class Item does PrintableVal { ## (this means a parent class can shadow a child class's `multi print() {}`, ## but it's an error if a role does) - ## NOTE: You can use a role as a class (with `is ROLE`). In this case, - ## methods will be shadowed, since the compiler will consider `ROLE` to - ## be a class. + ## NOTE: You can use a role as a class (with `is ROLE`). In this case, + ## methods will be shadowed, since the compiler will consider `ROLE` + ## to be a class. } ``` @@ -891,91 +1019,109 @@ class Item does PrintableVal { ```perl6 ## Exceptions are built on top of classes, in the package `X` (like `X::IO`). -## In Perl6 exceptions are automatically 'thrown' -open 'foo'; #> Failed to open file foo: no such file or directory -## It will also print out what line the error was thrown at and other error info +## In Perl6 exceptions are automatically 'thrown': +open 'foo'; #=> Failed to open file foo: no such file or directory +## It will also print out what line the error was thrown at +## and other error info. ## You can throw an exception using `die`: die 'Error!'; #=> Error! ## Or more explicitly: -die X::AdHoc.new(payload => 'Error!'); +X::AdHoc.new(payload => 'Error!').throw; #=> Error! ## In Perl 6, `orelse` is similar to the `or` operator, except it only matches -## undefined variables instead of anything evaluating as false. +## undefined variables instead of anything evaluating as `False`. ## Undefined values include: `Nil`, `Mu` and `Failure` as well as `Int`, `Str` ## and other types that have not been initialized to any value yet. ## You can check if something is defined or not using the defined method: my $uninitialized; -say $uninitiazilzed.defined; #> False -## When using `orelse` it will disarm the exception and alias $_ to that failure -## This will avoid it being automatically handled and printing lots of scary -## error messages to the screen. -## We can use the exception method on $_ to access the exception +say $uninitiazilzed.defined; #=> False + +## When using `orelse` it will disarm the exception and alias $_ to that +## failure. This will prevent it to being automatically handled and printing +## lots of scary error messages to the screen. We can use the `exception` +## method on the `$_` variable to access the exception open 'foo' orelse say "Something happened {.exception}"; ## This also works: -open 'foo' orelse say "Something happened $_"; #> Something happened - #> Failed to open file foo: no such file or directory -## Both of those above work but in case we get an object from the left side that -## is not a failure we will probably get a warning. We see below how we can use -## `try` and `CATCH` to be more specific with the exceptions we catch. +open 'foo' orelse say "Something happened $_"; #=> Something happened + #=> Failed to open file foo: no such file or directory +## Both of those above work but in case we get an object from the left side +## that is not a failure we will probably get a warning. We see below how we +## can use try` and `CATCH` to be more specific with the exceptions we catch. ``` ### Using `try` and `CATCH` ```perl6 ## By using `try` and `CATCH` you can contain and handle exceptions without -## disrupting the rest of the program. `try` will set the last exception to -## the special variable `$!` Note: This has no relation to $!variables. +## disrupting the rest of the program. The `try` block will set the last +## exception to the special variable `$!` (known as the error variable). +## Note: This has no relation to $!variables seen inside class definitions. + try open 'foo'; -say "Well, I tried! $!" if defined $!; #> Well, I tried! Failed to open file - #foo: no such file or directory +say "Well, I tried! $!" if defined $!; +#=> Well, I tried! Failed to open file foo: no such file or directory + ## Now, what if we want more control over handling the exception? ## Unlike many other languages, in Perl 6, you put the `CATCH` block *within* -## the block to `try`. Similar to how $_ was set when we 'disarmed' the -## exception with orelse, we also use $_ in the CATCH block. -## Note: ($! is only set *after* the `try` block) -## By default, a `try` has a `CATCH` block that catches -## any exception (`CATCH { default {} }`). +## the block to `try`. Similar to how the `$_` variable was set when we +## 'disarmed' the exception with `orelse`, we also use `$_` in the CATCH block. +## Note: The `$!` variable is only set *after* the `try` block has caught an +## exception. By default, a `try` block has a `CATCH` block of its own that +## catches any exception (`CATCH { default {} }`). -try { my $a = (0 %% 0); CATCH { say "Something happened: $_" } } - #=> Something happened: Attempt to divide by zero using infix:<%%> +try { + my $a = (0 %% 0); + CATCH { + say "Something happened: $_" + } +} +#=> Something happened: Attempt to divide by zero using infix:<%%> + +## You can redefine it using `when`s (and `default`) to handle the exceptions +## you want to catch explicitly: -## You can redefine it using `when`s (and `default`) -## to handle the exceptions you want: try { open 'foo'; - CATCH { # In the `CATCH` block, the exception is set to $_ - when X::AdHoc { say "Error: $_" } - #=>Error: Failed to open file /dir/foo: no such file or directory - - ## Any other exception will be re-raised, since we don't have a `default` - ## Basically, if a `when` matches (or there's a `default`) marks the - ## exception as - ## "handled" so that it doesn't get re-thrown from the `CATCH`. - ## You still can re-throw the exception (see below) by hand. + CATCH { + # In the `CATCH` block, the exception is set to the $_ variable. + when X::AdHoc { + say "Error: $_" + } + when X::Numeric::DivideByZero { + say "Error: $_"; + } + ## Any other exceptions will be re-raised, since we don't have a `default`. + ## Basically, if a `when` matches (or there's a `default`), the + ## exception is marked as "handled" so as to prevent its re-throw + ## from the `CATCH` block. You still can re-throw the exception (see below) + ## by hand. } } +#=>Error: Failed to open file /dir/foo: no such file or directory ## There are also some subtleties to exceptions. Some Perl 6 subs return a -## `Failure`, which is a kind of "unthrown exception". They're not thrown until -## you tried to look at their content, unless you call `.Bool`/`.defined` on -## them - then they're handled. +## `Failure`, which is a wrapper around an `Exception` object which is +## "unthrown". They're not thrown until you try to use the variables containing +## them unless you call `.Bool`/`.defined` on them - then they're handled. ## (the `.handled` method is `rw`, so you can mark it as `False` back yourself) -## ## You can throw a `Failure` using `fail`. Note that if the pragma `use fatal` ## is on, `fail` will throw an exception (like `die`). + fail "foo"; # We're not trying to access the value, so no problem. try { - fail "foo"; - CATCH { - default { say "It threw because we tried to get the fail's value!" } + fail "foo"; + CATCH { + default { + say "It threw because we tried to get the fail's value!" + } } } ## There is also another kind of exception: Control exceptions. -## Those are "good" exceptions, which happen when you change your program's +## Those are "good" exceptions, which happen when you change your program's ## flow, using operators like `return`, `next` or `last`. ## You can "catch" those with `CONTROL` (not 100% working in Rakudo yet). ``` @@ -989,29 +1135,35 @@ try { ## Packages are important - especially as Perl is well-known for CPAN, ## the Comprehensive Perl Archive Network. -## You can use a module (bring its declarations into scope) with `use` +## You can use a module (bring its declarations into scope) with +## the `use` keyword: use JSON::Tiny; # if you installed Rakudo* or Panda, you'll have this module say from-json('[1]').perl; #=> [1] ## You should not declare packages using the `package` keyword (unlike Perl 5). ## Instead, use `class Package::Name::Here;` to declare a class, or if you only -## want to export variables/subs, you can use `module`. +## want to export variables/subs, you can use `module` instead. + +module Hello::World { # bracketed form + # If `Hello` doesn't exist yet, it'll just be a "stub", + # that can be redeclared as something else later. -module Hello::World { # Bracketed form - # If `Hello` doesn't exist yet, it'll just be a "stub", - # that can be redeclared as something else later. - # ... declarations here ... + # ... declarations here ... } -unit module Parse::Text; # file-scoped form -grammar Parse::Text::Grammar { # A grammar is a package, which you could `use` -} # You will learn more about grammars in the regex section +unit module Parse::Text; # file-scoped form which extends until + # the end of the file + +grammar Parse::Text::Grammar { + # A grammar is a package, which you could `use`. + # You will learn more about grammars in the regex section +} ## As said before, any part of the six model is also a package. ## Since `JSON::Tiny` uses its own `JSON::Tiny::Actions` class, you can use it: my $actions = JSON::Tiny::Actions.new; -## We'll see how to export variables and subs in the next part: +## We'll see how to export variables and subs in the next part. ``` ## Declarators @@ -1020,36 +1172,38 @@ my $actions = JSON::Tiny::Actions.new; ## In Perl 6, you get different behaviors based on how you declare a variable. ## You've already seen `my` and `has`, we'll now explore the others. -## * `our` declarations happen at `INIT` time -- (see "Phasers" below) -## It's like `my`, but it also creates a package variable. -## (All packagish things (`class`, `role`, etc) are `our` by default) -module Var::Increment { - our $our-var = 1; # Note: you can't put a type constraint like Int on an - my $my-var = 22; # `our` variable. - our sub Inc { - - our sub available { # If you try to make inner `sub`s `our`... - # Better know what you're doing (Don't !). - say "Don't do that. Seriously. You'll get burned."; - } +## `our` - these declarations happen at `INIT` time -- (see "Phasers" below). +## It's like `my`, but it also creates a package variable. All packagish +## things such as `class`, `role`, etc. are `our` by default. - my sub unavailable { # `my sub` is the default - say "Can't access me from outside, I'm 'my'!"; - } - say ++$our-var; # Increment the package variable and output its value +module Var::Increment { + our $our-var = 1; # Note: `our`-declared variables cannot be typed. + my $my-var = 22; + + our sub Inc { + our sub available { # If you try to make inner `sub`s `our`... + # ... Better know what you're doing (Don't !). + say "Don't do that. Seriously. You'll get burned."; + } + + my sub unavailable { # `sub`s are `my`-declared by default + say "Can't access me from outside, I'm 'my'!"; + } + say ++$our-var; # Increment the package variable and output its value } } -say $Var::Increment::our-var; #=> 1 This works -say $Var::Increment::my-var; #=> (Any) This will not work. -Var::Increment::Inc; #=> 2 -Var::Increment::Inc; #=> 3 # Notice how the value of $our-var was - # retained. -Var::Increment::unavailable; #> Could not find symbol '&unavailable' +say $Var::Increment::our-var; #=> 1, this works! +say $Var::Increment::my-var; #=> (Any), this will not work! + +Var::Increment::Inc; #=> 2 +Var::Increment::Inc; #=> 3 , notice how the value of $our-var was + # retained. +Var::Increment::unavailable; #=> Could not find symbol '&unavailable' -## * `constant` (happens at `BEGIN` time) -## You can use the `constant` keyword to declare a compile-time variable/symbol: +## `constant` - these declarations happen at `BEGIN` time. You can use +## the `constant` keyword to declare a compile-time variable/symbol: constant Pi = 3.14; constant $var = 1; @@ -1057,12 +1211,12 @@ constant $var = 1; constant why-not = 5, 15 ... *; say why-not[^5]; #=> 5 15 25 35 45 -## * `state` (happens at run time, but only once) -## State variables are only initialized one time -## (they exist in other languages such as C as `static`) +## `state` - these declarations happen at run time, but only once. State +## variables are only initialized one time. In other languages such as C +## they exist as `static` variables. sub fixed-rand { - state $val = rand; - say $val; + state $val = rand; + say $val; } fixed-rand for ^10; # will print the same number 10 times @@ -1070,40 +1224,42 @@ fixed-rand for ^10; # will print the same number 10 times ## If you declare a function with a `state` within a loop, it'll re-create the ## variable for each iteration of the loop. See: for ^5 -> $a { - sub foo { - state $val = rand; # This will be a different value for every value of `$a` - } - for ^5 -> $b { - say foo; # This will print the same value 5 times, but only 5. - # Next iteration will re-run `rand`. - } + sub foo { + state $val = rand; # This will be a different value for + # every value of `$a` + } + for ^5 -> $b { + say foo; # This will print the same value 5 times, + # but only 5. Next iteration will re-run `rand`. + } } ``` ## Phasers ```perl6 -## Phasers in Perl 6 are blocks that happen at determined points of time in your -## program. They are called phasers because they mark a change in the phase -## of a program. For example, when the program is compiled, a for loop runs, -## you leave a block, or an exception gets thrown. -## (`CATCH` is actually a phaser!) -## Some of them can be used for their return values, some of them can't -## (those that can have a "[*]" in the beginning of their explanation text). -## Let's have a look ! - -## * Compile-time phasers +## Phasers in Perl 6 are blocks that happen at determined points of time in +## your program. They are called phasers because they mark a change in the +## phase of a program. For example, when the program is compiled, a for loop +## runs, you leave a block, or an exception gets thrown (The `CATCH` block is +## actually a phaser!). Some of them can be used for their return values, +## some of them can't (those that can have a "[*]" in the beginning of their +## explanation text). Let's have a look! + +## Compile-time phasers BEGIN { say "[*] Runs at compile time, as soon as possible, only once" } CHECK { say "[*] Runs at compile time, as late as possible, only once" } -## * Run-time phasers +## Run-time phasers INIT { say "[*] Runs at run time, as soon as possible, only once" } -END { say "Runs at run time, as late as possible, only once" } +END { say "Runs at run time, as late as possible, only once" } -## * Block phasers +## Block phasers ENTER { say "[*] Runs everytime you enter a block, repeats on loop blocks" } -LEAVE { say "Runs everytime you leave a block, even when an exception - happened. Repeats on loop blocks." } +LEAVE { + say "Runs everytime you leave a block, even when an exception + happened. Repeats on loop blocks." +} PRE { say "Asserts a precondition at every block entry, @@ -1112,7 +1268,7 @@ PRE { an exception of type X::Phaser::PrePost is thrown."; } -## example: +## Example: for 0..2 { PRE { $_ > 1 } # This is going to blow up with "Precondition failed" } @@ -1123,83 +1279,86 @@ POST { say "If this block doesn't return a truthy value, an exception of type X::Phaser::PrePost is thrown, like PRE."; } + for 0..2 { POST { $_ < 2 } # This is going to blow up with "Postcondition failed" } -## * Block/exceptions phasers +## Block/exceptions phasers sub { KEEP { say "Runs when you exit a block successfully (without throwing an exception)" } - UNDO { say "Runs when you exit a block unsuccessfully + UNDO { say "Runs when you exit a block unsuccessfully (by throwing an exception)" } } -## * Loop phasers +## Loop phasers for ^5 { FIRST { say "[*] The first time the loop is run, before ENTER" } - NEXT { say "At loop continuation time, before LEAVE" } - LAST { say "At loop termination time, after LEAVE" } + NEXT { say "At loop continuation time, before LEAVE" } + LAST { say "At loop termination time, after LEAVE" } } -## * Role/class phasers +## Role/class phasers COMPOSE { "When a role is composed into a class. /!\ NOT YET IMPLEMENTED" } -## They allow for cute tricks or clever code ...: +## They allow for cute tricks or clever code...: say "This code took " ~ (time - CHECK time) ~ "s to compile"; ## ... or clever organization: sub do-db-stuff { - $db.start-transaction; # start a new transaction - KEEP $db.commit; # commit the transaction if all went well - UNDO $db.rollback; # or rollback if all hell broke loose + $db.start-transaction; # start a new transaction + KEEP $db.commit; # commit the transaction if all went well + UNDO $db.rollback; # or rollback if all hell broke loose } ``` ## Statement prefixes ```perl6 -## Those act a bit like phasers: they affect the behavior of the following code. -## Though, they run in-line with the executable code, so they're in lowercase. -## (`try` and `start` are theoretically in that list, but explained elsewhere) -## Note: all of these (except start) don't need explicit brackets `{` and `}`. +## Those act a bit like phasers: they affect the behavior of the following +## code. Though, they run in-line with the executable code, so they're in +## lowercase. (`try` and `start` are theoretically in that list, but explained +## elsewhere) Note: all of these (except start) don't need explicit curly +## braces `{` and `}`. -## - `do` (that you already saw) - runs a block or a statement as a term -## You can't normally use a statement as a value (or "term"): -## -## my $value = if True { 1 } # `if` is a statement - parse error -## -## This works: -my $a = do if True { 5 } # with `do`, `if` is now a term. - -## - `once` - Makes sure a piece of code only runs once -for ^5 { once say 1 }; #=> 1 - # Only prints ... once. -## Like `state`, they're cloned per-scope -for ^5 { sub { once say 1 }() } #=> 1 1 1 1 1 - # Prints once per lexical scope - -## - `gather` - Co-routine thread -## Gather allows you to `take` several values in an array, -## much like `do`, but allows you to take any expression. +## `do` - (which you already saw) runs a block or a statement as a term. +## Normally you cannot use a statement as a value (or "term"). `do` helps us +## do it. + +# my $value = if True { 1 } # this fails since `if` is a statement +my $a = do if True { 5 } # with `do`, `if` is now a term returning a value + +## `once` - makes sure a piece of code only runs once. +for ^5 { + once say 1 +}; #=> 1, only prints ... once + +## Similar to `state`, they're cloned per-scope. +for ^5 { + sub { once say 1 }() +}; #=> 1 1 1 1 1, prints once per lexical scope. + +## `gather` - co-routine thread. The `gather` constructs allows us to `take` +## several values from an array/list, much like `do`. say gather for ^5 { - take $_ * 3 - 1; - take $_ * 3 + 1; -} #=> -1 1 2 4 5 7 8 10 11 13 + take $_ * 3 - 1; + take $_ * 3 + 1; +} +#=> -1 1 2 4 5 7 8 10 11 13 + say join ',', gather if False { - take 1; - take 2; - take 3; -} # Doesn't print anything. + take 1; + take 2; + take 3; +} +# Doesn't print anything. -## - `eager` - Evaluate statement eagerly (forces eager context) +## `eager` - evaluates a statement eagerly (forces eager context) ## Don't try this at home: -## -## eager 1..*; # this will probably hang for a while (and might crash ...). -## +# eager 1..*; # this will probably hang for a while (and might crash ...). ## But consider: constant thrice = gather for ^3 { say take $_ }; # Doesn't print anything - ## versus: constant thrice = eager gather for ^3 { say take $_ }; #=> 0 1 2 ``` @@ -1207,102 +1366,105 @@ constant thrice = eager gather for ^3 { say take $_ }; #=> 0 1 2 ## Iterables ```perl6 -## Iterables are objects that can be iterated similar to the `for` construct -## `flat`, flattens iterables: -say (1, 10, (20, 10) ); #> (1 10 (20 10)) Notice how grouping is maintained -say (1, 10, (20, 10) ).flat; #> (1 10 20 10) Now the iterable is flat +## Iterables are objects that can be iterated over which are +## are similar to the `for` construct. -## - `lazy` - Defer actual evaluation until value is fetched -## (forces lazy context) +## `flat` - flattens iterables. +say (1, 10, (20, 10) ); #=> (1 10 (20 10)), notice how neste lists are + # preserved +say (1, 10, (20, 10) ).flat; #=> (1 10 20 10), now the iterable is flat + +## - `lazy` - defers actual evaluation until value is fetched by forcing +## lazy context. my @lazy-array = (1..100).lazy; -say @lazy-array.is-lazy; #> True # Check for laziness with the `is-lazy` method. -say @lazy-array; #> [...] List has not been iterated on! +say @lazy-array.is-lazy; #=> True, check for laziness with the `is-lazy` method. +say @lazy-array; #=> [...] List has not been iterated on! my @lazy-array { .print }; # This works and will only do as much work as # is needed. -[//]: # ( TODO explain that gather/take and map are all lazy) -## - `sink` - An `eager` that discards the results (forces sink context) + +# ( **TODO** explain that gather/take and map are all lazy) + +## `sink` - an `eager` that discards the results by forcing sink context. constant nilthingie = sink for ^3 { .say } #=> 0 1 2 -say nilthingie.perl; #=> Nil +say nilthingie.perl; #=> Nil -## - `quietly` blocks will suppress warnings: +## `quietly` - suppresses warnings in blocks. quietly { warn 'This is a warning!' }; #=> No output -## - `contend` - Attempts side effects under STM -## Not yet implemented ! +## `contend` - attempts side effects under STM +## Not yet implemented! ``` -## More operators thingies ! +## More operators thingies! ```perl6 -## Everybody loves operators ! Let's get more of them +## Everybody loves operators! Let's get more of them. ## The precedence list can be found here: ## https://docs.perl6.org/language/operators#Operator_Precedence ## But first, we need a little explanation about associativity: -## * Binary operators: +## Binary operators: $a ! $b ! $c; # with a left-associative `!`, this is `($a ! $b) ! $c` $a ! $b ! $c; # with a right-associative `!`, this is `$a ! ($b ! $c)` $a ! $b ! $c; # with a non-associative `!`, this is illegal $a ! $b ! $c; # with a chain-associative `!`, this is `($a ! $b) and ($b ! $c)` $a ! $b ! $c; # with a list-associative `!`, this is `infix:<>` -## * Unary operators: +## Unary operators: !$a! # with left-associative `!`, this is `(!$a)!` !$a! # with right-associative `!`, this is `!($a!)` !$a! # with non-associative `!`, this is illegal ``` -### Create your own operators ! +### Create your own operators! ```perl6 -## Okay, you've been reading all of that, so I guess I should try -## to show you something exciting. -## I'll tell you a little secret (or not-so-secret): +## Okay, you've been reading all of that, so you might want to try something +## more exciting?! I'll tell you a little secret (or not-so-secret): ## In Perl 6, all operators are actually just funny-looking subroutines. ## You can declare an operator just like you declare a sub: -sub prefix:<win>($winner) { # refer to the operator categories - # (yes, it's the "words operator" `<>`) - say "$winner Won !"; +# prefix refers to the operator categories (prefix, infix, postfix, etc). +sub prefix:<win>( $winner ) { + say "$winner Won!"; } -win "The King"; #=> The King Won ! - # (prefix is before) +win "The King"; #=> The King Won! + # (prefix means 'before') ## you can still call the sub with its "full name": -say prefix:<!>(True); #=> False +say prefix:<!>(True); #=> False +prefix:<win>("The Queen"); #=> The Queen Won! -sub postfix:<!>(Int $n) { - [*] 2..$n; # using the reduce meta-operator ... See below ;-) ! +sub postfix:<!>( Int $n ) { + [*] 2..$n; # using the reduce meta-operator... See below ;-)! } say 5!; #=> 120 - # Postfix operators (after) have to come *directly* after the term. + # Postfix operators ('after') have to come *directly* after the term. # No whitespace. You can use parentheses to disambiguate, i.e. `(5!)!` - -sub infix:<times>(Int $n, Block $r) { # infix in the middle - for ^$n { - $r(); # You need the explicit parentheses to call the function in `$r`, - # else you'd be referring at the variable itself, like with `&r`. - } +sub infix:<times>( Int $n, Block $r ) { # infix ('between') + for ^$n { + $r(); # You need the explicit parentheses to call the function in `$r`, + # else you'd be referring at the variable itself, like with `&r`. + } } 3 times -> { say "hello" }; #=> hello #=> hello #=> hello - # You're very recommended to put spaces - # around your infix operator calls. +## It's recommended to put spaces around your +## infix operator calls. ## For circumfix and post-circumfix ones -sub circumfix:<[ ]>(Int $n) { - $n ** $n +sub circumfix:<[ ]>( Int $n ) { + $n ** $n } say [5]; #=> 3125 - # circumfix is around. Again, no whitespace. + # circumfix means 'around'. Again, no whitespace. -sub postcircumfix:<{ }>(Str $s, Int $idx) { - ## post-circumfix is - ## "after a term, around something" - $s.substr($idx, 1); +sub postcircumfix:<{ }>( Str $s, Int $idx ) { + ## post-circumfix is 'after a term, around something' + $s.substr($idx, 1); } say "abc"{1}; #=> b # after the term `"abc"`, and around the index (1) @@ -1312,47 +1474,47 @@ say "abc"{1}; #=> b ## (a simple named argument underneath): %h{$key}:delete; ## equivalent to: -postcircumfix:<{ }>(%h, $key, :delete); # (you can call operators like that) +postcircumfix:<{ }>( %h, $key, :delete ); # (you can call operators like this) -## It's *all* using the same building blocks! -## Syntactic categories (prefix infix ...), named arguments (adverbs), ..., -## - used to build the language - are available to you. -## (you are, obviously, recommended against making an operator out of -## *everything* -- with great power comes great responsibility) +## It's *all* using the same building blocks! Syntactic categories +## (prefix infix ...), named arguments (adverbs), ..., etc. used to build +## the language - are available to you. Obviously, you're advised against +## making an operator out of *everything* -- with great power comes great +## responsibility. ``` -### Meta operators ! +### Meta operators! ```perl6 -## Oh boy, get ready. Get ready, because we're delving deep -## into the rabbit's hole, and you probably won't want to go -## back to other languages after reading that. -## (I'm guessing you don't want to already at that point). +## Oh boy, get ready!. Get ready, because we're delving deep into the rabbit's +## hole, and you probably won't want to go back to other languages after +## reading this. (I'm guessing you don't want to go back at this point but +## let's continue, for the journey is long and enjoyable!). + ## Meta-operators, as their name suggests, are *composed* operators. -## Basically, they're operators that apply another operator. +## Basically, they're operators that act on another operators. + +## The reduce meta-operator is a prefix meta-operator that takes a binary +## function and one or many lists. If it doesn't get passed any argument, +## it either returns a "default value" for this operator (a meaningless value) +## or `Any` if there's none (examples below). Otherwise, it pops an element +## from the list(s) one at a time, and applies the binary function to the last +## result (or the list's first element) and the popped element. -## * Reduce meta-operator -## It's a prefix meta-operator that takes a binary function and -## one or many lists. If it doesn't get passed any argument, -## it either returns a "default value" for this operator -## (a meaningless value) or `Any` if there's none (examples below). -## -## Otherwise, it pops an element from the list(s) one at a time, and applies -## the binary function to the last result (or the list's first element) -## and the popped element. -## ## To sum a list, you could use the reduce meta-operator with `+`, i.e.: -say [+] 1, 2, 3; #=> 6 -## equivalent to `(1+2)+3` +say [+] 1, 2, 3; #=> 6, equivalent to (1+2)+3. -say [*] 1..5; #=> 120 -## equivalent to `((((1*2)*3)*4)*5)`. +## To multiply a list +say [*] 1..5; #=> 120, equivalent to ((((1*2)*3)*4)*5). ## You can reduce with any operator, not just with mathematical ones. -## For example, you could reduce with `//` to get -## the first defined element of a list: -say [//] Nil, Any, False, 1, 5; #=> False - # (Falsey, but still defined) +## For example, you could reduce with `//` to get first defined element +## of a list: +say [//] Nil, Any, False, 1, 5; #=> False + # (Falsey, but still defined) +## Or with relational operators, i.e., `>` to check elements of a list +## are ordered accordingly: +say say [>] 234, 156, 6, 3, -20; #=> True ## Default value examples: say [*] (); #=> 1 @@ -1365,15 +1527,14 @@ say [//]; #=> (Any) sub add($a, $b) { $a + $b } say [[&add]] 1, 2, 3; #=> 6 -## * Zip meta-operator -## This one is an infix meta-operator that also can be used as a "normal" -## operator. It takes an optional binary function (by default, it just creates -## a pair), and will pop one value off of each array and call its binary -## function on these until it runs out of elements. It returns an array with -## all of these new elements. -(1, 2) Z (3, 4); # ((1, 3), (2, 4)), since by default, the function - # makes an array. -1..3 Z+ 4..6; # (5, 7, 9), using the custom infix:<+> function +## The zip meta-operator is an infix meta-operator that also can be used as a +## "normal" operator. It takes an optional binary function (by default, it +## just creates a pair), and will pop one value off of each array and call +## its binary function on these until it runs out of elements. It returns an +## array with all of these new elements. +say (1, 2) Z (3, 4); #=> ((1, 3), (2, 4)), since by default the function + # makes an array. +say 1..3 Z+ 4..6; #=> (5, 7, 9), using the custom infix:<+> function ## Since `Z` is list-associative (see the list above), ## you can use it on more than one list @@ -1385,252 +1546,258 @@ say [[&add]] 1, 2, 3; #=> 6 ## And to end the operator list: -## * Sequence operator ## The sequence operator is one of Perl 6's most powerful features: ## it's composed of first, on the left, the list you want Perl 6 to deduce from ## (and might include a closure), and on the right, a value or the predicate -## that says when to stop (or Whatever for a lazy infinite list). -my @list = 1, 2, 3 ... 10; # basic deducing -#my @list = 1, 3, 6 ... 10; # this dies because Perl 6 can't figure out the end -my @list = 1, 2, 3 ...^ 10; # as with ranges, you can exclude the last element - # (the iteration when the predicate matches). -my @list = 1, 3, 9 ... * > 30; # you can use a predicate - # (with the Whatever Star, here). -my @list = 1, 3, 9 ... { $_ > 30 }; # (equivalent to the above) - -my @fib = 1, 1, *+* ... *; # lazy infinite list of fibonacci series, - # computed using a closure! +## that says when to stop (or a Whatever Star for a lazy infinite list). + +my @list = 1, 2, 3...10; # basic arithmetic sequence +# my @list = 1, 3, 6...10; # this dies because Perl 6 can't figure out the end +my @list = 1, 2, 3...^10; # as with ranges, you can exclude the last element + # (the iteration ends when the predicate matches). +my @list = 1, 3, 9...* > 30; # you can use a predicate (with the Whatever Star). +my @list = 1, 3, 9 ... { $_ > 30 }; # (equivalent to the above + # using a block here). + +my @fib = 1, 1, *+* ... *; # lazy infinite list of fibonacci sequence, + # computed using a closure! my @fib = 1, 1, -> $a, $b { $a + $b } ... *; # (equivalent to the above) -my @fib = 1, 1, { $^a + $^b } ... *; #(... also equivalent to the above) +my @fib = 1, 1, { $^a + $^b } ... *; # (also equivalent to the above) ## $a and $b will always take the previous values, meaning here -## they'll start with $a = 1 and $b = 1 (values we set by hand). -## then $a = 1 and $b = 2 (result from previous $a+$b), and so on. +## they'll start with $a = 1 and $b = 1 (values we set by hand), +## then $a = 1 and $b = 2 (result from previous $a+$b), and so on. say @fib[^10]; #=> 1 1 2 3 5 8 13 21 34 55 # (using a range as the index) -## Note : as for ranges, once reified, elements aren't re-calculated. +## Note: as for ranges, once reified, elements aren't re-calculated. ## That's why `@primes[^100]` will take a long time the first time you print -## it, then be instant. +## it, then will be instateneous. ``` ## Regular Expressions ```perl6 -## I'm sure a lot of you have been waiting for this one. -## Well, now that you know a good deal of Perl 6 already, we can get started. -## First off, you'll have to forget about "PCRE regexps" (perl-compatible -## regexps). +## I'm sure a lot of you have been waiting for this one. Well, now that you know +## a good deal of Perl 6 already, we can get started. First off, you'll have to +## forget about "PCRE regexps" (perl-compatible regexps). ## -## IMPORTANT: Don't skip them because you know PCRE. They're different. -## Some things are the same (like `?`, `+`, and `*`), -## but sometimes the semantics change (`|`). -## Make sure you read carefully, because you might trip over a new behavior. +## IMPORTANT: Don't skip them because you know PCRE. They're different. Some +## things are the same (like `?`, `+`, and `*`), but sometimes the semantics +## change (`|`). Make sure you read carefully, because you might trip over a +## new behavior. ## ## Perl 6 has many features related to RegExps. After all, Rakudo parses itself. -## We're first going to look at the syntax itself, -## then talk about grammars (PEG-like), differences between -## `token`, `regex` and `rule` declarators, and some more. -## Side note: you still have access to PCRE regexps using the `:P5` modifier. -## (we won't be discussing this in this tutorial, however) +## We're first going to look at the syntax itself, then talk about grammars +## (PEG-like), differences between `token`, `regex` and `rule` declarators, +## and some more. Side note: you still have access to PCRE regexps using the +## `:P5` modifier which we won't be discussing this in this tutorial, though. ## ## In essence, Perl 6 natively implements PEG ("Parsing Expression Grammars"). ## The pecking order for ambiguous parses is determined by a multi-level -## tie-breaking test: -## - Longest token matching. `foo\s+` beats `foo` (by 2 or more positions) -## - Longest literal prefix. `food\w*` beats `foo\w*` (by 1) +## tie-breaking test: +## - Longest token matching: `foo\s+` beats `foo` (by 2 or more positions) +## - Longest literal prefix: `food\w*` beats `foo\w*` (by 1) ## - Declaration from most-derived to less derived grammars -## (grammars are actually classes) +## (grammars are actually classes) ## - Earliest declaration wins -say so 'a' ~~ /a/; #=> True -say so 'a' ~~ / a /; #=> True # More readable with some spaces! +say so 'a' ~~ /a/; #=> True +say so 'a' ~~ / a /; #=> True, more readable with some spaces! ## In all our examples, we're going to use the smart-matching operator against -## a regexp. We're converting the result using `so`, but in fact, it's -## returning a `Match` object. They know how to respond to list indexing, -## hash indexing, and return the matched string. -## The results of the match are available as `$/` (implicitly lexically-scoped). -## You can also use the capture variables which start at 0: -## `$0`, `$1', `$2`... +## a regexp. We're converting the result using `so` to a Boolean value because, +## in fact, it's returning a `Match` object. They know how to respond to list +## indexing, hash indexing, and return the matched string. The results of the +## match are available in the `$/` variable (implicitly lexically-scoped). You +## can also use the capture variables which start at 0: `$0`, `$1', `$2`... ## -## You can also note that `~~` does not perform start/end checking -## (meaning the regexp can be matched with just one char of the string), -## we're going to explain later how you can do it. - -## In Perl 6, you can have any alphanumeric as a literal, -## everything else has to be escaped, using a backslash or quotes. -say so 'a|b' ~~ / a '|' b /; # `True`. Wouldn't mean the same if `|` wasn't - # escaped -say so 'a|b' ~~ / a \| b /; # `True`. Another way to escape it. - -## The whitespace in a regexp is actually not significant, -## unless you use the `:s` (`:sigspace`, significant space) adverb. -say so 'a b c' ~~ / a b c /; #> `False`. Space is not significant here -say so 'a b c' ~~ /:s a b c /; #> `True`. We added the modifier `:s` here. +## You can also note that `~~` does not perform start/end checking, meaning +## the regexp can be matched with just one character of the string. We'll +## explain later how you can do it. + +## In Perl 6, you can have any alphanumeric as a literal, everything else has +## to be escaped by using a backslash or quotes. +say so 'a|b' ~~ / a '|' b /; #=> `True`, it wouldn't mean the same thing if + # `|` wasn't escaped. +say so 'a|b' ~~ / a \| b /; #=> `True`, another way to escape it. + +## The whitespace in a regexp is actually not significant, unless you use the +## `:s` (`:sigspace`, significant space) adverb. +say so 'a b c' ~~ / a b c /; #=> `False`, space is not significant here! +say so 'a b c' ~~ /:s a b c /; #=> `True`, we added the modifier `:s` here. + ## If we use only one space between strings in a regex, Perl 6 will warn us: -say so 'a b c' ~~ / a b c /; #> 'False' #> Space is not significant here; -## please use quotes or :s (:sigspace) modifier (or, to suppress this warning, -## omit the space, or otherwise change the spacing) -## To fix this and make the spaces less ambiguous, either use at least two -## spaces between strings or use the `:s` adverb. +say so 'a b c' ~~ / a b c /; #=> `False`, with warning about space +say so 'a b c' ~~ / a b c /; #=> `False` + +## Please use quotes or :s (:sigspace) modifier (or, to suppress this warning, +## omit the space, or otherwise change the spacing). To fix this and make the +## spaces less ambiguous, either use at least two spaces between strings +## or use the `:s` adverb. -## As we saw before, we can embed the `:s` inside the slash delimiters, but we +## As we saw before, we can embed the `:s` inside the slash delimiters, but we ## can also put it outside of them if we specify `m` for 'match': -say so 'a b c' ~~ m:s/a b c/; #> `True` -## By using `m` to specify 'match', we can also use delimiters other -## than slashes: -say so 'abc' ~~ m{a b c}; #> `True` +say so 'a b c' ~~ m:s/a b c/; #=> `True` + +## By using `m` to specify 'match', we can also use delimiters other than +## slashes: +say so 'abc' ~~ m{a b c}; #=> `True` +say so 'abc' ~~ m[a b c]; #=> `True` +# m/.../ is equivalent to /.../ ## Use the :i adverb to specify case insensitivity: -say so 'ABC' ~~ m:i{a b c}; #> `True` +say so 'ABC' ~~ m:i{a b c}; #=> `True` -## It is, however, important as for how modifiers (that you're gonna see just -## below) are applied ... +## However, whitespace is important as for how modifiers are applied ( +## (which you'll see just below) ... ## Quantifying - `?`, `+`, `*` and `**`. -## - `?` - 0 or 1 -so 'ac' ~~ / a b c /; # `False` -so 'ac' ~~ / a b? c /; # `True`, the "b" matched 0 times. -so 'abc' ~~ / a b? c /; # `True`, the "b" matched 1 time. +## `?` - zero or one match +so 'ac' ~~ / a b c /; #=> `False` +so 'ac' ~~ / a b? c /; #=> `True`, the "b" matched 0 times. +so 'abc' ~~ / a b? c /; #=> `True`, the "b" matched 1 time. -## ... As you read just before, whitespace is important because it determines -## which part of the regexp is the target of the modifier: -so 'def' ~~ / a b c? /; # `False`. Only the `c` is optional -so 'def' ~~ / a b? c /; # `False`. Whitespace is not significant -so 'def' ~~ / 'abc'? /; # `True`. The whole "abc" group is optional. +## ...As you read before, whitespace is important because it determines which +## part of the regexp is the target of the modifier: +so 'def' ~~ / a b c? /; #=> `False`, only the `c` is optional +so 'def' ~~ / a b? c /; #=> `False`, whitespace is not significant +so 'def' ~~ / 'abc'? /; #=> `True`, the whole "abc" group is optional ## Here (and below) the quantifier applies only to the `b` -## - `+` - 1 or more -so 'ac' ~~ / a b+ c /; # `False`; `+` wants at least one matching -so 'abc' ~~ / a b+ c /; # `True`; one is enough -so 'abbbbc' ~~ / a b+ c /; # `True`, matched 4 "b"s - -## - `*` - 0 or more -so 'ac' ~~ / a b* c /; # `True`, they're all optional. -so 'abc' ~~ / a b* c /; # `True` -so 'abbbbc' ~~ / a b* c /; # `True` -so 'aec' ~~ / a b* c /; # `False`. "b"(s) are optional, not replaceable. - -## - `**` - (Unbound) Quantifier -## If you squint hard enough, you might understand -## why exponentation is used for quantity. -so 'abc' ~~ / a b**1 c /; # `True` (exactly one time) -so 'abc' ~~ / a b**1..3 c /; # `True` (one to three times) -so 'abbbc' ~~ / a b**1..3 c /; # `True` -so 'abbbbbbc' ~~ / a b**1..3 c /; # `False` (too much) -so 'abbbbbbc' ~~ / a b**3..* c /; # `True` (infinite ranges are okay) - -## - `<[]>` - Character classes -## Character classes are the equivalent of PCRE's `[]` classes, but -## they use a more perl6-ish syntax: -say 'fooa' ~~ / f <[ o a ]>+ /; #=> 'fooa' +## `+` - one or more matches +so 'ac' ~~ / a b+ c /; #=> `False`, `+` wants at least one matching +so 'abc' ~~ / a b+ c /; #=> `True`, one is enough +so 'abbbbc' ~~ / a b+ c /; #=> `True`, matched 4 "b"s + +## `*` - zero or more matches +so 'ac' ~~ / a b* c /; #=> `True`, they're all optional. +so 'abc' ~~ / a b* c /; #=> `True` +so 'abbbbc' ~~ / a b* c /; #=> `True` +so 'aec' ~~ / a b* c /; #=> `False`. "b"(s) are optional, not replaceable. + +## `**` - (Unbound) Quantifier +## If you squint hard enough, you might understand why exponentation is used +## for quantity. +so 'abc' ~~ / a b**1 c /; #=> `True`, (exactly one time) +so 'abc' ~~ / a b**1..3 c /; #=> `True`, (one to three times) +so 'abbbc' ~~ / a b**1..3 c /; #=> `True` +so 'abbbbbbc' ~~ / a b**1..3 c /; #=> `False, (too much) +so 'abbbbbbc' ~~ / a b**3..* c /; #=> `True`, (infinite ranges are okay) + +## `<[]>` - Character classes +## Character classes are the equivalent of PCRE's `[]` classes, but they use a +## more perl6-ish syntax: +say 'fooa' ~~ / f <[ o a ]>+ /; #=> 'fooa' ## You can use ranges: say 'aeiou' ~~ / a <[ e..w ]> /; #=> 'ae' -## Just like in normal regexes, if you want to use a special character, -## escape it (the last one is escaping a space) +## Just like in normal regexes, if you want to use a special character, escape +## it (the last one is escaping a space which would be equivalent to using +## ' '): say 'he-he !' ~~ / 'he-' <[ a..z \! \ ]> + /; #=> 'he-he !' -## You'll get a warning if you put duplicate names -## (which has the nice effect of catching the wrote quoting:) -'he he' ~~ / <[ h e ' ' ]> /; # Warns "Repeated characters found in characters - # class" +## You'll get a warning if you put duplicate names (which has the nice effect +## of catching the raw quoting): +'he he' ~~ / <[ h e ' ' ]> /; +# Warns "Repeated character (') unexpectedly found in character class" -## You can also negate them ... (equivalent to `[^]` in PCRE) -so 'foo' ~~ / <-[ f o ]> + /; # False +## You can also negate character classes... (`<-[]>` equivalent to `[^]` in PCRE) +so 'foo' ~~ / <-[ f o ]> + /; #=> False -## ... and compose them: : -so 'foo' ~~ / <[ a..z ] - [ f o ]> + /; # False (any letter except f and o) -so 'foo' ~~ / <-[ a..z ] + [ f o ]> + /; # True (no letter except f and o) -so 'foo!' ~~ / <-[ a..z ] + [ f o ]> + /; # True (the + doesn't replace the +## ... and compose them: +so 'foo' ~~ / <[ a..z ] - [ f o ]> + /; #=> `False`, (any letter except f and o) +so 'foo' ~~ / <-[ a..z ] + [ f o ]> + /; #=> `True`, (no letter except f and o) +so 'foo!' ~~ / <-[ a..z ] + [ f o ]> + /; #=> `True`, (the + doesn't replace the # left part) ``` ### Grouping and capturing ```perl6 -## Group: you can group parts of your regexp with `[]`. -## These groups are *not* captured (like PCRE's `(?:)`). -so 'abc' ~~ / a [ b ] c /; # `True`. The grouping does pretty much nothing +## Group: you can group parts of your regexp with `[]`. Unlike PCRE's `(?:)`, +## these groups are *not* captured. +so 'abc' ~~ / a [ b ] c /; # `True`. The grouping does pretty much nothing so 'foo012012bar' ~~ / foo [ '01' <[0..9]> ] + bar /; -## The previous line returns `True`. -## We match the "012" 1 or more time (the `+` was applied to the group). + +## The previous line returns `True`. The regex matches "012" 1 or more time +## (achieved by the the `+` applied to the group). ## But this does not go far enough, because we can't actually get back what ## we matched. -## Capture: We can actually *capture* the results of the regexp, -## using parentheses. + +## Capture: The results of a regexp can be *captured* by using parentheses. so 'fooABCABCbar' ~~ / foo ( 'A' <[A..Z]> 'C' ) + bar /; # `True`. (using `so` # here, `$/` below) ## So, starting with the grouping explanations. -## As we said before, our `Match` object is available as `$/`: -say $/; # Will print some weird stuff (we'll explain) (or "Nil" if - # nothing matched). +## As we said before, our `Match` object is stored inside the `$/` variable: +say $/; # Will either print some weird stuff or `Nil` if nothing matched. ## As we also said before, it has array indexing: say $/[0]; #=> 「ABC」 「ABC」 - # These weird brackets are `Match` objects. + # These corner brackets are `Match` objects. # Here, we have an array of these. -say $0; # The same as above. +say $0; # The same as above. -## Our capture is `$0` because it's the first and only one capture in the +## Our capture is `$0` because it's the first and only one capture in the ## regexp. You might be wondering why it's an array, and the answer is simple: -## Some capture (indexed using `$0`, `$/[0]` or a named one) will be an array -## IFF it can have more than one element -## (so, with `*`, `+` and `**` (whatever the operands), but not with `?`). +## Some captures (indexed using `$0`, `$/[0]` or a named one) will be an array +## if and only if they can have more than one element. Thus any capture with +## `*`, `+` and `**` (whatever the operands), but not with `?`. ## Let's use examples to see that: ## Note: We quoted A B C to demonstrate that the whitespace between them isn't -## significant. If we want the whitespace to *be* significant there, we +## significant. If we want the whitespace to *be* significant there, we ## can use the :sigspace modifier. -so 'fooABCbar' ~~ / foo ( "A" "B" "C" )? bar /; # `True` -say $/[0]; #=> 「ABC」 +say so 'fooABCbar' ~~ / foo ( "A" "B" "C" )? bar /; #=> `True` +say $/[0]; #=> 「ABC」 say $0.WHAT; #=> (Match) # There can't be more than one, so it's only a single match object. -so 'foobar' ~~ / foo ( "A" "B" "C" )? bar /; #=> True +say so 'foobar' ~~ / foo ( "A" "B" "C" )? bar /; #=> True say $0.WHAT; #=> (Any) # This capture did not match, so it's empty -so 'foobar' ~~ / foo ( "A" "B" "C" ) ** 0..1 bar /; # `True` +so 'foobar' ~~ / foo ( "A" "B" "C" ) ** 0..1 bar /; #=> `True` say $0.WHAT; #=> (Array) # A specific quantifier will always capture an Array, - # may it be a range or a specific value (even 1). + # be a range or a specific value (even 1). -## The captures are indexed per nesting. This means a group in a group will be +## The captures are indexed per nesting. This means a group in a group will be ## nested under its parent group: `$/[0][0]`, for this code: 'hello-~-world' ~~ / ( 'hello' ( <[ \- \~ ]> + ) ) 'world' /; -say $/[0].Str; #=> hello~ +say $/[0].Str; #=> hello~ say $/[0][0].Str; #=> ~ -## This stems from a very simple fact: `$/` does not contain strings, integers -## or arrays, it only contains match objects. These contain the `.list`, `.hash` -## and `.Str` methods. (but you can also just use `match<key>` for hash access -## and `match[idx]` for array access) +## This stems from a very simple fact: `$/` does not contain strings, integers +## or arrays, it only contains Match objects. These contain the `.list`, `.hash` +## and `.Str` methods but you can also just use `match<key>` for hash access +## and `match[idx]` for array access. say $/[0].list.perl; #=> (Match.new(...),).list - # We can see it's a list of Match objects. Those contain - # a bunch of infos: where the match started/ended, - # the "ast" (see actions later), etc. + # We can see it's a list of Match objects. These contain + # a bunch of info: where the match started/ended, + # the "ast" (see actions later), etc. # You'll see named capture below with grammars. -## Alternatives - the `or` of regexps +## Alternation - the `or` of regexps ## WARNING: They are DIFFERENT from PCRE regexps. -so 'abc' ~~ / a [ b | y ] c /; # `True`. Either "b" or "y". -so 'ayc' ~~ / a [ b | y ] c /; # `True`. Obviously enough ... - -## The difference between this `|` and the one you're used to is LTM. -## LTM means "Longest Token Matching". This means that the engine will always -## try to match as much as possible in the strng -'foo' ~~ / fo | foo /; # `foo`, because it's longer. -## To decide which part is the "longest", it first splits the regex in +say so 'abc' ~~ / a [ b | y ] c /; #=> `True`. Either "b" or "y". +say so 'ayc' ~~ / a [ b | y ] c /; #=> `True`. Obviously enough... + +## The difference between this `|` and the one you're used to is +## LTM ("Longest Token Matching"). This means that the engine will always +## try to match as much as possible in the string. +say 'foo' ~~ / fo | foo /; #=> `foo`, instead of `fo`, because it's longer. + +## To decide which part is the "longest", it first splits the regex in ## two parts: ## The "declarative prefix" (the part that can be statically analyzed) -## and the procedural parts. -## Declarative prefixes include alternations (`|`), conjunctions (`&`), -## sub-rule calls (not yet introduced), literals, characters classes and +## and the procedural parts: +## - The declarative prefixes include alternations (`|`), conjunctions (`&`), +## sub-rule calls (not yet introduced), literals, characters classes and ## quantifiers. -## The latter include everything else: back-references, code assertions, -## and other things that can't traditionnaly be represented by normal regexps. +## - The procedural part include everything else: back-references, +## code assertions, and other things that can't traditionnaly be represented +## by normal regexps. ## ## Then, all the alternatives are tried at once, and the longest wins. ## Examples: @@ -1639,109 +1806,110 @@ so 'ayc' ~~ / a [ b | y ] c /; # `True`. Obviously enough ... ## DECLARATIVE (nested groups are not a problem) / \s* [ \w & b ] [ c | d ] /; ## However, closures and recursion (of named regexps) are procedural. -## ... There are also more complicated rules, like specificity -## (literals win over character classes) +## There are also more complicated rules, like specificity (literals win over +## character classes). ## Note: the first-matching `or` still exists, but is now spelled `||` -'foo' ~~ / fo || foo /; # `fo` now. +say 'foo' ~~ / fo || foo /; #=> `fo` now. ``` ## Extra: the MAIN subroutine ```perl6 -## The `MAIN` subroutine is called when you run a Perl 6 file directly. -## It's very powerful, because Perl 6 actually parses the arguments -## and pass them as such to the sub. It also handles named argument (`--foo`) -## and will even go as far as to autogenerate a `--help` -sub MAIN($name) { say "Hello, $name !" } +## The `MAIN` subroutine is called when you run a Perl 6 file directly. It's +## very powerful, because Perl 6 actually parses the arguments and pass them +## as such to the sub. It also handles named argument (`--foo`) and will even +## go as far as to autogenerate a `--help` flag. +sub MAIN($name) { + say "Hello, $name!"; +} ## This produces: -## $ perl6 cli.pl -## Usage: -## t.pl <name> +## $ perl6 cli.pl +## Usage: +## t.pl <name> ## And since it's a regular Perl 6 sub, you can have multi-dispatch: ## (using a "Bool" for the named argument so that we can do `--replace` -## instead of `--replace=1`) +## instead of `--replace=1`. The presence of `--replace` indicates truthness +## while its absence falseness). + subset File of Str where *.IO.d; # convert to IO object to check the file exists multi MAIN('add', $key, $value, Bool :$replace) { ... } multi MAIN('remove', $key) { ... } multi MAIN('import', File, Str :$as) { ... } # omitting parameter name + ## This produces: -## $ perl6 cli.pl -## Usage: -## t.pl [--replace] add <key> <value> -## t.pl remove <key> -## t.pl [--as=<Str>] import (File) -## As you can see, this is *very* powerful. -## It even went as far as to show inline the constants. -## (the type is only displayed if the argument is `$`/is named) +## $ perl6 cli.pl +## Usage: +## cli.p6 [--replace] add <key> <value> +## cli.p6 remove <key> +## cli.p6 [--as=<Str>] import <File> + +## As you can see, this is *very* powerful. It even went as far as to show inline +## the constants (the type is only displayed if the argument is `$`/is named). ``` ## APPENDIX A: ### List of things ```perl6 -## It's considered by now you know the Perl6 basics. -## This section is just here to list some common operations, -## but which are not in the "main part" of the tutorial to bloat it up +## It's assumed by now you know the Perl6 basics. This section is just here to +## list some common operations, but which are not in the "main part" of the +## tutorial to avoid bloating it up. ## Operators - -## * Sort comparison -## They return one value of the `Order` enum : `Less`, `Same` and `More` -## (which numerify to -1, 0 or +1). -1 <=> 4; # sort comparison for numerics -'a' leg 'b'; # sort comparison for string -$obj eqv $obj2; # sort comparison using eqv semantics - -## * Generic ordering -3 before 4; # True -'b' after 'a'; # True - -## * Short-circuit default operator -## Like `or` and `||`, but instead returns the first *defined* value : -say Any // Nil // 0 // 5; #=> 0 - -## * Short-circuit exclusive or (XOR) -## Returns `True` if one (and only one) of its arguments is true -say True ^^ False; #=> True -## * Flip Flop -## The flip flop operators (`ff` and `fff`, equivalent to P5's `..`/`...`). -## are operators that take two predicates to test: -## They are `False` until their left side returns `True`, then are `True` until -## their right side returns `True`. -## Like for ranges, you can exclude the iteration when it became `True`/`False` -## by using `^` on either side. -## Let's start with an example : +## Sort comparison - they return one value of the `Order` enum: `Less`, `Same` +## and `More` (which numerify to -1, 0 or +1 respectively). +1 <=> 4; # sort comparison for numerics +'a' leg 'b'; # sort comparison for string +$obj eqv $obj2; # sort comparison using eqv semantics + +## Generic ordering +3 before 4; # True +'b' after 'a'; # True + +## Short-circuit default operator - similar to `or` and `||`, but instead +## returns the first *defined* value: +say Any // Nil // 0 // 5; #=> 0 + +## Short-circuit exclusive or (XOR) - returns `True` if one (and only one) of +## its arguments is true +say True ^^ False; #=> True + +## Flip flops - these operators (`ff` and `fff`, equivalent to P5's `..` +## and `...`) are operators that take two predicates to test: They are `False` +## until their left side returns `True`, then are `True` until their right +## side returns `True`. Similar to ranges, you can exclude the iteration when +## it become `True`/`False` by using `^` on either side. Let's start with an +## example : for <well met young hero we shall meet later> { - # by default, `ff`/`fff` smart-match (`~~`) against `$_`: - if 'met' ^ff 'meet' { # Won't enter the if for "met" - # (explained in details below). - .say - } + # by default, `ff`/`fff` smart-match (`~~`) against `$_`: + if 'met' ^ff 'meet' { # Won't enter the if for "met" + .say # (explained in details below). + } - if rand == 0 ff rand == 1 { # compare variables other than `$_` - say "This ... probably will never run ..."; - } + if rand == 0 ff rand == 1 { # compare variables other than `$_` + say "This ... probably will never run ..."; + } } -## This will print "young hero we shall meet" (excluding "met"): -## the flip-flop will start returning `True` when it first encounters "met" -## (but will still return `False` for "met" itself, due to the leading `^` -## on `ff`), until it sees "meet", which is when it'll start returning `False`. - -## The difference between `ff` (awk-style) and `fff` (sed-style) is that -## `ff` will test its right side right when its left side changes to `True`, -## and can get back to `False` right away -## (*except* it'll be `True` for the iteration that matched) - -## While `fff` will wait for the next iteration to -## try its right side, once its left side changed: + +## This will print "young hero we shall meet" (excluding "met"): the flip-flop +## will start returning `True` when it first encounters "met" (but will still +## return `False` for "met" itself, due to the leading `^` on `ff`), until it +## sees "meet", which is when it'll start returning `False`. + +## The difference between `ff` (awk-style) and `fff` (sed-style) is that `ff` +## will test its right side right when its left side changes to `True`, and can +## get back to `False` right away (*except* it'll be `True` for the iteration +## that matched) while `fff` will wait for the next iteration to try its right +## side, once its left side changed: .say if 'B' ff 'B' for <A B C B A>; #=> B B # because the right-hand-side was tested # directly (and returned `True`). - # "B"s are printed since it matched that - # time (it just went back to `False` + # "B"s are printed since it matched that + # time (it just went back to `False` # right away). .say if 'B' fff 'B' for <A B C B A>; #=> B C B # The right-hand-side wasn't tested until @@ -1750,50 +1918,49 @@ for <well met young hero we shall meet later> { ## A flip-flop can change state as many times as needed: for <test start print it stop not printing start print again stop not anymore> { - .say if $_ eq 'start' ^ff^ $_ eq 'stop'; # exclude both "start" and "stop", - #=> "print it print again" + .say if $_ eq 'start' ^ff^ $_ eq 'stop'; # exclude both "start" and "stop", + #=> "print it print again" } -## You might also use a Whatever Star, -## which is equivalent to `True` for the left side or `False` for the right: +## You might also use a Whatever Star, which is equivalent to `True` for the +## left side or `False` for the right: for (1, 3, 60, 3, 40, 60) { # Note: the parenthesis are superfluous here # (sometimes called "superstitious parentheses") - .say if $_ > 50 ff *; # Once the flip-flop reaches a number greater than 50, - # it'll never go back to `False` - #=> 60 3 40 60 + .say if $_ > 50 ff *; # Once the flip-flop reaches a number greater + # than 50, it'll never go back to `False` + #=> 60 3 40 60 } -## You can also use this property to create an `If` -## that'll not go through the first time : +## You can also use this property to create an `if` that'll not go through the +## first time: for <a b c> { - .say if * ^ff *; # the flip-flop is `True` and never goes back to `False`, - # but the `^` makes it *not run* on the first iteration - #=> b c + .say if * ^ff *; # the flip-flop is `True` and never goes back to `False`, + # but the `^` makes it *not run* on the first iteration + #=> b c } - -## - `===` is value identity and uses `.WHICH` on the objects to compare them -## - `=:=` is container identity and uses `VAR()` on the objects to compare them - +## The `===` operator is the value identity operator and uses `.WHICH` on the +## objects to compare them while `=:=` is the container identity operator +## and uses `VAR()` on the objects to compare them. ``` If you want to go further, you can: - Read the [Perl 6 Docs](https://docs.perl6.org/). This is a great - resource on Perl6. If you are looking for something, use the search bar. + resource on Perl6. If you are looking for something, use the search bar. This will give you a dropdown menu of all the pages referencing your search - term (Much better than using Google to find Perl 6 documents!) + term (Much better than using Google to find Perl 6 documents!). - Read the [Perl 6 Advent Calendar](http://perl6advent.wordpress.com/). This - is a great source of Perl 6 snippets and explanations. If the docs don't + is a great source of Perl 6 snippets and explanations. If the docs don't describe something well enough, you may find more detailed information here. This information may be a bit older but there are many great examples and - explanations. Posts stopped at the end of 2015 when the language was declared + explanations. Posts stopped at the end of 2015 when the language was declared stable and Perl 6.c was released. - - Come along on `#perl6` at `irc.freenode.net`. The folks here are + - Come along on `#perl6` at `irc.freenode.net`. The folks here are always helpful. - - Check the [source of Perl 6's functions and - classes](https://github.com/rakudo/rakudo/tree/nom/src/core). Rakudo is + - Check the [source of Perl 6's functions and + classes](https://github.com/rakudo/rakudo/tree/nom/src/core). Rakudo is mainly written in Perl 6 (with a lot of NQP, "Not Quite Perl", a Perl 6 subset easier to implement and optimize). - - Read [the language design documents](http://design.perl6.org). They explain + - Read [the language design documents](http://design.perl6.org). They explain P6 from an implementor point-of-view, but it's still very interesting. diff --git a/pl-pl/java-pl.html.markdown b/pl-pl/java-pl.html.markdown new file mode 100644 index 00000000..0da449c5 --- /dev/null +++ b/pl-pl/java-pl.html.markdown @@ -0,0 +1,1026 @@ +--- +language: java +filename: LearnJavaPl.java +contributors: + - ["Jake Prather", "https://github.com/JakeHP"] + - ["Jakukyo Friel", "https://weakish.github.io"] + - ["Madison Dickson", "https://github.com/mix3d"] + - ["Simon Morgan", "https://sjm.io/"] + - ["Zachary Ferguson", "https://github.com/zfergus2"] + - ["Cameron Schermerhorn", "https://github.com/cschermerhorn"] + - ["Rachel Stiyer", "https://github.com/rstiyer"] + - ["Michael Dähnert", "https://github.com/JaXt0r"] + - ["Rob Rose", "https://github.com/RobRoseKnows"] + - ["Sean Nam", "https://github.com/seannam"] + - ["Shawn M. Hanes", "https://github.com/smhanes15"] +filename: LearnJava.java +translators: + - ["Jacek Wachowiak", "https://github.com/jacekwachowiak"] +lang: pl-pl +--- + +Java jest współbieżnym, opartym na klasach, obiektowym językiem programowania +ogólnego zastosowania. +[Tu znajdziesz więcej informacji po angielsku.] +(https://docs.oracle.com/javase/tutorial/java/) + +```java +// Pojedyncze komentarze oznaczamy // + +/* +Komentarze wieloliniowe wyglądają tak +*/ + +/** + * Komentarze JavaDoc wygladają w ten sposób. Używane są do opisu klas lub + * różnych właściwości klas. + * Główne właściwości: + * + * @author Imię i nazwisko (i kontakt np. email) autora. + * @version Aktualna wersja programu. + * @since Kiedy ta część programu została dodana. + * @param Służy do opisu parametrów metody. + * @return Służy do opisu zwracanej wartości. + * @deprecated Służy do oznaczenia nieaktualnego lub niezalecanego kodu. + * @see Linki do innej cześci dokumentacji. +*/ + +// Import klasy ArrayList z paczki java.util +import java.util.ArrayList; +// Import wszystkich klas z paczki java.security +import java.security.*; + +public class LearnJava { + + // Aby móc uruchomić program w języku java musi on mieć główną metodę jako + // punkt wejścia. + public static void main(String[] args) { + + /////////////////////////////////////// + // Operacje wejścia/wyjścia (input/output) + /////////////////////////////////////// + + /* + * Wyjście + */ + + // System.out.println() służy do wyświetlania linii tekstu. + System.out.println("Hello World!"); + System.out.println( + "Integer: " + 10 + + " Double: " + 3.14 + + " Boolean: " + true); + + // Aby wyświetlić bez nowej linii użyj System.out.print(). + System.out.print("Hello "); + System.out.print("World"); + + // System.out.printf() służy do łatwego formatowania wyświetlanego elementu. + System.out.printf("pi = %.5f", Math.PI); // => pi = 3.14159 + + /* + * Wejście + */ + + // Scanner służy do wczytywania danych + // niezbędny jest import java.util.Scanner; + Scanner scanner = new Scanner(System.in); + + // zczytaj string (tekst) + String name = scanner.next(); + + // zczytaj zmienną typu bajt + byte numByte = scanner.nextByte(); + + // zczytaj zmienną typu integer - liczba całkowita + int numInt = scanner.nextInt(); + + // zczytaj zmienną typu float - liczba zmiennoprzecinkowa + float numFloat = scanner.nextFloat(); + + // zczytaj zmienna typu double -liczba zmiennoprzecinkowa + double numDouble = scanner.nextDouble(); + + // zczytaj zmienną typu boolowskiego - + boolean bool = scanner.nextBoolean(); + + /////////////////////////////////////// + // Zmienne + /////////////////////////////////////// + + /* + * Deklaracja zmiennych + */ + // Zmienną deklaruje się poprzez <rodzaj> <nazwa> + int fooInt; + // Dozwolona jest deklaracja wielu zmiennych tego samego typu na raz + // rodzaj <nazwa1>, <nazwa2>, <nazwa3> + int fooInt1, fooInt2, fooInt3; + + /* + * Inicjalizacja zmiennych + */ + + // Zmienną inicjalizuje się poprzez <rodzaj> <nazwa> = <wartość> + int barInt = 1; + // Możliwe jest zainicjalizowanie wielu zmiennych tego samego typu tą samą wartością + // rodzaj <nazwa1>, <nazwa2>, <nazwa3> + // <nazwa1> = <nazwa2> = <nazwa3> = <wartość> + int barInt1, barInt2, barInt3; + barInt1 = barInt2 = barInt3 = 1; + + /* + * Rodzaje zmiennych + */ + // Bajt - 8-bitowa, zawierająca ujemne wartości zmienna w dwójkowym + // systemie pozycyjnym + // (-128 <= byte <= 127) + byte fooByte = 100; + + // Jeśli chcemy zinterpretować bajt jako zmienną typu unsigned integer + // - liczbę całkowitą z wartościami ujemnymi ta operacja może pomóc: + int unsignedIntLessThan256 = 0xff & fooByte; + // jako kontrast operacja zmiany typu która może zwrócić wartość ujemną. + int signedInt = (int) fooByte; + + // Short - 16-bitowa, zawierająca ujemne wartości zmienna w dwójkowym + // systemie pozycyjnym (-32,768 <= short <= 32,767) + short fooShort = 10000; + + // Integer - 32-bitowa, zawierająca ujemne wartości zmienna w dwójkowym systemie pozycyjnym + // (-2,147,483,648 <= int <= 2,147,483,647) + int bazInt = 1; + + // Long - 64-bitowa, zawierająca ujemne wartości zmienna w dwójkowym + // systemie pozycyjnym + // (-9,223,372,036,854,775,808 <= long <= 9,223,372,036,854,775,807) + long fooLong = 100000L; + // L jest używane do zaznaczenia, że wartość zmiennej jest typu Long; + // bez L wszystko inne będzie traktowane z założenia jako integer. + + // Uwaga: byte, short, int and long zawierają ujemne wartości. + // Nie istnieją odpowiedniki z jedynie pozytywnymi wartościami. + // Jedynie char jest 16-bitowym typem zmiennej, który akceptuje tylko + // wartości nieujemne. + + // Float - 32-bitowy typ zmiennoprzecinkowy zgodnie z IEEE 754 + // Floating Point 2^-149 <= float <= (2-2^-23) * 2^127 + float fooFloat = 234.5f; + // f or F jest używane aby zaznaczyć, że dana zmienna jest typu float; + // w przeciwnym razie będzie ona traktowana jako double. + + // Double - 64-bitowy typ zmiennoprzecinkowy zgodnie z IEEE 754 + // Floating Point 2^-1074 <= x <= (2-2^-52) * 2^1023 + double fooDouble = 123.4; + + // Typ boolowski - true/prawda & false/fałsz + boolean fooBoolean = true; + boolean barBoolean = false; + + // Char - pojedynczy 16-bitowy symbol Unicode + char fooChar = 'A'; + + // zmienne zadeklarowane z użyciem final nie mogą być edytowane, + final int HOURS_I_WORK_PER_WEEK = 9001; + // ale możliwa jest późniejsza inicjalizacja. + final double E; + E = 2.71828; + + // BigInteger - Nieedytowalny typ zmiennej o nieograniczonej długości + // dla liczb całkowitych + // + // BigInteger jest typem zmiennej, który pozwala na operacje na liczbach całkowitych dłuższych niż 64 bity. + // Liczby są przechowywane jako tablica bajtów + // i modyfikowane za pomocą funkcji wbudowanych w BigInteger + // + // BigInteger może być zainicjalizowany za pomocą tablicy bajtów lub jako string. + BigInteger fooBigInteger = new BigInteger(fooByteArray); + + // BigDecimal - Nieedytowalny typ zmiennej o nieograniczonej długości dla + // liczb zmiennoprzecinkowych + // + // BigDecimal zaiwera 2 części: typ integer o arbitralnej precyzji bez skalowania + // oraz 32-bitową skalę + // + // BigDecimal pozwala programiście na całkowitą kontrolę zaokrąglenia dziesiętnego. + // Zalecane jest używanie BigDecimal z wartościami walut. + // oraz tam, gdzie absolutna dokładność jest niezbędna. + // + // BigDecimal można zainicjalizowac używając int, long, double or String + // a także inicjalizując nieprzeskalowaną wartość (BigInteger) i skalę (int). + BigDecimal fooBigDecimal = new BigDecimal(fooBigInteger, fooInt); + + // Uwaga na konstruktor, który przyjmuje float lub double jako, że + // niedokładność float/double będzie przeniesiona do BigDecimal. + // Zalecane jest uzywanie konstruktora typu String gdy konieczne jest + // uzyskanie absolutnej precyzji. + BigDecimal tenCents = new BigDecimal("0.1"); + + // String - zmienna tekstowa + String fooString = "Tutaj jest mój string!"; + + // \n jest symbolem karetki, która rozpoczyna nową linę + String barString = "Wyświetlanie w nowej linii?\nNie ma problemu!"; + // \t jest symbolem tabulatora, który dodaje odstęp. + String bazString = "Chesz dodać tabulator?\tBez problemu!"; + System.out.println(fooString); + System.out.println(barString); + System.out.println(bazString); + + // Budowanie Stringów + // #1 - za pomocą operatora dodawania + // To jest podstawowy sposób (zoptymalizowany) + String plusConcatenated = "Stringi mogą " + "być łączone " + "operatorem +."; + System.out.println(plusConcatenated); + // Wyjście: Stringi będą połączone operatorem +. + + // #2 - za pomocą StringBuilder + // Ten sposób nie tworzy żadnych pośrednich stringów, jedynie zachowuje + // części i wiąże je po kolei gdy wywołane jest toString(). + // Wskazówka: Ta klasa nie jest bezpieczna z punktu widzenia wątków. + // Bezpieczną alternatywą jest (wiążąca się ze spadkiem wydajności) + // StringBuffer. + StringBuilder builderConcatenated = new StringBuilder(); + builderConcatenated.append("Możesz "); + builderConcatenated.append("użyć "); + builderConcatenated.append("klasy StringBuilder."); + System.out.println(builderConcatenated.toString()); // dopiero tutaj + //budowany jest string + // Wyjście: Używany jest StringBuilder. + + // StringBuilder jest wydajny, gdy połączony string nie jest używany aż do końcowego przetworzenia. + StringBuilder stringBuilder = new StringBuilder(); + String inefficientString = ""; + for (int i = 0 ; i < 10; i++) { + stringBuilder.append(i).append(" "); + inefficientString += i + " "; + } + System.out.println(inefficientString); + System.out.println(stringBuilder.toString()); + // inefficientString wymaga dużo więcej pracy przy stworzeniu ponieważ + // tworzy string przy każdej iteracji. + // Proste łączenie za pomocą + jest kompilowane do StringBuilder i + // toString(). Unikaj łączenia stringów w pętlach. + + // #3 - za pomocą String formatter + // Inna możliwość, szybka i czytelna. + String.format("%s wolisz %s.", "A może", "String.format()"); + // Wyjście: Być może wolisz String.format(). + + // Tablice + // Rozmiar tablicy musi być określony przy stworzeniu. + // Podane poniżej sposoby są dozwolone prz deklaracji tablicy + // <rodzaj>[] <nazwa> = new <rodzaj>[<rozmiar>]; + // <rodzaj> <nazwa>[] = new <rodzaj>[<rozmiar>]; + int[] intArray = new int[10]; + String[] stringArray = new String[1]; + boolean boolArray[] = new boolean[100]; + + // Inny sposób deklaracji i inicjalizacji tablicy + int[] y = {9000, 1000, 1337}; + String names[] = {"Bob", "John", "Fred", "Juan Pedro"}; + boolean bools[] = {true, false, false}; + + // Indeksowanie tablicy - dostęp do elementów + System.out.println("intArray @ 0: " + intArray[0]); + + // Tablice zaczynają się z indeksem 0 i są edytowalne. + intArray[1] = 1; + System.out.println("intArray @ 1: " + intArray[1]); // => 1 + + // Inny typ zmiennej, z którymi warto się zapoznać + // ArrayLists - Tablice z większą funkcjonalnością + // i zmiennym rozmiarem. + // LinkedLists - Dwustronnie połączone listy. Wszystkie operacje + // na listach zaimpllementowane. + // Maps - Mapy zawierające klucz i wartość. Mapa jest interfejsem + // i nie może zostać zainicjalizowana. + // Rodzaj klucza i wartości dla mapy musi zostać określony + // przy inicjalizacji implementującej mapę klasy + // Każdy klucz przypisany jest do tylko jednej wartości, + // każdy klucz może wystąpić tylko raz (brak duplikatów). + // HashMaps - Używa tablicy hashów do implementacji interfejsu mapy + // Pozwala to na użycie podstawowych operacji, jak + // get i insert, które pozostają niezmiennie wydajne + // czasowo nawet dla dużych zestawów danych + // TreeMap - Mapa posortowana przez klucze. Każda modyfikacja + // utrzymuje sortowanie, zdefiniowane przez komparator + // dodany przy inicjalizacji lub porównanie każdego obiektu + // jeśli zaimplementowany jest interfejs Comparable. + // Niepowodzenie kluczy wimplemntacji Comparable połączone + // z niepowodzeniem dostarczenia komparatora spowoduje + // ClassCastExceptions. + // Dodawanie i usuwanie kosztuje O(log(n)) czasu, + // zalecane jest nieużywanie tego typu jeżeli sortowanie + // nie jest przydatne. + + /////////////////////////////////////// + // Operatory + /////////////////////////////////////// + System.out.println("\n->Operatory"); + + int i1 = 1, i2 = 2; // Skrót dla wielokrotnych deklaracji + + // Arytmetyka jest prosta + System.out.println("1+2 = " + (i1 + i2)); // => 3 + System.out.println("2-1 = " + (i2 - i1)); // => 1 + System.out.println("2*1 = " + (i2 * i1)); // => 2 + System.out.println("1/2 = " + (i1 / i2)); // => 0 (int/int zwraca int) + System.out.println("1/2.0 = " + (i1 / (double)i2)); // => 0.5 + + // Modulo + System.out.println("11%3 = "+(11 % 3)); // => 2 + + // Porównania + System.out.println("3 == 2? " + (3 == 2)); // => false + System.out.println("3 != 2? " + (3 != 2)); // => true + System.out.println("3 > 2? " + (3 > 2)); // => true + System.out.println("3 < 2? " + (3 < 2)); // => false + System.out.println("2 <= 2? " + (2 <= 2)); // => true + System.out.println("2 >= 2? " + (2 >= 2)); // => true + + // Operacje boolowskie + System.out.println("3 > 2 && 2 > 3? " + ((3 > 2) && (2 > 3))); // => false + System.out.println("3 > 2 || 2 > 3? " + ((3 > 2) || (2 > 3))); // => true + System.out.println("!(3 == 2)? " + (!(3 == 2))); // => true + + // Operacje na bitach! + /* + ~ Odwrócenie bitów + << Przesunięcie w lewo + >> Przesunięcie w prawo, arytmetyczne/dla wartości ujemnych -signed + >>> Przesunięcie w prawo, logiczne/dla wartości dodatnich - unsigned + & Bitowe AND + ^ Bitowe XOR + | Bitowe OR + */ + + // Operatory inkrementacji + int i = 0; + System.out.println("\n->In/De-krementacja"); + // Operatory ++ i -- zwiększają lub zmniejszają o 1 daną wartość. + // Jeżeli używane są przed zmienną, wykonywane są przed powrotem zmiennej. + // Użyte po zmiennej najpierw zwracają zmienną a następnie dokonują + // zmiany wartości. + System.out.println(i++); // i = 1, wyświetli 0 (post-increment) + System.out.println(++i); // i = 2, wyświetli 2 (pre-increment) + System.out.println(i--); // i = 1, wyświetli 2 (post-decrement) + System.out.println(--i); // i = 0, wyświetli 0 (pre-decrement) + + /////////////////////////////////////// + // Przepływ sterowania + /////////////////////////////////////// + System.out.println("\n->Przepływ sterowania"); + + // Instrukcja if wygląda jak w c + int j = 10; + if (j == 10) { + System.out.println("Wyświetlam się"); + } else if (j > 10) { + System.out.println("A ja nie"); + } else { + System.out.println("Ja też nie"); + } + + // Pętla while + int fooWhile = 0; + while(fooWhile < 100) { + System.out.println(fooWhile); + // Licznik jest zwiększany + // Iteruje 100 razy, fooWhile 0,1,2...99 + fooWhile++; + } + System.out.println("Wartość fooWhile: " + fooWhile); + + // Pętla do while + int fooDoWhile = 0; + do { + System.out.println(fooDoWhile); + // Licznik jest zwiększany + // Iteruje 99 razy, fooDoWhile 0->99 + fooDoWhile++; + } while(fooDoWhile < 100); + System.out.println("Wartość fooDoWhile: " + fooDoWhile); + + // Pętla for + // struktura pętli for => for(<początek>; <warunek>; <krok>) + for (int fooFor = 0; fooFor < 10; fooFor++) { + System.out.println(fooFor); + // Iteruje 10 razy, fooFor 0->9 + } + System.out.println("Wartość fooFor: " + fooFor); + + // Wyjście z zagnieżdżonej, oznaczonej pętli for + outer: + for (int i = 0; i < 10; i++) { + for (int j = 0; j < 10; j++) { + if (i == 5 && j ==5) { + break outer; + // wychodzi z zewnętrznej pętli zamiast jednynie z aktualnej z + // powodu oznaczenia + } + } + } + + // Pętla for each + // Pętla for each może iterować tablice jak i obiekty + // które implementują interfejs Iterable. + int[] fooList = {1, 2, 3, 4, 5, 6, 7, 8, 9}; + // Struktura for each => for (<element> : <obiekt iterowany>) + // należy rozumieć jako: dla każdego elementu w obiekcie iterowanym + // uwaga: typ zdefiniowango elementu musi się zgadzać z typem w + //obiekcie iterowanym. + for (int bar : fooList) { + System.out.println(bar); + //Iteruje 9 razy i wyświetla 1-9 w nowych liniach + } + + // Switch Case + // Switch (przełącznik) działa z zmiennymi typu byte, short, char, int. + // Działa również z enumeratorami (zobacz typ Enum), + // klasą String, i kilkoma specjalnymi klasami które zawierają typy + // podstawowe: Character, Byte, Short, and Integer. + // Z wersją Java 7 i wyższymi możliwe jest użycie typu String. + // Uwagga: Pamiętaj, że nie dodając "break" na końcu danego case + // spowoduje przejście do następnego (jeżeli spełniony jest warunek). + int month = 3; + String monthString; + switch (month) { + case 1: monthString = "Styczeń"; + break; + case 2: monthString = "Luty"; + break; + case 3: monthString = "Marzec"; + break; + default: monthString = "Inny miesiąc"; + break; + } + System.out.println("Wynik Switch Case : " + monthString); + + + // Try-with-resources (Java 7+) + // Try-catch-finally działa zgodnie z oczekiwaniami jednakże w Java 7+ + // dodatkowo jest dostępny try-with-resources statement. + // Try-with-resources upraszcza try-catch-finally automatycznie + // usuwając zasoby. + + // Aby użyć try-with-resources, użyj instancji klasy + // w części "try". Klasa musi implementować java.lang.AutoCloseable. + try (BufferedReader br = new BufferedReader(new FileReader("foo.txt"))) { + // Tutaj możesz spróbować wywołac wyjątek. + System.out.println(br.readLine()); + // W Java 7 zasoby będą zawsze usuwane nawet jeśli nastąpi wyjątek. + } catch (Exception ex) { + // Zasób będzie usunięty zanim wykona się catch. + System.out.println("readLine() nie powiódł się."); + } + // Nie ma potrzeby używać sekcji "finally", jako że BufferedReader + // został już zamknięty. Ten sposób może zostać użyty aby uniknąć + // pewnych wartości brzegowych gdzie "finally" nie zostałoby wywołane + // Więcej na ten temat po angielsku: + // https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html + + + // Skrócone instrukcje warunkowe + // Dozwolone jest użycie operatora '?' aby szybko sprawdzić warunek + // logiczny. Rozumiane jest to jako "Jeśli (warunek) jest spełniony, użyj + // <pierwszej wartości>, inaczej, użyj <drugiej wartości>" + int foo = 5; + String bar = (foo < 10) ? "A" : "B"; + System.out.println("bar : " + bar); // Wyśwletli "bar : A", poineważ + // warunke jest spełniony. + // Lub prościej + System.out.println("bar : " + (foo < 10 ? "A" : "B")); + + + //////////////////////////////////////// + // Konwersja typów danych + //////////////////////////////////////// + + // Konwersja danych + + // Konwersja String do Integer + Integer.parseInt("123");//zwraca zmienna typu Integer o wartości "123" + + // Konwersja Integer do String + Integer.toString(123);//zwraca zmienną typu String o wartości 123 + + // Inne konwersje możesz sprawdzić dla klas: + // Double + // Long + // String + + /////////////////////////////////////// + // Klasy i funkcje + /////////////////////////////////////// + + System.out.println("\n->Klasy & Funkcje"); + + // (definicja klasy Rower nieco niżej) + + // Użyj new aby zainstancjonować klasę + Rower trek = new Rower(); + + // Wywoływanie metod klasy + trek.predkoscZwieksz(3); // Zawsze używaj settera i gettera jako metod + trek.setPedalowanie(100); + + // toString zwraca reprezentację typu String tego obiektu. + System.out.println("trek info: " + trek.toString()); + + // Inicjalizacja za pomocą podwójnego nawiasu + // Język Java nie zawiera możliwości stworzenia statycznej kolekcji + // Dlatego zwykle odbywa się to w ten sposób: + private static final Set<String> KRAJE = new HashSet<String>(); + static { + KRAJE.add("DANIA"); + KRAJE.add("SZWECJA"); + KRAJE.add("FINLANDIA"); + } + + // Jest jednak sprytny sposób aby łatwiej osiągnąc ten sam efekt + // używając czegoś nazywanego Double Brace Initialization - + // inicjalizacja za pomocą podwójnego nawiasu. + private static final Set<String> KRAJE = new HashSet<String>() {{ + add("DANIA"); + add("SZWECJA"); + add("FINLANDIA"); + }} + + // Pierwszy nawias tworzy nową klasę AnonymousInnerClass, + // drugi deklaruje instancję bloku inicjalizacji. Blok ten + // jest wywoływany gdy wewnętrzna, anonimowa klasa jest tworzona. + // Dany sposób działa nie tylko dla kolekcji, ale również dla + // wszystkich nie-finalnych klas. + + } // Koniec metody main +} // Koniec klasy LearnJava + +// Możesz zawrzeć inne, niepubliczne, zewnętrzne klasy w pliku .java, +// jednak nie jest to zalecane. Zalecane jest dzielenie klas na osobne pliki. + +// Składnia deklaracji klasy: +// <public/private/protected> class <nazwa klasy> { +// // pola danych, konstruktory, funkcje. +// // w jężyku Java funkcje są wywoływane jako metody. +// } + +class Rower { + + // Zmienne klasy + public int pedalowanie; // Public: Dostępne wszędzie + private int predkosc; // Private: Dostępne tylko w klasie + protected int przerzutka; // Protected: Dostępne w klasie i podklasach + String nazwa; // domyślnie: Dostępne tlyko w danej paczce + static String nazwaKlasy; // Zmienna statyczna + + // Blok statyczny + // Java nie posiada implemntacji konstruktorów staycznych, ale + // posiada blok stayczny, który może być użyty aby zainicjalizować + // statyczne zmienne klasy + // Ten blok będzie wywołane gdy klasa jest ładowana. + static { + nazwaKlasy = "Rower"; + } + + // Konstruktory służą do stworzenia instancji klas + // Too jest konstruktor + public Rower() { + // Możesz wywołać także inny konstruktor: + // this(1, 50, 5, "Bontrager"); + przerzutka = 1; + pedalowanie = 50; + predkosc = 5; + nazwa = "Bontrager"; + } + // To jest konstruktor, który przyjmuje argumenty + public Rower(int poczatkowePedalowanie, int poczatkowaPredkosc, int początkowaPrzerzutka, + String nazwa) { + this.przerzutka = początkowaPrzerzutka; + this.pedalowanie = poczatkowePedalowanie; + this.predkosc = poczatkowaPredkosc; + this.nazwa = nazwa; + } + + // Składnia metod: + // <public/private/protected> <zwracany rodzaj> <nazwa funkcji>(<argumenty>) + + // Klasy często implementują metody getter i setter dla danych wewnątrz + + // Składnia deklaracji metody: + // <dostępność> <zwracany rodzaj> <nawa metody>(<argumenty>) + public int getPedalowanie() { + return pedalowanie; + } + + // metody void nie wymagają słowa kluczowego return, nic nie zwracają + public void setPedalowanie(int newValue) { + pedalowanie = newValue; + } + public void setPrzerzutka(int newValue) { + przerzutka = newValue; + } + public void predkoscZwieksz(int inkrement) { + predkosc += inkrement; + } + public void predkoscZmniejsz(int dekrement) { + predkosc -= dekrement; + } + public void nadajNazwe(String nowaNazwa) { + nazwa = nowaNazwa; + } + public String zwrocNazwe() { + return nazwa; + } + + // Metoda do wyświetlenia wartości atrybutów danego obiektu. + @Override // Dziedziczy z klasy obiektu. + public String toString() { + return "przerzutka: " + przerzutka + " pedalowanie: " + pedalowanie + " predkosc: " + predkosc + + " nazwa: " + nazwa; + } +} // koniec klasy Rower + +// PennyFarthing jest podklasą klasy Rower +class PennyFarthing extends Rower { + // (Penny Farthing to rower z wielkim przednim kołem. + // Nie ma przerzutek.) + + public PennyFarthing(int poczatkowePedalowanie, int poczatkowaPredkosc) { + // Wywołanie kostruktora klasy z której dziedziczymy za pomocą super + super(poczatkowePedalowanie, poczatkowaPredkosc, 0, "PennyFarthing"); + } + + // Używamy annotacji @annotation przy przeciążaniu metod. + // Aby dowiedzieć się więcej o annotacjach przydatne jest przejrzenie + // (w języku angielskim): + // http://docs.oracle.com/javase/tutorial/java/annotations/ + @Override + public void setPrzerzutka(int przerzutka) { + this.przerzutka = 0; + } +} + +// Rzutowanie +// Jako, że klasa PennyFarthing dziedziczy z klasy Rower, możemy uznać, że +// instancja PennyFarthing jest typu Rower i napisać : +// Rower rower = new PennyFarthing(); +// Dana operacja jest rzutowaniem obiektu, gdzie jego domyślna klasa jest inna niż docelowa. +// Więcej szczegółów i przykładów oraz ciekawych konceptów (po angielsku): +// https://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html + +// Interfejsy +// Składnia deklaracji interfejsu +// <dostępność> interface <nazwa interfejsu> extends <super-interfaces> { +// // Zmienne typu constant +// // Deklaracje metod +// } + +// Przykład - Jedzenie: +public interface Jadalne { + public void jedz(); // Każda klasa która implemetuje ten interfejs musi + // implementować tę metodę. +} + +public interface Przetrawialne { + public void przetrawiaj(); + // Wraz z Java 8, interfejsy mogą mieć metodę domyślną. + public default void defaultMethod() { + System.out.println("Hej z metody domyślnej ..."); + } +} + +// Teraz stworzymy klasę, która zaimplementuje oba interfejsy. +public class Owoc implements Jadalne, Przetrawialne { + @Override + public void jedz() { + // ... + } + + @Override + public void przetrawiaj() { + // ... + } +} + +// W Javie możesz dziedziczyć jedynie z jednej klasy, jednak implementować +// wiele interfejsów. Na przykład: +public class Przyklad extends Przodek implements Interfejs1, + Interfejs2 { + @Override + public void Interfejs1Metoda() { + } + + @Override + public void Interfejs2Metoda() { + } + +} + +// Klasy abstrakcyjne + +// Składnia deklaracji klasy abstrakcyjnej +// <dostępność> abstract class <nawa klasy abstrakcyjnej> extends +// <superklasy, z których dziedziczy> { +// // Zmienne i stałe +// // Deklaracje metod +// } + +// Klasy abstrakcyjne nie mogą posiadać instancji. +// Klasy abstrakcyjne mogą definiować metody abstrakcyjne. +// Metody abstrakcyjne nie mają ciała funkcji i są oznaczone jako abstrakcyjne. +// Nieabstrakcyjne klasy-dzieci muszą przeciążać wszystkie abstrakcyjne metody +// superklasy. +// Klasy abstrakcyjne są użyteczne gdy wymagana jest powtarzalna logika działania, +// jednak należy zaauważyć, że jako, że wymagają dziedziczenia, łamią +// zasadę "Composition over inheritance". Rozważ inne podejścia używając +// kompozycji. https://en.wikipedia.org/wiki/Composition_over_inheritance + +public abstract class Zwierze +{ + private int wiek; + + public abstract void dajGlos(); + + // Metody mogą mieć ciało + public void jedz() + { + System.out.println("Jestem zwierzeciem i jem."); + // Uwaga: Możliwy jest dostęp do zmiennych prywatnych. + wiek = 30; + } + + public void wyswietlWiek() + { + System.out.println(wiek); + } + + // Klasy abstrakcyjne mogą mieć metodę główną. + public static void main(String[] args) + { + System.out.println("Jestem abstrakcyjna"); + } +} + +class Pies extends Zwierze +{ + // Musimy przeciążyć wszystkie abstrakcyjne metody z klasy abstrakcyjnej + @Override + public void dajGlos() + { + System.out.println("Hau"); + // wiek = 30; ==> BLAD! wiek jest typu private dla Zwierze + } + + // NOTE: Wystąpi błąd jeżeli użyto annotacji @Override jako, że Java + // nie pozwala na przeciążanie metod statycznych. + // Występuje tutaj METHOD HIDING - ukrywanie metod. + // Więcej w poście na SO: http://stackoverflow.com/questions/16313649/ + public static void main(String[] args) + { + Pies pluto = new Pies(); + pluto.dajGLos(); + pluto.jedz(); + pluto.wyswietlWiek(); + } +} + +// Klasy finalne + +// Składnia deklaracji klasy finalnej +// <dostępność> final <nazwa klasy finalnej> { +// // Zmienne i stałe +// // Deklaracje Metody +// } + +// Klasy finalne są klasami, które nie mogą być użyte do dziedziczenia, są więc +// z założenia ostatnim elementem dziedziczenia. W ten sposób są przeciwnością +// klas abstrakcyjnych, które z założenia muszą być dziedziczone. +public final class TygrysSzablozebny extends Zwierze +{ + // Nadal musimy przeciążyć metody abstrakcyjne klasy abstrakcyjnej Zwierze + @Override + public void dajGlos() + { + System.out.println("Roar"); + } +} + +// Metody finalne +public abstract class Ssak +{ + // Składnia metody finalnej: + // <dostępność> final <zwracany rodzaj> <nazwa funkcji>(<argumenty>) + + // Metody finalne, jak klasy finalne nie mogą być przeciążane + // i są w ten sposób ostatecznymi implementacjami danej metody. + public final boolean jestStalocieplny() + { + return true; + } +} + +// Enumeratory +// +// Enumerator jest specjalnym tyme danej, która pozwala zmiennej na bycie +// zestawem wcześniej zdefiniowanych stałych. Zmienna musi być równa jednej z +// wartości wcześniej zdefiniowanych. Jako, że są to stałe, nazwy pól typu enum +// są pisane wielkimi literami. W języku Java typ enum definiujemy przez użycie +// słowa enum. Na przykład aby zdefiniować dni tygodnia: +public enum Dzien { + PONIEDZIALEK, WTOREK, SRODA, CZWARTEK, + PIATEK, SOBOTA, NIEDZIELA +} + +// We can use our enum Day like that: +public class EnumTest { + // Zmienna typu enum + Dzien dzien; + + public EnumTest(Dzien dzien) { + this.dzien = dzien; + } + + public void opiszDzien() { + switch (dzien) { + case PONIEDZIALEK: + System.out.println("Nie lubię poniedziałku!"); + break; + case PIATEK: + System.out.println("Piątki są dużo lepsze."); + break; + case SOBOTA: + case NIEDZIELA: + System.out.println("Weekendy są najlepsze."); + break; + default: + System.out.println("Środek tygodnia jest taki sobie."); + break; + } + } + + public static void main(String[] args) { + EnumTest pierwszyDzien = new EnumTest(Dzien.PONIEDZIALEK); + pierwszyDzien.opiszDzien(); // => Nie lubię poniedziałku! + EnumTest trzeciDzien = new EnumTest(Dzien.SRODA); + trzeciDzien.opiszDzien(); // => Środek tygodnia jest taki sobie. + } +} + +// Typ enum jest bardziej wszechstronny niż powyższa demostracja. +// Ciało typu enum może zawierać metody i inne pola. +// Rzuć okiem na (angielski) https://docs.oracle.com/javase/tutorial/java/javaOO/enum.html + +// Wprowadzenie do wyrażeń lambda +// +// Nowe w Javie 8 są wyrażenia lambda. Lambdy znajdujemy zwykle w funkcyjnych +// językach programowania, co oznacza, że są metodami, które potrafią być +// stowrzone bez klasy i przekazywane jak gdyby były obiektem oraz wykonywane +// gdy zajdzie potrzeba. +// +// Ostatnia uwaga - lambdy muszą implementować funcjonalny interfejs. +// Interfels funkcjonalny to taki, który ma jedynie jedną zadeklarowaną metodę +// abstrakcyjną, ale może mieć dowolną ilość domyślnych metod. Wyrażenia lambda +// mogą być używane jako instancje tego interfejsu. Każdy inteferjs, który +// spełnia wymagania jest traktowany jako funkcjonalny. Więcej o interfejsach +// znajdziesz powyżej, w odpowiedniej sekcji. +// +import java.util.Map; +import java.util.HashMap; +import java.util.function.*; +import java.security.SecureRandom; + +public class Lambdas { + public static void main(String[] args) { + // Składnia deklaracji lambdy: + // <zero lub więcej parametrów> -> <ciało wyrażenia lub blok instrukcji> + + // Poniżej w przykładzie użyjemy tablicy z hashowaniem. + Map<String, String> planety = new HashMap<>(); + planety.put("Merkury", "87.969"); + planety.put("Wenus", "224.7"); + planety.put("Ziemia", "365.2564"); + planety.put("Mars", "687"); + planety.put("Jowisz", "4,332.59"); + planety.put("Saturn", "10,759"); + planety.put("Uran", "30,688.5"); + planety.put("Neptun", "60,182"); + + // Lambda z zerową liczbą parametrów używając funkcjonalnego interfejsu + // Supplier z java.util.function.Supplier. Faktyczną lambdą jest częśc + // po numPlanets =. + Supplier<String> numPlanety = () -> Integer.toString(planety.size()); + System.out.format("Liczba planet: %s\n\n", numPlanety.get()); + + // Lambda z jednym parametrem używająca funkcjonalnego interfejsu + // Consumer z java.util.function.Consumer.planety jest mapą, która + // wimplementuje Collection jak i Iterable. Użyty forEach pochodzi z + // Iterable i jest użyty w lambdzie na każdym elemencie kolekcji + // Domyślna implementacja forEach wygląda tak: + /* + for (T t : this) + action.accept(t); + */ + + // Faktyczna lambda jest parametrem przekazywanym do forEach. + planety.keySet().forEach((p) -> System.out.format("%s\n", p)); + + // Jeżeli przekazujemy tyklo pojedynczy argumentpowyższy zapis możemy + // przekształcić do (zauważ brak nawiasów dookoła p): + planety.keySet().forEach(p -> System.out.format("%s\n", p)); + + // Śledząc powyższe widzimy, że planety jest typu HashMap, a keySet() + // zwraca zestaw kluczy, forEach stosuje o każdego elementu lambdę: + // (parameter p) -> System.out.format("%s\n", p). Za każdym razem + // element jest uznawany jako "konsumowany" i wyrażenie (wyrażenia) + // w lambdzie są wykonywane. Pamiętaj, że ciało lambdy to część po + // symbolu ->. + + // Powyższy przykład bez użycia lambdy wyglądałby tradycyjnie tak: + for (String planeta : planety.keySet()) { + System.out.format("%s\n", planeta); + } + + // Poniższy przykład różni się od powyższego sposobem implementacji + // forEach: forEach użyty w klasie HashMap implementuje intefejs Map. + // Poniższy forEach przyjmuje BiConsumer, który ogólnie ujmując jest + // wymyślnym sposobem stwierdzenia, że zajmuje się zestawem par + // klucz-wartość Key -> Value dla każdego klucza. Ta domyślna + // implementacja działa jak: + /* + for (Map.Entry<K, V> entry : map.entrySet()) + action.accept(entry.getKey(), entry.getValue()); + */ + + // Faktyczna lambda jest parametrem przekazywanym do forEach. + String orbity = "%s okrąża Słońce w %s dni.\n"; + planety.forEach((K, V) -> System.out.format(orbity, K, V)); + + // Powyższe bez użycia lambdy wyglądałoby tradycyjnie tak: + for (String planet : planety.keySet()) { + System.out.format(orbity, planet, planety.get(planet)); + } + + // Lub jeżeli postępujemy zgodnie ze specyfikacją domyślnej implementacji: + for (Map.Entry<String, String> planeta : planety.entrySet()) { + System.out.format(orbity, planeta.getKey(), planeta.getValue()); + } + + // Podane przykłady pokrywają jedynie podstawowe zastosowanie wyrażeń + // lambda. Być może wydają się one niezbyt przydatne, jednak należy + // pamiętać, że lambdy można stworzyć jako obiekty, które nastepnie mogą + // zostać przekazane jako parametry do innych metod. + } +} +``` + +## Dalsze materiały + +Linki zamieszczone poniżej służą pomocą w zrozumieniu wybranego tematu, w razie braku rozwiązania wyszukanie w Google zwykle służy pomocą + +**Oficjalne poradniki Oracle po angielsku**: + +* [Tutorial w Javie od Sun / Oracle](https://docs.oracle.com/javase/tutorial/index.html) + +* [Modyfikacje poziomu dostępu w Java](https://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html) + +* [Koncepty programowania obiektowego](https://docs.oracle.com/javase/tutorial/java/concepts/index.html): + * [Dziedziczenie](https://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html) + * [Polimorfizm](https://docs.oracle.com/javase/tutorial/java/IandI/polymorphism.html) + * [Abstrakcja](https://docs.oracle.com/javase/tutorial/java/IandI/abstract.html) + +* [Wyjątki](https://docs.oracle.com/javase/tutorial/essential/exceptions/index.html) + +* [Interfejsy](https://docs.oracle.com/javase/tutorial/java/IandI/createinterface.html) + +* [Uogólnianie](https://docs.oracle.com/javase/tutorial/java/generics/index.html) + +* [Konwencja kodu Java](https://www.oracle.com/technetwork/java/codeconvtoc-136057.html) + +* Nowości z Java 8: + * [Funkcje Lambda (programowanie funkcyjne)](https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html) + * [Data y czas API (java.time package)](http://www.oracle.com/technetwork/articles/java/jf14-date-time-2125367.html) + +**Kursy po polsku** + +* [PJWSTK - Podstawy programowania w języku Java](http://edu.pjwstk.edu.pl/wyklady/ppj/scb/) + +* [PJWSTK - Programowanie obiektowe w języku Java](http://edu.pjwstk.edu.pl/wyklady/poj/scb/) + +**Tutoriale i ćwiczenia online po angielsku** + +* [Learneroo.com - Learn Java](http://www.learneroo.com) + +* [Codingbat.com](http://codingbat.com/java) + +* [Codewars - Java Katas](https://www.codewars.com/?language=java) + +**Książki po angielsku**: + +* [Head First Java](http://www.headfirstlabs.com/books/hfjava/) + +* [Thinking in Java](http://www.mindview.net/Books/TIJ/) + +* [Objects First with Java](https://www.amazon.com/Objects-First-Java-Practical-Introduction/dp/0132492660) + +* [Java The Complete Reference](https://www.amazon.com/gp/product/0071606300) diff --git a/pl-pl/python-pl.html.markdown b/pl-pl/python-pl.html.markdown index 023c3e6b..222f753f 100644 --- a/pl-pl/python-pl.html.markdown +++ b/pl-pl/python-pl.html.markdown @@ -532,7 +532,7 @@ Czlowiek.grunt() # => "*grunt*" # Tak importuje się moduły: import math -print(math.sqrt(16)) # => 4 +print(math.sqrt(16)) # => 4.0 # Można podać konkretne funkcje, np. ceil, floor z modułu math from math import ceil, floor diff --git a/powershell.html.markdown b/powershell.html.markdown index f9c20607..db29bf96 100644 --- a/powershell.html.markdown +++ b/powershell.html.markdown @@ -245,7 +245,7 @@ function New-Website() { 'string' | gm # Syntax for calling static .NET methods -\[System.Reflection.Assembly]::LoadWithPartialName('Microsoft.VisualBasic') +[System.Reflection.Assembly]::LoadWithPartialName('Microsoft.VisualBasic') # Note that .NET functions MUST be called with parentheses # while PS functions CANNOT be called with parentheses. diff --git a/prolog.html.markdown b/prolog.html.markdown index f7b55ac6..d4c28cba 100644 --- a/prolog.html.markdown +++ b/prolog.html.markdown @@ -75,7 +75,7 @@ magicNumber(42). ?- 2 = 3. % False - equality test ?- X = 3. % X = 3 - assignment ?- X = 2, X = Y. % X = Y = 2 - two assignments - % Note Y is assigned to, even though it is + % Note Y is assigned too, even though it is % on the right hand side, because it is free ?- X = 3, X = 2. % False % First acts as assignment and binds X=3 diff --git a/pt-br/asymptotic-notation-pt.html.markdown b/pt-br/asymptotic-notation-pt.html.markdown index 2f179f96..b70d26b7 100644 --- a/pt-br/asymptotic-notation-pt.html.markdown +++ b/pt-br/asymptotic-notation-pt.html.markdown @@ -13,7 +13,7 @@ lang: pt-br ## O que é? Notação Assintótica é uma linguagem que nos permite analisar o tempo de execução - de um algoritmo através da indentificação de seu comportamento com o + de um algoritmo através da identificação de seu comportamento com o crescimento da entrada oferecida. Isso também é conhecido como taxa de crescimento do algoritmo. O algoritmo de repente torna-se lento quando o tamanho da entrada cresce? O algoritmo mantém, em geral, seu tempo de execução @@ -33,12 +33,12 @@ Um modo seria contar o número de operações primitivas com diferentes tamanhos ## Tipos de Notação Assintótica -Na primeira seção desse documento, descrevemos como Notação Assintótica identifica o comportamento de um algoritmo +Na primeira seção deste documento, descrevemos como Notação Assintótica identifica o comportamento de um algoritmo a medida que o tamanho da entrada cresce. Imaginemos um algoritmo como uma função *f*, *n* como o tamanho da entrada e *f(n)* sendo o tempo de execução. Então, para dado algoritmo *f*, com entrada de tamanho *n*, você terá tempo de execução - *f(n)*. Isto resulta em um gráfico onde a coordernada Y é o tempo de execução -, a coordernada X representa o tamanho da entrada e os pontos representam o tempo + *f(n)*. Isto resulta em um gráfico onde a coordenada Y é o tempo de execução, + a coordenada X representa o tamanho da entrada e os pontos representam o tempo de execução para dado tamanho de entrada. Você pode representar a função, ou o algoritmo, com Notação Assintótica de várias @@ -49,7 +49,7 @@ não avalia o melhor caso, porque essas condições não são atingidas com freq Um bom exemplo disto seria em algoritmos de ordenação; especificamente, na adição de elementos à árvores. O melhor caso na maioria de algoritmos pode ser de apenas uma operação. Entretanto, na maioria dos casos, o elemento a ser adicionado terá -que percorrer a árvore de forma apropriada, o que pode causar a analise de um +que percorrer a árvore de forma apropriada, o que pode causar a análise de um ramo inteiro. Este é o pior caso, e isto é o que você está se preparando. @@ -63,16 +63,16 @@ Função Polinomial - an^z + . . . + an^2 + a*n^1 + a*n^0, onde *z* é uma const Função Exponencial - a^n, onde a é alguma constante ``` Estas são as funções básicas de crescimento usadas em várias notações. A lista - começa com a de crescimento mais lento (logarítima, a de execução mais rápida) + começa com a de crescimento mais lento (logarítmica, a de execução mais rápida) e segue para a de crescimento mais rápido (exponencial, de execução mais lenta). -Repare que enquando *n*, a entrada, cresce, cada uma dessas funções cresce mais -rápido que quadrático, polinimial e exponencial, comparadas com logaritma e linear. +Repare que enquanto *n*, a entrada, cresce, cada uma dessas funções cresce mais +rápido que quadrático, polinomial e exponencial, comparadas com logarítmica e linear. Uma nota extremamente importante para notações é tentar usar os termos mais simples. Isto significa descartar constantes e termos de ordem mais baixa, pois quando o tamanho da entrada cresce para o infinito (limites matemáticos), os termos de ordem mais baixa e constantes tornam-se irrelevantes. Por exemplo, se você tiver uma -constante muito grande, 2^9001, a simplificação não afeterá sua notação. +constante muito grande, 2^9001, a simplificação não afetará sua notação. Já que queremos as formas mais simples, mudemos nossa tabela um pouco... @@ -87,7 +87,7 @@ Função Exponencial - a^n, onde *a* é uma constante ### Big-O Big-O, também escrita como O, é uma Notação Assintótica para o pior caso. Digamos -*f(n)* seja o tempo de exeução de um algoritmo e *g(n)) um tempo de complexidade +*f(n)* seja o tempo de execução de um algoritmo e *g(n)) um tempo de complexidade arbitrário que você quer relacionar com seu algoritmo. *f(n)* é O(g(n)), se, para quando constante real c (c > 0), *f(n)* <= *c g(n)* para todo tamanho de entrada n (n > 0). @@ -116,7 +116,7 @@ Há alguma constante c que satisfaça a definição para todo n? 3log n + 100 <= 150 * log n, n > 2 (Indefinido em n = 1) ``` -Sim! A definição de Big-I for atentida, portante `f(n)` é `O(g(n))`. +Sim! A definição de Big-O foi atendida, portanto `f(n)` é `O(g(n))`. *Exemplo 2* @@ -146,7 +146,7 @@ Big-Omega, também escrita como Ω, é uma Notação Assintótica para o melhor Sinta-se livre para adicionar mais exemplos. Big-O é a notação primária usada para medir complexidade de algoritmos. ### Notas Finais -É difícil manter esse tipo de tópico curto e você deveria ler os livros e artigos listados abaixo. Eles cobrem muito mais profundamente definições e exemplos. Mais x='Algoritms & Data Structures' virá; teremos um documento sobre analisar código em breve. +É difícil manter esse tipo de tópico curto e você deveria ler os livros e artigos listados abaixo. Eles cobrem muito mais profundamente definições e exemplos. Mais x='Algorithms & Data Structures' virá; teremos um documento sobre analisar código em breve. ## Livros diff --git a/pt-br/awk-pt.html.markdown b/pt-br/awk-pt.html.markdown index 761f5294..9bf770fd 100644 --- a/pt-br/awk-pt.html.markdown +++ b/pt-br/awk-pt.html.markdown @@ -1,5 +1,6 @@ --- -language: awk +category: tool +tool: awk filename: learnawk-pt.awk contributors: - ["Marshall Mason", "http://github.com/marshallmason"] diff --git a/pt-br/clojure-pt.html.markdown b/pt-br/clojure-pt.html.markdown index 7e8b3f7b..b88d4eec 100644 --- a/pt-br/clojure-pt.html.markdown +++ b/pt-br/clojure-pt.html.markdown @@ -340,7 +340,7 @@ keymap ; => {:a 1, :b 2, :c 3} (def my-atom (atom {})) ; Atualize o atom com um swap!. -; swap! pega uma funçnao and chama ela com o valor atual do atom +; swap! pega uma função e chama ela com o valor atual do atom ; como primeiro argumento, e qualquer argumento restante como o segundo (swap! my-atom assoc :a 1) ; Coloca o valor do átomo my-atom como o resultado de (assoc {} :a 1) (swap! my-atom assoc :b 2) ; Coloca o valor do átomo my-atom como o resultado de (assoc {:a 1} :b 2) diff --git a/pt-br/cmake-pt.html.markdown b/pt-br/cmake-pt.html.markdown index 8d4c3fda..d11fe4f4 100644 --- a/pt-br/cmake-pt.html.markdown +++ b/pt-br/cmake-pt.html.markdown @@ -1,5 +1,6 @@ --- -language: cmake +category: tool +tool: cmake contributors: - ["Bruno Alano", "https://github.com/brunoalano"] filename: CMake-br diff --git a/pt-br/coffeescript-pt.html.markdown b/pt-br/coffeescript-pt.html.markdown index 8b1094b1..7129a463 100644 --- a/pt-br/coffeescript-pt.html.markdown +++ b/pt-br/coffeescript-pt.html.markdown @@ -3,19 +3,20 @@ language: coffeescript contributors: - ["Tenor Biel", "http://github.com/L8D"] - ["Xavier Yao", "http://github.com/xavieryao"] + - ["Claudio Busatto", "http://github.com/cjcbusatto"] translators: - ["Miguel Araújo", "https://github.com/miguelarauj1o"] lang: pt-br filename: learncoffeescript-pt.coffee --- -CoffeeScript é uma pequena linguagem que compila um-para-um para o JavaScript -equivalente, e não há interpretação em tempo de execução. Como um dos sucessores -de JavaScript, CoffeeScript tenta o seu melhor para exibir uma saída legível, -bem-impressa e bom funcionamento dos códigos JavaScript em todo o tempo de +CoffeeScript é uma pequena linguagem que compila um-para-um para o JavaScript +equivalente, e não há interpretação em tempo de execução. Como um dos sucessores +de JavaScript, CoffeeScript tenta o seu melhor para exibir uma saída legível, +bem-impressa e bom funcionamento dos códigos JavaScript em todo o tempo de execução JavaScript. -Veja também [site do CoffeeScript](http://coffeescript.org/), que tem um tutorial +Veja também [site do CoffeeScript](http://coffeescript.org/), que tem um tutorial completo sobre CoffeeScript. ``` coffeescript @@ -23,35 +24,35 @@ completo sobre CoffeeScript. #Segue as tendências de muitas linguagens modernas #Assim, os comentários são iguais a Ruby e Python, eles usam símbolos numéricos. -### -Os comentários em bloco são como estes, e eles traduzem diretamente para '/ *'s e +### +Os comentários em bloco são como estes, e eles traduzem diretamente para '/ *'s e '* /'s para o código JavaScript que resulta... -Você deveria entender mais de semântica de JavaScript antes de continuar... +Você deveria entender mais de semântica de JavaScript antes de continuar... ### -# Tarefa: -numero = 42 #=> número var = 42; +# Tarefa: +numero = 42 #=> var numero = 42; oposto = true #=> var oposto = true; -# Condições: -numero = -42 if oposto #=> if (oposto) {número = -42;} +# Condições: +numero = -42 if oposto #=> if (oposto) {numero = -42;} -# Funções: +# Funções: quadrado = (x) -> x * x #=> var quadrado = function (x) {return x * x;} -preencher = (recipiente, líquido = "coffee") -> - "Preenchendo o #{recipiente} with #{líquido}..." +preencher = (recipiente, liquido = "coffee") -> + "Preenchendo o #{recipiente} with #{liquido}..." #=>var preencher; # -#preencher = function(recipiente, líquido) { -# if (líquido == null) { -# líquido = "coffee"; +#preencher = function(recipiente, liquido) { +# if (liquido == null) { +# liquido = "coffee"; # } -# return "Preenchendo o " + recipiente + " with " + líquido + "..."; +# return "Preenchendo o " + recipiente + " with " + liquido + "..."; #}; -# Alcances: +# Alcances: list = [1 .. 5] #=> lista var = [1, 2, 3, 4, 5]; # Objetos: @@ -79,7 +80,7 @@ alert "Eu sabia!" if elvis? #=> if(typeof elvis !== "undefined" && elvis !== null) { alert("Eu sabia!"); } # Compressão de Matrizes: -cubes = (math.cube num for num in list) +cubes = (math.cube num for num in list) #=>cubes = (function() { # var _i, _len, _results; # _results = []; @@ -99,8 +100,9 @@ eat alimento for alimento in comidas when alimento isnt 'chocolate' # if (alimento !== 'chocolate') { # eat(alimento); # } +``` ## Recursos adicionais - [Smooth CoffeeScript](http://autotelicum.github.io/Smooth-CoffeeScript/) -- [CoffeeScript Ristretto](https://leanpub.com/coffeescript-ristretto/read)
\ No newline at end of file +- [CoffeeScript Ristretto](https://leanpub.com/coffeescript-ristretto/read) diff --git a/pt-br/make-pt.html.markdown b/pt-br/make-pt.html.markdown index 8e7603cc..cbdebde7 100644 --- a/pt-br/make-pt.html.markdown +++ b/pt-br/make-pt.html.markdown @@ -1,5 +1,6 @@ ---
-language: make
+category: tool
+tool: make
contributors:
- ["Robert Steed", "https://github.com/robochat"]
- ["Stephan Fuhrmann", "https://github.com/sfuhrm"]
diff --git a/pt-br/pascal-pt.html.markdown b/pt-br/pascal-pt.html.markdown new file mode 100644 index 00000000..3a37271a --- /dev/null +++ b/pt-br/pascal-pt.html.markdown @@ -0,0 +1,253 @@ +--- +language: Pascal +filename: learnpascal-pt.pas +contributors: + - ["Ganesha Danu", "https://github.com/blinfoldking"] + - ["Keith Miyake", "https//github.com/kaymmm"] +translators: + - ["Raul Almeida", "https://github.com/almeidaraul"] +lang: pt-br +--- + + +>Pascal é uma linguagem de programação estruturada, que recebeu este nome em homenagem ao matemático e físico Blaise Pascal. Foi criada em 1970 pelo suíço Niklaus Wirth,tendo em mente encorajar o uso de código estruturado. +fonte : [wikipédia](https://pt.wikipedia.org/wiki/Pascal_(linguagem_de_programa%C3%A7%C3%A3o)) + + + +Para compilar e executar um programa em Pascal, você pode usar o freepascal, +um compilador gratuito. [Faça o download aqui](https://www.freepascal.org/) + +```pascal +//Corpo de um programa em Pascal +//isso é um comentário +{ + isso também é um comentário, + mas com várias linhas +} + +//cabeçalho do programa +PROGRAM aprendendo_pascal; //<-- não esqueça o ponto e vírgula. O nome do +programa deve começar com uma letra. + +CONST + { + aqui você declara valores constantes + } +TYPE + { + aqui você declara tipos não nativos + } +VAR + { + aqui você declara variáveis + } + +//programa de fato +BEGIN + 80 + aqui ficam todas as instruções que não pertencem nem a funções + nem a procedimentos + + blocos de código começam com BEGIN e terminam com END + (como as chaves em C) + } +END. //o "end" no final do programa requer um ponto final. +``` + +```pascal +//formas de declarar uma variável +VAR a:INTEGER; +VAR b:INTEGER; + +VAR + a : INTEGER; + b : INTEGER; + +VAR a,b : INTEGER; +``` + +```pascal +PROGRAM Learn_More; +//agora, mais sobre tipos de dados e operações + +CONST + PI = 3.141592654; + GNU = 'GNU''s Not Unix'; + { a convenção é usar caixa alta para constantes + + constantes têm valores fixos que só podem ser alterados + antes da compilação + + constantes podem ser de qualquer tipo nativo (integer, real, boolean, + char, string) + +TYPE + vet_char : array [0..255] of CHAR; + // isso declara um novo tipo de variável, vet_char, com 256 caracteres + vet_multd : array of array of INTEGER; + // vetores de vetores são vetores multidimensionais + // use vetores de tamanho 0 (daí, usa-se alocação dinâmica) + // vetores do tipo vet_multd são de duas dimensões + +//declarando variáveis +VAR + int, c, d : INTEGER; + // três variáveis que guardam valores inteiros + // inteiros têm 16 bits (vão de -32768 a 32767) + r : REAL; + // uma variável que guarda um valor real + // reais vão de 3.4E-38 a 3.4E38 + bool : BOOLEAN; + // uma variável que guarda um valor booleano (verdadeiro ou falso) + ch : CHAR; + // uma variável que guarda um caractere + // caracteres têm 8 bits + str : STRING; + // STRING não é um tipo padrão, mas vem na maioria dos compiladores + // string é um vetor de caracteres com tamanho padrão de 255 elementos + s : STRING[50]; + // especificar o tamanho de uma string assim otimiza o uso de memória + my_str: vet_char; + // aqui, uma variável de um tipo personalizado declarado acima + my_2d : vet_multd; + // defina o tamanho de vetores dinâmicos antes de usá-los + +// outros tipos de dados (pascal é uma linguagem fortemente tipada) + + // tipos adicionais de inteiros + b : BYTE; // faixa [0..255] + shi : SHORTINT; // faixa [-128..127] + smi : SMALLINT; // faixa [-32,768..32,767] (inteiro padrão) + w : WORD; // faixa [0..65,535] + li : LONGINT; // faixa [-2,147,483,648..2,147,483,647] + lw : LONGWORD; // faixa [0..4,294,967,295] + c : CARDINAL; // longword + i64 : INT64; // faixa [-9223372036854775808..9223372036854775807] + qw : QWORD; // faixa [0..18,446,744,073,709,551,615] + + // tipos adicionais de reais + rr : REAL; // faixa depende da plataforma (8 bits, 16 bits, etc) + rs : SINGLE; // faixa [1.5E-45..3.4E38] + rd : DOUBLE; // faixa [5.0E-324 .. 1.7E308] + re : EXTENDED; // faixa [1.9E-4932..1.1E4932] + rc : COMP; // faixa [-2E64+1 .. 2E63-1] + +BEGIN + int := 1;// usa-se := para atribuir valores a variáveis + r := 3.14; + ch := 'a'; + str := 'apple'; + bool := true; + //pascal não é case-sensitive (não diferencia maiúsculas de minúsculas) + // uma opção de organização é usar maiúsculas para termos da linguagem + // (BEGIN, END, INTEGER, etc) e constantes + // aritmética + int := 1 + 1; // int deixa de ser 1 e passa a ser 2 + int := int + 1; // int = 2 + 1 = 3; + int := 4 DIV 2; //int = 2 (DIV é uma divisão inteira - ignora o resto) + int := 3 DIV 2; //int = 1 + int := 1 DIV 2; //int = 0 + + bool := true OR false; // bool = true + bool := false AND true; // bool = false + bool := true XOR true; // bool = false + + r := 3 / 2; // usa-se a "/" para divisões entre inteiros + r := int; // um real pode receber um valor inteiro (mas não o contrário) + + c := str[1]; //acessando elementos de um vetor: vetor[índice do elemento] + str := 'hello' + 'world'; //concatenção de strings + + my_str[0] := 'a'; { só se pode atribuir valores a vetores elemento + por elemento (não o vetor inteiro de uma vez) } + + // LAÇOS + WHILE (ch != 'a') DO + BEGIN + writeln('ch é diferente de a'); + IF (ch = 'c') THEN + writeln('ch é igual a c'); + END; + + SETLENGTH(my_2d,10,10); + // inicialização de um vetor com alocação dinâmica; my_2d vira um 10x10 + FOR c := 0 to 9 DO + { vetores começam em 0 e terminam em tamanho-1 + (exceto se, declarando o tipo, forem especificados valores diferentes) } + FOR d := 0 to 9 DO + // a variável usada em um laço FOR deve ter sido declarada no cabeçalho + my_2d[c,d] := c * d; + // acessam-se elementos de vetores multidimensionais com [d1, d2, d3...] + + +END. +``` + +```pascal +PROGRAM programacao_com_funcoes; + +VAR + i, inutil : INTEGER; + +{ OBS: diferença entre procedimento e função + função: realiza operações e retorna valor + procedimento: só realiza operações +} +//declarando e descrevendo uma função +FUNCTION fatorial_recursiva(CONST a: INTEGER) : INTEGER; +{ calcula a! recursivamente } + +// pode-se declarar variáveis locais para funções e procedimentos +// exemplo: +// VAR +// local_a : INTEGER; + +BEGIN + { O bloco ELSE só funciona se não houver ponto e vírgula no bloco do IF + exemplo: + IF a THEN + writeln('a'); + ELSE + writeln('b'); + Isso não permitiria que o programa compilasse } + + IF a >= 1 THEN + // o valor de retorno é atribuído como se a função fosse uma variável + fatorial_recursiva := a * fatorial_recursiva(a-1) + ELSE + fatorial_recursiva := 1; +END; // o END de funções e procedimentos recebe ponto e vírgula + +//declarando e descrevendo um procedimento +PROCEDURE salvainteiro(VAR i : INTEGER; inutil : INTEGER); +{ recebe entrada do usuário e salva na variável i + passagem de valor: + + POR REFERÊNCIA - "VAR i: integer"; implica que alterações na variável i + dentro da função são guardadas para o escopo de todo o programa + + POR VALOR - "inutil: integer"; implica que o valor do argumento é copiado + e alterações na variável inutil não são guardadas +} + +BEGIN + WRITE('Insira um inteiro: '); //escreve sem quebrar linha + READLN(i); //lê i com quebra de linha + inutil := 4; // inutil não terá seu valor alterado fora do procedimento. +END; + +BEGIN // programa principal + inutil := 3; + salvainteiro(i, inutil); + + // escrevendo i! + WRITELN(i, '! = ', factorial_recursion(i)); // escreve e quebra linha + // valores numéricos são automaticamente convertidos para texto na escrita + + // escrever valor de inutil (sempre 3, já que salvainteiro não a altera) + WRITELN('inutil = ', inutil); +END. + +``` + diff --git a/pt-br/python-pt.html.markdown b/pt-br/python-pt.html.markdown index 5afd46d0..82b70117 100644 --- a/pt-br/python-pt.html.markdown +++ b/pt-br/python-pt.html.markdown @@ -464,7 +464,7 @@ Humano.ronca() #=> "*arrrrrrr*" # Você pode importar módulos import math -print math.sqrt(16) #=> 4 +print math.sqrt(16) #=> 4.0 # Você pode importar funções específicas de um módulo from math import ceil, floor diff --git a/pt-br/python3-pt.html.markdown b/pt-br/python3-pt.html.markdown index ea0617f4..b72c732a 100644 --- a/pt-br/python3-pt.html.markdown +++ b/pt-br/python3-pt.html.markdown @@ -647,7 +647,7 @@ Human.grunt() # => "*grunt*" # Você pode importar módulos import math -print(math.sqrt(16)) # => 4 +print(math.sqrt(16)) # => 4.0 # Você pode importar apenas funções específicas de um módulo from math import ceil, floor diff --git a/pt-br/stylus-pt.html.markdown b/pt-br/stylus-pt.html.markdown new file mode 100755 index 00000000..804fa806 --- /dev/null +++ b/pt-br/stylus-pt.html.markdown @@ -0,0 +1,228 @@ +--- +language: stylus +filename: learnStylus-pt.styl +contributors: + - ["Salomão Neto", "https://github.com/salomaosnff"] + - ["Isaac Henrique", "https://github.com/Isaachi1"] +lang: pt-br +--- + +Stylus tem como propósito, adicionar funcionalidades às suas folhas de estilos CSS que te ajudam no desenvolvimento, sem que haja a quebra de compartibilidade entre os navegadores Web. +Entre elas estão variáveis, aninhamento, mixins, funções e muito mais. + +A sintaxe do Stylus é muito flexivel podendo utilizar a sintaxe padrão do CSS e deixando opcional o ponto e vírgula (;), dois pontos (:) e até mesmo as chaves ({ e }), tornando assim o seu código ainda mais legível. + +Stylus não fornece novas opções de estilos, mas dá funcionalidades que permitem deixar seu CSS muito mais dinâmico. + + +```scss + +/* Estilo de código +==============================*/ + +/* As chaves, ponto e vírgula, e dois pontos são opcionais no Stylus. */ + +body { + background: #000; +} + +body { + background: #000 +} + +body { + background #000 +} + +body + background #000 + +body + background: #000; + +body + background: #000 + + +// Comentários de linha única são removidos quando Stylus é compilado para CSS. + +/* Comentários multi-line são preservados. */ + + +/* Seletores +==============================*/ + +/* Selecionando elementos dentro de outro elemento */ +body { + background: #000000; + h1 { + color: #FF0000; + } +} + +/* Ou se preferir... */ +body + background #000000 + h1 + color #FF0000 + + +/* Obtendo a referência do elemento pai +==============================*/ +a { + color: #0088dd; + &:hover { + color: #DD8800; + } +} + + +/*Variáveis +==============================*/ + + +/* + É possível armazenar um valor CSS (tais como a cor) de uma variável. + Embora seja opcional, é recomendado adicionar $ antes de um nome de variável + para que você possa distinguir uma variável de outro valor CSS. +*/ + +$primary-color = #A3A4FF +$secondary-color = #51527F +$body-font = 'Roboto', sans-serif + +/* Você pode usar as variáveis em toda a sua folha de estilo. +Agora, se você quer mudar a cor, você só tem que fazer a mudança uma vez. */ + +body + background-color $primary-color + color $secondary-color + font-family $body-font + +/* Quando compilar ficaria assim: */ +body { + background-color: #A3A4FF; + color: #51527F; + font-family: 'Roboto', sans-serif; +} + +/ * +Este é muito mais fácil de manter do que ter de mudar a cor +cada vez que aparece em toda a sua folha de estilo. +* / + + + +/*Mixins +==============================*/ + +/* Se você achar que você está escrevendo o mesmo código para mais de um +elemento, você pode querer armazenar esse código em um mixin. + +center() + display block + margin-left auto + margin-right auto + left 0 + right 0 + +/* Utilizando um mixin */ +body { + center() + background-color: $primary-color +} + +/* Apoś compilar ficaria assim: */ +div { + display: block; + margin-left: auto; + margin-right: auto; + left: 0; + right: 0; + background-color: #A3A4FF; +} + +/* Você pode usar mixins para criar uma propriedade estenográfica. */ + +size($width, $height) + width $width + height $height + +.rectangle + size(100px, 60px) + +.square + size(40px, 40px) + +/* Você pode usar um mixin como uma propriedade CSS. */ +circle($ratio) + width $ratio * 2 + height $ratio * 2 + border-radius $ratio + +.ball + circle 25px + + +/* Interpolação +==============================*/ + +vendor(prop, args) + -webkit-{prop} args + -moz-{prop} args + {prop} args + +border-radius() + vendor('border-radius', arguments) + +box-shadow() + vendor('box-shadow', arguments) + +button + border-radius 1px 2px / 3px 4px + +/* Funções +==============================*/ + +/* Funções no Stylus permitem fazer uma variedade de tarefas, como por exemplo, menipular algum dado. */ + +body { + background darken(#0088DD, 50%) // Escurece a cor #0088DD em 50% +} + +/** Criando sua própria função */ +somar(a, b) + a + b + +body + padding somar(10px, 5) + +/* Condições +==============================*/ +comparar(a, b) + if a > b + maior + else if a < b + menor + else + igual + +comparar(5, 2) // => maior +comparar(1, 5) // => menor +comparar(10, 10) // => igual + +/* Iterações +==============================*/ + +/** +Sintaxe de laço de repetição for: +for <val-name> [, <key-name>] in <expression> +**/ + +for $item in (1..2) /* Repete o bloco 12 vezes */ + .col-{$item} + width ($item / 12) * 100% /* Calcula a largula pelo número da coluna* + +``` + +Agora que você conhece um pouco sobre esse poderoso pré-processador de CSS, você está pronto para criar folhas de estilos mais dinâmicas. Para aprofundar seus conhecimentos visite a documentação oficial do stylus em http://stylus-lang.com. diff --git a/python.html.markdown b/python.html.markdown index df1ca6f2..0cc33a80 100644 --- a/python.html.markdown +++ b/python.html.markdown @@ -328,7 +328,8 @@ filled_dict["four"] = 4 # now, filled_dict["four"] => 4 filled_dict.setdefault("five", 5) # filled_dict["five"] is set to 5 filled_dict.setdefault("five", 6) # filled_dict["five"] is still 5 -# Sets store ... well sets (which are like lists but can contain no duplicates) +# You can declare sets (which are like unordered lists that cannot contain +# duplicate values) using the set object. empty_set = set() # Initialize a "set()" with a bunch of values some_set = set([1, 2, 2, 3, 4]) # some_set is now set([1, 2, 3, 4]) @@ -661,7 +662,7 @@ i.age # => raises an AttributeError # You can import modules import math -print math.sqrt(16) # => 4 +print math.sqrt(16) # => 4.0 # You can get specific functions from a module from math import ceil, floor diff --git a/python3.html.markdown b/python3.html.markdown index 4d5bb3ae..ecdbd932 100644 --- a/python3.html.markdown +++ b/python3.html.markdown @@ -41,10 +41,10 @@ Note: This article applies to Python 3 specifically. Check out [here](http://lea 10 * 2 # => 20 35 / 5 # => 7.0 -# Result of integer division truncated down both for positive and negative. +# Integer division rounds down for both positive and negative numbers. 5 // 3 # => 1 -5.0 // 3.0 # => 1.0 # works on floats too -5 // 3 # => -2 +5.0 // 3.0 # => 1.0 # works on floats too -5.0 // 3.0 # => -2.0 # The result of division is always a float @@ -155,7 +155,7 @@ len("This is a string") # => 16 name = "Reiko" f"She said her name is {name}." # => "She said her name is Reiko" # You can basically put any Python statement inside the braces and it will be output in the string. -f"{name} is {len(name)} characters long." +f"{name} is {len(name)} characters long." # => "Reiko is 5 characters long." # None is an object @@ -314,16 +314,19 @@ valid_dict = {(1,2,3):[1,2,3]} # Values can be of any type, however. filled_dict["one"] # => 1 # Get all keys as an iterable with "keys()". We need to wrap the call in list() -# to turn it into a list. We'll talk about those later. Note - Dictionary key -# ordering is not guaranteed. Your results might not match this exactly. -list(filled_dict.keys()) # => ["three", "two", "one"] +# to turn it into a list. We'll talk about those later. Note - for Python +# versions <3.7, dictionary key ordering is not guaranteed. Your results might +# not match the example below exactly. However, as of Python 3.7, dictionary +# items maintain the order at which they are inserted into the dictionary. +list(filled_dict.keys()) # => ["three", "two", "one"] in Python <3.7 +list(filled_dict.keys()) # => ["one", "two", "three"] in Python 3.7+ # Get all values as an iterable with "values()". Once again we need to wrap it # in list() to get it out of the iterable. Note - Same as above regarding key # ordering. -list(filled_dict.values()) # => [3, 2, 1] - +list(filled_dict.values()) # => [3, 2, 1] in Python <3.7 +list(filled_dict.values()) # => [1, 2, 3] in Python 3.7+ # Check for existence of keys in a dictionary with "in" "one" in filled_dict # => True @@ -805,6 +808,7 @@ class Superhero(Human): # add additional class attributes: self.fictional = True self.movie = movie + # be aware of mutable default values, since defaults are shared self.superpowers = superpowers # The "super" function lets you access the parent class's methods diff --git a/r.html.markdown b/r.html.markdown index a8b04be2..3e855602 100644 --- a/r.html.markdown +++ b/r.html.markdown @@ -664,7 +664,7 @@ require(plyr) # "pets.csv" is a file on the internet # (but it could just as easily be a file on your own computer) require(RCurl) -pets <- read.csv(textConnection(getURL("http://learnxinyminutes.com/docs/pets.csv"))) +pets <- read.csv(textConnection(getURL("https://learnxinyminutes.com/docs/pets.csv"))) pets head(pets, 2) # first two rows tail(pets, 1) # last row diff --git a/racket.html.markdown b/racket.html.markdown index c6b1deba..60a895e0 100644 --- a/racket.html.markdown +++ b/racket.html.markdown @@ -249,7 +249,7 @@ m ; => '#hash((b . 2) (a . 1) (c . 3)) <-- no `d' (hash-remove m 'a) ; => '#hash((b . 2) (c . 3)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; 3. Functions +;; 4. Functions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Use `lambda' to create functions. @@ -319,7 +319,7 @@ m ; => '#hash((b . 2) (a . 1) (c . 3)) <-- no `d' ; => "Hi Finn, 6 extra args" ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; 4. Equality +;; 5. Equality ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; for numbers use `=' @@ -369,7 +369,7 @@ m ; => '#hash((b . 2) (a . 1) (c . 3)) <-- no `d' (equal? (list 3) (list 3)) ; => #t ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; 5. Control Flow +;; 6. Control Flow ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Conditionals @@ -505,7 +505,7 @@ m ; => '#hash((b . 2) (a . 1) (c . 3)) <-- no `d' (+ 1 (raise 2))) ; => 2 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; 6. Mutation +;; 7. Mutation ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Use `set!' to assign a new value to an existing variable @@ -541,7 +541,7 @@ vec ; => #(1 2 3 4) (hash-remove! m3 'a) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; 7. Modules +;; 8. Modules ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Modules let you organize code into multiple files and reusable @@ -568,7 +568,7 @@ vec ; => #(1 2 3 4) ; (show "~a" 1 #\A) ; => error, `show' was not exported ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; 8. Classes and Objects +;; 9. Classes and Objects ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Create a class fish% (-% is idiomatic for class bindings) @@ -609,7 +609,7 @@ vec ; => #(1 2 3 4) (send (new (add-color fish%) [size 10] [color 'red]) get-color) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; 9. Macros +;; 10. Macros ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Macros let you extend the syntax of the language @@ -651,7 +651,7 @@ vec ; => #(1 2 3 4) ;; it, the compiler will get in an infinite loop ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; 10. Contracts +;; 11. Contracts ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Contracts impose constraints on values exported from modules @@ -678,7 +678,7 @@ vec ; => #(1 2 3 4) ;; more details.... ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; 11. Input & output +;; 12. Input & output ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Racket has this concept of "port", which is very similar to file diff --git a/ro-ro/python-ro.html.markdown b/ro-ro/python-ro.html.markdown index c96e30dc..ada0c034 100644 --- a/ro-ro/python-ro.html.markdown +++ b/ro-ro/python-ro.html.markdown @@ -449,7 +449,7 @@ Om.exclama() #=> "*Aaaaaah*" # Pentru a folosi un modul, trebuie importat import math -print math.sqrt(16) #=> 4 +print math.sqrt(16) #=> 4.0 # Putem importa doar anumite funcţii dintr-un modul from math import ceil, floor diff --git a/rst.html.markdown b/rst.html.markdown index 01595fe4..2423622e 100644 --- a/rst.html.markdown +++ b/rst.html.markdown @@ -47,19 +47,27 @@ Title are underlined with equals signs too Subtitles with dashes --------------------- -You can put text in *italic* or in **bold**, you can "mark" text as code with double backquote ``print()``. +You can put text in *italic* or in **bold**, you can "mark" text as code with double backquote ``print()``. -Lists are as simple as in Markdown: +Lists are similar to Markdown, but a little more involved. + +Remember to line up list symbols (like - or *) with the left edge of the previous text block, and remember to use blank lines to separate new lists from parent lists: - First item - Second item - - Sub item + + - Sub item + +- Third item or * First item * Second item - * Sub item + + * Sub item + +* Third item Tables are really easy to write: diff --git a/ru-ru/asymptotic-notation-ru.html.markdown b/ru-ru/asymptotic-notation-ru.html.markdown index 73ad80ba..7fd02c47 100644 --- a/ru-ru/asymptotic-notation-ru.html.markdown +++ b/ru-ru/asymptotic-notation-ru.html.markdown @@ -1,225 +1,225 @@ ---- -category: Algorithms & Data Structures -name: Asymptotic Notation -contributors: - - ["Jake Prather", "http://github.com/JakeHP"] - - ["Divay Prakash", "http://github.com/divayprakash"] -translators: - - ["pru-mike", "http://gihub.com/pru-mike"] -lang: ru-ru ---- - -# О-cимволика - -## Что это такое? - -О-cимволика или асимптотическая запись это система символов позволяющая оценить -время выполнения алгоритма, устанавливая зависимость времени выполнения от -увеличения объема входных данных, так же известна как оценка -сложности алгоритмов. Быстро-ли алгоритм станет невероятно медленным, когда -объем входных данных увеличится? Будет-ли алгоритм выполняться достаточно быстро, -если объем входных данных возрастет? О-символика позволяет ответить на эти -вопросы. - -## Можно-ли по-другому найти ответы на эти вопросы? - -Один способ это подсчитать число элементарных операций в зависимости от -различных объемов входных данных. Хотя это и приемлемое решение, тот объем -работы которого оно потребует, даже для простых алгоритмов, делает его -использование неоправданным. - -Другой способ это измерить какое время алгоритм потребует для завершения на -различных объемах входных данных. В тоже время, точность и относительность -(полученное время будет относиться только к той машине на которой оно -вычислено) этого метода зависит от среды выполнения: компьютерного аппаратного -обеспечения, мощности процессора и т.д. - -## Виды О-символики - -В первом разделе этого документа мы определили, что О-символика -позволяет оценивать алгоритмы в зависимости от изменения размера входных -данных. Представим что алгоритм это функция f, n размер входных данных и -f(n) время выполнения. Тогда для данного алгоритма f c размером входных -данных n получим какое-то результирующее время выполнения f(n). -Из этого можно построить график, где ось Y время выполнения, ось X размер входных -данных и точки на графике это время выполнения для заданного размера входных -данных. - -С помощью О-символики можно оценить функцию или алгоритм -несколькими различными способами. Например можно оценить алгоритм исходя -из нижней оценки, верхней оценки, тождественной оценки. Чаще всего встречается -анализ на основе верхней оценки. Как правило не используется нижняя оценка, -потому что она не подходит под планируемые условия. Отличный пример алгоритмы -сортировки, особенно добавление элементов в древовидную структуру. Нижняя оценка -большинства таких алгоритмов может быть дана как одна операция. В то время как в -большинстве случаев, добавляемые элементы должны быть отсортированы -соответствующим образом при помощи дерева, что может потребовать обхода целой -ветви. Это и есть худший случай, для которого планируется верхняя оценка. - -### Виды функций, пределы и упрощения - -``` -Логарифмическая функция - log n -Линейная функция - an + b -Квадратическая функция - an^2 + bn +c -Полиномиальная функция - an^z + . . . + an^2 + a*n^1 + a*n^0, где z константа -Экспоненциальная функция - a^n, где a константа -``` - -Приведены несколько базовых функций используемых при определении сложности в -различных оценках. Список начинается с самой медленно возрастающей функции -(логарифм, наиболее быстрое время выполнения) и следует до самой быстро -возрастающей функции (экспонента, самое медленное время выполнения). Отметим, -что в то время как 'n' или размер входных данных, возрастает в каждой из этих функций, -результат намного быстрее возрастает в квадратической, полиномиальной -и экспоненциальной по сравнению с логарифмической и линейной. - -Крайне важно понимать, что при использовании описанной далее нотации необходимо -использовать упрощенные выражения. -Это означает, что необходимо отбрасывать константы и слагаемые младших порядков, -потому что если размер входных данных (n в функции f(n) нашего примера) -увеличивается до бесконечности (в пределе), тогда слагаемые младших порядков -и константы становятся пренебрежительно малыми. Таким образом, если есть -константа например размера 2^9001 или любого другого невообразимого размера, -надо понимать, что её упрощение внесёт значительные искажения в точность -оценки. - -Т.к. нам нужны упрощенные выражения, немного скорректируем нашу таблицу... - -``` -Логарифм - log n -Линейная функция - n -Квадратическая функция - n^2 -Полиномиальная функция - n^z, где z константа -Экспонента - a^n, где a константа -``` - -### О-Большое -О-Большое, записывается как **О**, это асимптотическая запись для оценки худшего -случая или для ограничения заданой функции сверху. Это позволяет сделать -_**асимптотическую оценку верхней границы**_ скорости роста времени выполнения -алгоритма. Допустим `f(n)` время выполнения алгоритма и `g(n)` заданная временная -сложность которая проверяется для алгоритма. Тогда `f(n)` это O(g(n)), если -существуют действительные константы с (с > 0) и n<sub>0</sub>, такие -что `f(n)` <= `c g(n)` выполняется для всех n начиная с некоторого n<sub>0</sub> (n > n<sub>0</sub>). - -*Пример 1* - -``` -f(n) = 3log n + 100 -g(n) = log n -``` - -Является-ли `f(n)` O(g(n))? -Является-ли `3 log n + 100` O(log n)? -Посмотрим на определение О-Большого: - -``` -3log n + 100 <= c * log n -``` - -Существуют-ли константы c, n<sub>0</sub> такие что выражение верно для всех n > n<sub>0</sub> - -``` -3log n + 100 <= 150 * log n, n > 2 (неопределенно для n = 1) -``` - -Да! По определению О-Большого `f(n)` является O(g(n)). - -*Пример 2* - -``` -f(n) = 3 * n^2 -g(n) = n -``` - -Является-ли `f(n)` O(g(n))? -Является-ли `3 * n^2` O(n)? -Посмотрим на определение О-Большого: - -``` -3 * n^2 <= c * n -``` - -Существуют-ли константы c, n<sub>0</sub> такие что выражение верно для всех n > n<sub>0</sub>? -Нет, не существуют. `f(n)` НЕ ЯВЛЯЕТСЯ O(g(n)). - -### Омега-Большое -Омега-Большое, записывается как **Ω**, это асимптотическая запись для оценки -лучшего случая или для ограничения заданой функции снизу. Это позволяет сделать -_**асимптотическую оценку нижней границы**_ скорости роста времени выполнения -алгоритма. - -`f(n)` принадлежит Ω(g(n)), если существуют действительные константы -с (с > 0) и <sub>0</sub> (n<sub>0</sub> > 0), такие что `f(n)` >= `c g(n)` для всех n > n<sub>0</sub>. - -### Примечание - -Асимптотические оценки сделаные при помощи О-Большое и Омега-Большое могут -как быть так и не быть точными. Для того что бы обозначить что границы не -являются асимптотически точными используются записи о-малое и омега-малое. - -### О-Малое -O-Малое, записывается как **о**, это асимптотическая запись для оценки верхней -границы времени выполнения алгоритма, при условии что граница не является -асимптотически точной. - -`f(n)` является o(g(n)), если можно подобрать такие действительные константы, -что для всех c (c > 0) найдется n<sub>0</sub> (n<sub>0</sub> > 0), так -что `f(n)` < `c g(n)` выполняется для всех n (n > n<sub>0</sub>). - -Определения О-символики для О-Большое и О-Малое похожи. Главное отличие в том, -что если f(n) = O(g(n)), тогда условие f(n) <= c g(n) выполняется если _**существует**_ -константа c > 0, но если f(n) = o(g(n)), тогда условие f(n) < c g(n) выполняется -для _**всех**_ констант с > 0. - -### Омега-малое -Омега-малое, записывается как **ω**, это асимптотическая запись для оценки -верней границы времени выполнения алгоритма, при условии что граница не является -асимптотически точной. - -`f(n)` является ω(g(n)), если можно подобрать такие действительные константы, -что для всех c (c > 0) найдется n<sub>0</sub> (n<sub>0</sub> > 0), так -что `f(n)` > `c g(n)` выполняется для всех n (n > n<sub>0</sub>) - -Определения Ω-символики и ω-символики похожи. Главное отличие в том, что -если f(n) = Ω(g(n)), тогда условие f(n) >= c g(n) выполняется если _**существует**_ -константа c > 0, но если f(n) = ω(g(n)), тогда условие f(n) > c g(n) -выполняется для _**всех**_ констант с > 0. - -### Тета -Тета, записывается как **Θ**, это асимптотическая запись для оценки -_***асимптотически точной границы***_ времени выполнения алгоритма. - -`f(n)` является Θ(g(n)), если для некоторых действительных -констант c1, c2 и n<sub>0</sub> (c1 > 0, c2 > 0, n<sub>0</sub> > 0), -`c1 g(n)` < `f(n)` < `c2 g(n)` для всех n (n > n<sub>0</sub>). - -∴ `f(n)` является Θ(g(n)) означает что `f(n)` является O(g(n)) -и `f(n)` является Ω(g(n)). - -О-Большое основной инструмент для анализа сложности алгоритмов. -Так же смотрите примеры по ссылкам. - -### Заключение -Такую тему сложно изложить кратко, поэтому обязательно стоит пройти по ссылкам и -посмотреть дополнительную литературу. В них дается более глубокое описание с -определениями и примерами. - - -## Дополнительная литература - -* [Алгоритмы на Java](https://www.ozon.ru/context/detail/id/18319699/) -* [Алгоритмы. Построение и анализ](https://www.ozon.ru/context/detail/id/33769775/) - -## Ссылки - -* [Оценки времени исполнения. Cимвол O()](http://algolist.manual.ru/misc/o_n.php) -* [Асимптотический анализ и теория вероятностей](https://www.lektorium.tv/course/22903) - -## Ссылки (Eng) - -* [Algorithms, Part I](https://www.coursera.org/learn/algorithms-part1) -* [Cheatsheet 1](http://web.mit.edu/broder/Public/asymptotics-cheatsheet.pdf) -* [Cheatsheet 2](http://bigocheatsheet.com/) - +---
+category: Algorithms & Data Structures
+name: Asymptotic Notation
+contributors:
+ - ["Jake Prather", "http://github.com/JakeHP"]
+ - ["Divay Prakash", "http://github.com/divayprakash"]
+translators:
+ - ["pru-mike", "http://github.com/pru-mike"]
+lang: ru-ru
+---
+
+# О-символика
+
+## Что это такое?
+
+О-символика, или асимптотическая запись, — это система символов, позволяющая
+оценить время выполнения алгоритма, устанавливая зависимость времени выполнения
+от увеличения объёма входных данных. Она также известна как оценка
+сложности алгоритмов. Станет ли алгоритм невероятно медленным, когда
+объём входных данных увеличится? Будет ли алгоритм выполняться достаточно быстро,
+если объём входных данных возрастёт? О-символика позволяет ответить на эти
+вопросы.
+
+## Можно ли по-другому найти ответы на эти вопросы?
+
+Один способ — это подсчитать число элементарных операций в зависимости от
+различных объёмов входных данных. Хотя это и приемлемое решение, тот объём
+работы, которого оно потребует, даже для простых алгоритмов делает его
+использование неоправданным.
+
+Другой способ — это измерить, какое время алгоритм потребует для завершения на
+различных объёмах входных данных. В то же время, точность и относительность
+этого метода (полученное время будет относиться только к той машине, на которой
+оно вычислено) зависит от среды выполнения: компьютерного аппаратного
+обеспечения, мощности процессора и т.д.
+
+## Виды О-символики
+
+В первом разделе этого документа мы определили, что О-символика
+позволяет оценивать алгоритмы в зависимости от изменения размера входных
+данных. Представим, что алгоритм — это функция f, n — размер входных данных и
+f(n) — время выполнения. Тогда для данного алгоритма f с размером входных
+данных n получим какое-то результирующее время выполнения f(n).
+Из этого можно построить график, где ось y — время выполнения, ось x — размер входных
+данных, а точки на графике — это время выполнения для заданного размера входных
+данных.
+
+С помощью О-символики можно оценить функцию или алгоритм
+несколькими различными способами. Например, можно оценить алгоритм исходя
+из нижней оценки, верхней оценки, тождественной оценки. Чаще всего встречается
+анализ на основе верхней оценки. Как правило не используется нижняя оценка,
+потому что она не подходит под планируемые условия. Отличный пример — алгоритмы
+сортировки, особенно добавление элементов в древовидную структуру. Нижняя оценка
+большинства таких алгоритмов может быть дана как одна операция. В то время как в
+большинстве случаев добавляемые элементы должны быть отсортированы
+соответствующим образом при помощи дерева, что может потребовать обхода целой
+ветви. Это и есть худший случай, для которого планируется верхняя оценка.
+
+### Виды функций, пределы и упрощения
+
+```
+Логарифмическая функция — log n
+Линейная функция — an + b
+Квадратичная функция — an^2 + bn +c
+Степенная функция — an^z + . . . + an^2 + a*n^1 + a*n^0, где z — константа
+Показательная функция — a^n, где a — константа
+```
+
+Приведены несколько базовых функций, используемых при определении сложности в
+различных оценках. Список начинается с самой медленно возрастающей функции
+(логарифм, наиболее быстрое время выполнения) и следует до самой быстро
+возрастающей функции (экспонента, самое медленное время выполнения). Отметим,
+что в то время, как «n», или размер входных данных, возрастает в каждой из этих функций,
+результат намного быстрее возрастает в квадратичной, степенной
+и показательной по сравнению с логарифмической и линейной.
+
+Крайне важно понимать, что при использовании описанной далее нотации необходимо
+использовать упрощённые выражения.
+Это означает, что необходимо отбрасывать константы и слагаемые младших порядков,
+потому что если размер входных данных (n в функции f(n) нашего примера)
+увеличивается до бесконечности (в пределе), тогда слагаемые младших порядков
+и константы становятся пренебрежительно малыми. Таким образом, если есть
+константа, например, размера 2^9001 или любого другого невообразимого размера,
+надо понимать, что её упрощение внесёт значительные искажения в точность
+оценки.
+
+Т.к. нам нужны упрощённые выражения, немного скорректируем нашу таблицу...
+
+```
+Логарифм — log n
+Линейная функция — n
+Квадратичная функция — n^2
+Степенная функция — n^z, где z — константа
+Показательная функция — a^n, где a — константа
+```
+
+### О Большое
+О Большое, записывается как **О**, — это асимптотическая запись для оценки худшего
+случая, или для ограничения заданной функции сверху. Это позволяет сделать
+_**асимптотическую оценку верхней границы**_ скорости роста времени выполнения
+алгоритма. Пусть `f(n)` — время выполнения алгоритма, а `g(n)` — заданная временная
+сложность, которая проверяется для алгоритма. Тогда `f(n)` — это O(g(n)), если
+существуют действительные константы c (c > 0) и n<sub>0</sub>, такие,
+что `f(n)` <= `c g(n)` выполняется для всех n, начиная с некоторого n<sub>0</sub> (n > n<sub>0</sub>).
+
+*Пример 1*
+
+```
+f(n) = 3log n + 100
+g(n) = log n
+```
+
+Является ли `f(n)` O(g(n))?
+Является ли `3 log n + 100` O(log n)?
+Посмотрим на определение О Большого:
+
+```
+3log n + 100 <= c * log n
+```
+
+Существуют ли константы c и n<sub>0</sub>, такие, что выражение верно для всех n > n<sub>0</sub>?
+
+```
+3log n + 100 <= 150 * log n, n > 2 (не определенно для n = 1)
+```
+
+Да! По определению О Большого `f(n)` является O(g(n)).
+
+*Пример 2*
+
+```
+f(n) = 3 * n^2
+g(n) = n
+```
+
+Является ли `f(n)` O(g(n))?
+Является ли `3 * n^2` O(n)?
+Посмотрим на определение О Большого:
+
+```
+3 * n^2 <= c * n
+```
+
+Существуют ли константы c и n<sub>0</sub>, такие, что выражение верно для всех n > n<sub>0</sub>?
+Нет, не существуют. `f(n)` НЕ ЯВЛЯЕТСЯ O(g(n)).
+
+### Омега Большое
+Омега Большое, записывается как **Ω**, — это асимптотическая запись для оценки
+лучшего случая, или для ограничения заданной функции снизу. Это позволяет сделать
+_**асимптотическую оценку нижней границы**_ скорости роста времени выполнения
+алгоритма.
+
+`f(n)` является Ω(g(n)), если существуют действительные константы
+c (c > 0) и n<sub>0</sub> (n<sub>0</sub> > 0), такие, что `f(n)` >= `c g(n)` для всех n > n<sub>0</sub>.
+
+### Примечание
+
+Асимптотические оценки, сделаные при помощи О Большого и Омега Большого, могут
+как являться, так и не являться точными. Для того, чтобы обозначить, что границы не
+являются асимптотически точными, используются записи О Малое и Омега Малое.
+
+### О Малое
+O Малое, записывается как **о**, — это асимптотическая запись для оценки верхней
+границы времени выполнения алгоритма при условии, что граница не является
+асимптотически точной.
+
+`f(n)` является o(g(n)), если можно подобрать такие действительные константы,
+что для всех c (c > 0) найдётся n<sub>0</sub> (n<sub>0</sub> > 0), так
+что `f(n)` < `c g(n)` выполняется для всех n (n > n<sub>0</sub>).
+
+Определения О-символики для О Большого и О Малого похожи. Главное отличие в том,
+что если f(n) = O(g(n)), тогда условие f(n) <= c g(n) выполняется, если _**существует**_
+константа c > 0, но если f(n) = o(g(n)), тогда условие f(n) < c g(n) выполняется
+для _**всех**_ констант c > 0.
+
+### Омега Малое
+Омега Малое, записывается как **ω**, — это асимптотическая запись для оценки
+верхней границы времени выполнения алгоритма при условии, что граница не является
+асимптотически точной.
+
+`f(n)` является ω(g(n)), если можно подобрать такие действительные константы,
+что для всех c (c > 0) найдётся n<sub>0</sub> (n<sub>0</sub> > 0), так
+что `f(n)` > `c g(n)` выполняется для всех n (n > n<sub>0</sub>).
+
+Определения Ω-символики и ω-символики похожи. Главное отличие в том, что
+если f(n) = Ω(g(n)), тогда условие f(n) >= c g(n) выполняется, если _**существует**_
+константа c > 0, но если f(n) = ω(g(n)), тогда условие f(n) > c g(n)
+выполняется для _**всех**_ констант c > 0.
+
+### Тета
+Тета, записывается как **Θ**, — это асимптотическая запись для оценки
+_***асимптотически точной границы***_ времени выполнения алгоритма.
+
+`f(n)` является Θ(g(n)), если для некоторых действительных
+констант c1, c2 и n<sub>0</sub> (c1 > 0, c2 > 0, n<sub>0</sub> > 0)
+`c1 g(n)` < `f(n)` < `c2 g(n)` для всех n (n > n<sub>0</sub>).
+
+∴ `f(n)` является Θ(g(n)) означает, что `f(n)` является O(g(n))
+и `f(n)` является Ω(g(n)).
+
+О Большое — основной инструмент для анализа сложности алгоритмов.
+Также см. примеры по ссылкам.
+
+### Заключение
+Такую тему сложно изложить кратко, поэтому обязательно стоит пройти по ссылкам и
+посмотреть дополнительную литературу. В ней даётся более глубокое описание с
+определениями и примерами.
+
+
+## Дополнительная литература
+
+* [Алгоритмы на Java](https://www.ozon.ru/context/detail/id/18319699/)
+* [Алгоритмы. Построение и анализ](https://www.ozon.ru/context/detail/id/33769775/)
+
+## Ссылки
+
+* [Оценки времени исполнения. Символ O()](http://algolist.manual.ru/misc/o_n.php)
+* [Асимптотический анализ и теория вероятностей](https://www.lektorium.tv/course/22903)
+
+## Ссылки (англ.)
+
+* [Algorithms, Part I](https://www.coursera.org/learn/algorithms-part1)
+* [Cheatsheet 1](http://web.mit.edu/broder/Public/asymptotics-cheatsheet.pdf)
+* [Cheatsheet 2](http://bigocheatsheet.com/)
+
diff --git a/ru-ru/bash-ru.html.markdown b/ru-ru/bash-ru.html.markdown index 5e99afc2..ce918340 100644 --- a/ru-ru/bash-ru.html.markdown +++ b/ru-ru/bash-ru.html.markdown @@ -11,29 +11,40 @@ contributors: - ["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"] + - ["Harry Mumford-Turner", "https://github.com/harrymt"] + - ["Martin Nicholson", "https://github.com/mn113"] translators: - ["Andrey Samsonov", "https://github.com/kryzhovnik"] - - ["Andre Polykanine", "https://github.com/Oire"] + - ["Andre Polykanine", "https://github.com/Menelion"] filename: LearnBash-ru.sh lang: ru-ru --- -Bash - это командная оболочка unix (unix shell), которая распространялась как оболочка для операционной системы GNU и используется в качестве оболочки по умолчанию для Linux и Mac OS X. -Почти все нижеприведенные примеры могут быть частью shell-скриптов или исполнены напрямую в shell. +Bash — это командная оболочка unix, которая распространялась как оболочка +для операционной системы GNU и используется в качестве оболочки по умолчанию +для Linux и Mac OS X. +Почти все нижеприведённые примеры могут быть частью shell-скриптов +или исполнены напрямую в shell. [Подробнее.](http://www.gnu.org/software/bash/manual/bashref.html) ```bash #!/bin/bash -# Первая строка скрипта - это shebang, который сообщает системе, как исполнять -# этот скрипт: http://en.wikipedia.org/wiki/Shebang_(Unix) -# Как вы уже поняли, комментарии начинаются с #. Shebang - тоже комментарий. +# Первая строка скрипта — это шебанг, который сообщает системе, как исполнять +# этот скрипт: https://ru.wikipedia.org/wiki/Шебанг_(Unix) +# Как вы уже поняли, комментарии начинаются с «#». Шебанг — тоже комментарий. # Простой пример hello world: echo Hello world! # Отдельные команды начинаются с новой строки или разделяются точкой с запятой: echo 'Это первая строка'; echo 'Это вторая строка' +# => Это первая строка +# => Это вторая строка # Вот так объявляется переменная: VARIABLE="Просто строка" @@ -41,103 +52,234 @@ VARIABLE="Просто строка" # но не так: VARIABLE = "Просто строка" # Bash решит, что VARIABLE - это команда, которую он должен исполнить, -# и выдаст ошибку, потому что не сможет найти ее. +# и выдаст ошибку, потому что не сможет найти её. # и не так: VARIABLE= 'Просто строка' -# Тут Bash решит, что 'Просто строка' - это команда, которую он должен исполнить, -# и выдаст ошибку, потому что не сможет найти такой команды +# Тут Bash решит, что 'Просто строка' — это команда, которую он должен +# исполнить, и выдаст ошибку, потому что не сможет найти такой команды # (здесь 'VARIABLE=' выглядит как присвоение значения переменной, # но только в контексте исполнения команды 'Просто строка'). # Использование переменой: -echo $VARIABLE -echo "$VARIABLE" -echo '$VARIABLE' -# Когда вы используете переменную - присваиваете, экспортируете и т.д. - +echo $VARIABLE # => Просто строка +echo "$VARIABLE" # => Просто строка +echo '$VARIABLE' # => $Variable +# Когда вы используете переменную — присваиваете, экспортируете и т.д. — # пишите её имя без $. А для получения значения переменной используйте $. # Заметьте, что ' (одинарные кавычки) не раскрывают переменные в них. -# Подстановка строк в переменные -echo ${VARIABLE/Просто/A} -# Это выражение заменит первую встреченную подстроку "Просто" на "A" +# Раскрытие параметров ${ }: +echo ${Variable} # => Просто строка +# Это простое использование раскрытия параметров +# Раскрытие параметров получает значение переменной. +# Оно «раскрывает», или печатает это значение. +# ̶Значение можно изменить во время раскрытия. +# Ниже приведены другие модификации при раскрытии параметров. + +# Замена подстрок в переменных +echo ${Variable/Просто/Это} # => Это строка +# Заменит первое вхождение «Просто» на «Это» # Взять подстроку из переменной LENGTH=7 -echo ${VARIABLE:0:LENGTH} -# Это выражение вернет только первые 7 символов переменной VARIABLE +echo ${VARIABLE:0:LENGTH} # => Просто +# Это выражение вернёт только первые 7 символов переменной VARIABLE +echo ${Variable: -5} # => трока +# Вернёт последние 5 символов (обратите внимание на пробел перед «-5») + +# Длина строки +echo ${#Variable} # => 13 -# Значение по умолчанию -echo ${FOO:-"DefaultValueIfFOOIsMissingOrEmpty"} +# Значение переменной по умолчанию +echo ${FOO:-"ЗначениеПоУмолчаниюЕслиFooПустаИлиНеНайдена"} +# => ЗначениеПоУмолчаниюЕслиFooПустаИлиНеНайдена # Это сработает при отсутствующем значении (FOO=) и пустой строке (FOO=""); -# ноль (FOO=0) вернет 0. -# Заметьте, что в любом случае значение самой переменной FOO не изменится. +# ноль (FOO=0) вернёт 0. +# Заметьте, что в любом случае это лишь вернёт значение по умолчанию, +# а значение самой переменной FOO не изменится. + +# Объявить массив из 6 элементов +array0=(один два три четыре пять шесть) +# Вывести первый элемент +echo $array0 # => "один" +# Вывести первый элемент +echo ${array0[0]} # => "один" +# Вывести все элементы +echo ${array0[@]} # => "один два три четыре пять шесть" +# Вывести число элементов +echo ${#array0[@]} # => "6" +# Вывести число символов в третьем элементе +echo ${#array0[2]} # => "3" +# Вывести 2 элемента, начиная с четвёртого +echo ${array0[@]:3:2} # => "четыре пять" +# Вывести все элементы, каждый на своей строке +for i in "${array0[@]}"; do + echo "$i" +done + +# Раскрытие скобок { } +# Используется для создания произвольных строк +echo {1..10} # => 1 2 3 4 5 6 7 8 9 10 +echo {a..z} # => a b c d e f g h i j k l m n o p q r s t u v w x y z +# Выведет диапазон от начального до конечного значения # Встроенные переменные: # В bash есть полезные встроенные переменные, например -echo "Последнее возвращенное значение: $?" -echo "PID скрипта: $$" -echo "Количество аргументов: $#" -echo "Аргументы скрипта: $@" +echo "Значение, возвращённое последней программой: $?" +echo "Идентификатор процесса скрипта: $$" +echo "Число аргументов, переданных скрипту: $#" +echo "Все аргументы, переданные скрипту: $@" echo "Аргументы скрипта, распределённые по отдельным переменным: $1 $2..." -# Чтение аргументов из устройста ввода: +# Теперь, когда мы знаем, как выводить и использовать переменные, +# давайте изучим некоторые другие основы Bash! + +# Текущая директория доступна по команде `pwd`. +# `pwd` расшифровывается как «print working directory», т.е. +# «напечатать рабочую директорию». +# Мы также можем использовать встроенную переменную `$PWD`. +# Заметьте, следующие выражения эквивалентны: +echo "Я в $(pwd)" # выполняет `pwd` и раскрывает вывод +echo "Я в $PWD" # раскрывает переменную + +# Если вы получаете слишком много информации в терминале или из скрипта, +# команда `clear` очистит экран +clear +# Очистить экран можно также с помощью Ctrl+L + +# Чтение аргументов с устройства ввода: echo "Как Вас зовут?" read NAME # Обратите внимание, что нам не нужно определять новую переменную echo Привет, $NAME! # У нас есть обычная структура if: # наберите 'man test' для получения подробной информации о форматах условия -if [ $NAME -ne $USER ] +if [ $NAME != $USER ] then echo "Имя не совпадает с именем пользователя" else echo "Имя совпадает с именем пользователя" fi +# Истинно, если значение $Name не совпадает с текущим именем пользователя -# Примечание: если $Name пустой, bash интерпретирует код как: -if [ -ne $USER ] +# Примечание: если $Name пуста, bash интерпретирует код так: +if [ != $USER ] # а это ошибочная команда -# поэтому такие переменные нужно использовать так: -if [ "$Name" -ne $USER ] ... -# когда $Name пустой, bash видит код как: -if [ "" -ne $USER ] ... +# поэтому «безопасный» способ использовать пустые переменные в Bash таков: +if [ "$Name" != $USER ] ... +# при этом, когда $Name пуста, bash видит код так: +if [ "" != $USER ] ... # что работает правильно # Также есть условное исполнение echo "Исполнится всегда" || echo "Исполнится, если первая команда завершится ошибкой" +# => Исполнится всегда echo "Исполнится всегда" && echo "Исполнится, если первая команда выполнится удачно" +# => Исполнится всегда +# => Исполнится, если первая команда выполнится удачно -# Можно использовать && и || в выражениях if, когда нужно несколько пар скобок: -if [ $NAME == "Steve" ] && [ $AGE -eq 15 ] + +# Чтобы использовать && и || в выражениях if, нужно несколько пар скобок: +if [ $NAME == "Стив" ] && [ $AGE -eq 15 ] +then + echo "Исполнится, если $NAME равно Стив И $AGE равно 15." +fi + +if [ $NAME == "Дания" ] || [ $NAME == "Зак" ] then - echo "Исполнится, если $NAME равно Steve И $AGE равно 15." + echo "Исполнится, если $NAME равно Дания ИЛИ Зак." fi -if [ $NAME == "Daniya" ] || [ $NAME == "Zach" ] +# Есть ещё оператор «=~», который проверяет строку +# на соответствие регулярному выражению: +Email=me@example.com +if [[ "$Email" =~ [a-z]+@[a-z]{2,}\.(com|net|org) ]] then - echo "Исполнится, если $NAME равно Daniya ИЛИ Zach." + echo "адрес корректный!" fi +# Обратите внимание, что =~ работает только внутри +# двойных квадратных скобок [[ ]], +# которые несколько отличаются от одинарных скобок [ ]. +# Для более подробной информации см. http://www.gnu.org/software/bash/manual/bashref.html#Conditional-Constructs. + +# Переопределить команду «ping» как псевдоним для отправки только пяти пакетов +alias ping='ping -c 5' +# Экранировать псевдоним и использовать команду под своим именем вместо него +\ping 192.168.1.1 +# Вывести все псевдонимы +alias -p # Выражения обозначаются таким форматом: -echo $(( 10 + 5 )) +echo $(( 10 + 5 )) # => 15 -# В отличие от других языков программирования, Bash - это командная оболочка, +# В отличие от других языков программирования, Bash — это командная оболочка, # а значит, работает в контексте текущей директории. # Вы можете просматривать файлы и директории в текущей директории командой ls: -ls +ls # перечисляет файлы и поддиректории в текущей директории -# У этой команды есть опции: +# У этой команды есть параметры: ls -l # Показать каждый файл и директорию на отдельной строке +ls -t # сортирует содержимое по дате последнего изменения (в обратном порядке) +ls -R # Рекурсивно выполняет `ls` по данной директории и всем её поддиректориям # Результат предыдущей команды может быть направлен на вход следующей. # Команда grep фильтрует ввод по шаблону. -# Так мы можем просмотреть только *.txt файлы в текущей директории: +# Так мы можем просмотреть только *.txt-файлы в текущей директории: ls -l | grep "\.txt" +# Для вывода файлов в стандартный поток используйте `cat`: +cat file.txt + +# С помощью `cat` мы также можем читать файлы: +Contents=$(cat file.txt) +echo "НАЧАЛО ФАЙЛА\n$Contents\nКОНЕЦ ФАЙЛА" # «\n» выводит символ перевода на новую строку +# => НАЧАЛО ФАЙЛА +# => [Содержимое file.txt] +# => КОНЕЦ ФАЙЛА + +# Для копирования файлов и директорий из одного места в другое используйте `cp`. +# `cp` создаёт новые версии исходных элементов, +# так что редактирование копии не повлияет на оригинал (и наоборот). +# Обратите внимание, что команда перезапишет целевой элемент, если он уже существует. +cp srcFile.txt clone.txt +cp -r srcDirectory/ dst/ # рекурсивное копирование + +# Если вам нужно обмениваться файлами между компьютерами, посмотрите в сторону `scp` или `sftp`. +# `scp` ведёт себя очень похоже на `cp`. +# `sftp` более интерактивна. + +# Для перемещения файлов и директорий из одного места в другое используйте `mv`. +# Команда `mv` похожа на `cp`, но она удаляет исходный элемент. +# `mv` также можно использовать для переименования файлов! +mv s0urc3.txt dst.txt # Извините, тут были Leet-хакеры... + +# Поскольку Bash работает в контексте текущей директории, вам может понадобиться +# запустить команду в другой директории. +# Для изменения местоположения у нас есть `cd`: +cd ~ # Перейти в домашнюю директорию +cd # Также переходит в домашнюю директорию +cd .. # Перейти на уровень вверх + # (например, из /home/username/Downloads в /home/username) +cd /home/username/Documents # перейти в указанную директорию +cd ~/Documents/.. # Всё ещё в домашней директории. Так ведь?? +cd - # Перейти в последнюю директорию +# => /home/username/Documents + +# Для работы по директориям используйте субоболочки +(echo "Сначала я здесь: $PWD") && (cd someDir; echo "А теперь я тут: $PWD") +pwd # всё ещё в первой директории + +# Для создания новых директорий используйте `mkdir`. +mkdir myNewDir +# Флаг `-p` указывает, что нужно создать все промежуточные директории, если нужно. +mkdir -p myNewDir/with/intermediate/directories +# Если промежуточные директории до этого не существовали, +# вышеприведённая команда без флага `-p` вернёт ошибку + # Вы можете перенаправить ввод и вывод команды (stdin, stdout и stderr). -# Следующая команда означает: читать из stdin, пока не встретится ^EOF$, и -# перезаписать hello.py следующим строками (до строки "EOF"): +# Прочитать из stdin, пока не встретится ^EOF$, и +# перезаписать hello.py следующими строками (до строки "EOF"): cat > hello.py << EOF #!/usr/bin/env python from __future__ import print_function @@ -147,23 +289,25 @@ print("#stderr", file=sys.stderr) for line in sys.stdin: print(line, file=sys.stdout) EOF +# Если первый «EOF» не заключён в кавычки, переменные будут раскрыты # Запуск hello.py с разными вариантами перенаправления потоков # стандартных ввода, вывода и ошибок: -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 +python hello.py < "input.in" # передать input.in в качестве ввода в скрипт +python hello.py > "output.out" # передать вывод скрипта в output.out +python hello.py 2> "error.err" # передать вывод ошибок в error.err +python hello.py > "output-and-error.log" 2>&1 # передать вывод скрипта и ошибок в output-and-error.log +python hello.py > /dev/null 2>&1 # передать вывод скрипта и ошибок в «чёрную дыру» /dev/null, т.е., без вывода # Поток ошибок перезапишет файл, если этот файл существует, -# поэтому, если вы хотите дописывать файл, используйте ">>": +# поэтому, если вы хотите дописывать файл, используйте «>>»: python hello.py >> "output.out" 2>> "error.err" -# Переписать output.txt, дописать error.err и сосчитать строки: +# Перезаписать output.txt, дописать error.err и сосчитать строки: info bash 'Basic Shell Features' 'Redirections' > output.out 2>> error.err wc -l output.out error.err -# Запустить команду и вывести ее файловый дескриптор (смотрите: man fd) +# Запустить команду и вывести её файловый дескриптор (например, /dev/fd/123) +# См. man fd echo <(echo "#helloworld") # Перезаписать output.txt строкой "#helloworld": @@ -172,40 +316,49 @@ echo "#helloworld" > output.out echo "#helloworld" | cat > output.out echo "#helloworld" | tee output.out >/dev/null -# Подчистить временные файлы с подробным выводом ('-i' - интерактивый режим) +# Подчистить временные файлы с подробным выводом ('-i' — интерактивный режим) +# ВНИМАНИЕ: команду `rm` отменить нельзя rm -v output.out error.err output-and-error.log +rm -r tempDir/ # рекурсивное удаление # Команды могут быть подставлены в строку с помощью $( ): # следующие команды выводят число файлов и директорий в текущей директории. echo "Здесь $(ls | wc -l) элементов." -# То же самое можно сделать с использованием обратных кавычек, +# То же самое можно сделать с использованием обратных кавычек «``», # но они не могут быть вложенными, поэтому предпочтительно использовать $( ). echo "Здесь `ls | wc -l` элементов." # В Bash есть структура case, которая похожа на switch в Java и C++: case "$VARIABLE" in - # Перечислите шаблоны для условий, которые хотите отловить + # Перечислите шаблоны для условий, которые хотите выполнить 0) echo "Тут ноль.";; 1) echo "Тут один.";; *) echo "Это не пустое значение.";; esac -# Цикл for перебирает элементы переданные в аргументе: +# Цикл for перебирает элементы по количеству аргументов: # Содержимое $VARIABLE будет напечатано три раза. for VARIABLE in {1..3} do echo "$VARIABLE" done +# => 1 +# => 2 +# => 3 + -# Или с использованием "традиционного" синтаксиса цикла for: +# Или с использованием «традиционного» синтаксиса цикла for: for ((a=1; a <= 3; a++)) do echo $a done +# => 1 +# => 2 +# => 3 # Цикл for можно использовать для действий с файлами. -# Запустим команду 'cat' для файлов file1 и file2 +# Запустим команду «cat» для файлов file1 и file2 for VARIABLE in file1 file2 do cat "$VARIABLE" @@ -221,52 +374,89 @@ done # Цикл while: while [ true ] do - echo "тело цикла здесь..." + echo "Здесь тело цикла..." break done +# => Здесь тело цикла... -# Вы можете определять функции +# Вы также можете определять функции # Определение: function foo () { - echo "Аргументы работают также, как аргументы скрипта: $@" - echo "и: $1 $2..." + echo "Аргументы работают так же, как и аргументы скрипта: $@" + echo "И так: $1 $2..." echo "Это функция" return 0 } +# Вызовем функцию `foo` с двумя аргументами, arg1 и arg2: +foo arg1 arg2 +# => Аргументы работают так же, как и аргументы скрипта: arg1 arg2 +# => И так: arg1 arg2... +# => Это функция # или просто bar () { - echo "Другой способ определить функцию!" + echo "Другой способ определять функции!" return 0 } +# Вызовем функцию `bar` без аргументов: +bar # => Другой способ определять функции! # Вызов функции -foo "Мое имя" $NAME +foo "Меня зовут" $NAME # Есть много полезных команд, которые нужно знать: # напечатать последние 10 строк файла file.txt tail -n 10 file.txt + # напечатать первые 10 строк файла file.txt head -n 10 file.txt + # отсортировать строки file.txt sort file.txt -# отобрать или наоборот пропустить повторяющиеся строки (с опцией -d отбирает) + +# отобрать или наоборот пропустить повторяющиеся строки (с параметром `-d` отбирает строки) uniq -d file.txt -# напечатать только первую колонку перед символом ',' + +# напечатать только первый столбец перед символом «,» cut -d ',' -f 1 file.txt -# заменить каждое 'okay' на 'great' в файле file.txt (regex поддерживается) -sed -i 's/okay/great/g' file.txt -# вывести в stdout все строки из file.txt, совпадающие с шаблоном regex; -# этот пример выводит строки, которые начинаются на "foo" и оканчиваются "bar" + +# заменить каждое вхождение «хорошо» на «прекрасно» в файле file.txt +# (поддерживаются регулярные выражения) +sed -i 's/хорошо/прекрасно/g' file.txt + +# вывести в stdout все строки из file.txt, соответствующие регулярному выражению +# этот пример выводит строки, которые начинаются на «foo» и оканчиваются на «bar» grep "^foo.*bar$" file.txt -# передайте опцию -c чтобы вывести число строк, в которых совпал шаблон + +# Передайте параметр `-c`, чтобы вывести лишь число строк, +# соответствующих регулярному выражению grep -c "^foo.*bar$" file.txt -# чтобы искать по строке, а не шаблону regex, используйте fgrep (или grep -F) + +# Ниже приведены другие полезные параметры: +grep -r "^foo.*bar$" someDir/ # рекурсивный `grep` +grep -n "^foo.*bar$" file.txt # задаются номера строк +grep -rI "^foo.*bar$" someDir/ # рекурсивный `grep` с игнорированием двоичных файлов + +# Выполнить тот же изначальный поиск, но удалив строки, содержащие «baz» +grep "^foo.*bar$" file.txt | grep -v "baz" + +# чтобы искать непосредственно по строке, а не в соответствии +# с регулярным выражением, используйте fgrep (или grep -F): fgrep "^foo.*bar$" file.txt -# Читайте встроенную документацию оболочки Bash командой 'help': +# Команда `trap` позволяет выполнить некую команду, когда ваш скрипт +# принимает определённый Posix-сигнал. В следующем примере `trap` выполнит `rm`, +# если скрипт примет один из трёх перечисленных сигналов. +trap "rm $TEMP_FILE; exit" SIGHUP SIGINT SIGTERM + +# `sudo` используется для выполнения команд с правами суперпользователя +NAME1=$(whoami) +NAME2=$(sudo whoami) +echo "Был $NAME1, затем стал более мощным $NAME2" + +# Читайте встроенную документацию оболочки Bash командой `help`: help help help help for @@ -274,18 +464,18 @@ help return help source help . -# Читайте Bash man-документацию +# Читайте man-документацию Bash командой `man`: apropos bash man 1 bash man bash -# Читайте документацию info (? для помощи) +# Читайте документацию info (? для справки) apropos info | grep '^info.*(' man info info info info 5 info -# Читайте bash info документацию: +# Читайте info-документацию Bash: info bash info bash 'Bash Features' info bash 6 diff --git a/ru-ru/learnvisualbasic-ru.html.markdown b/ru-ru/learnvisualbasic-ru.html.markdown new file mode 100644 index 00000000..72e1358c --- /dev/null +++ b/ru-ru/learnvisualbasic-ru.html.markdown @@ -0,0 +1,284 @@ +--- +language: Visual Basic +contributors: + - ["Brian Martin", "http://brianmartin.biz"] +translators: + - ["satory-ra", "https://github.com/satory-ra"] +filename: learnvisualbasic-ru.vb +lang: ru-ru +--- + +```vbnet +Module Module1 + + Sub Main() + 'Краткий обзор консольных приложений Visual Basic перед более + 'глубоким изучением. + 'Апостроф начинает строку комментария. + 'Чтобы изучить это руководство в компиляторе Visual Basic, + 'я создал систему навигации. + 'Эта система будет объяснена при прохождении этого урока. + 'Постепенно вы всё поймете. + Console.Title = ("Выучи Х за Y минут") + Console.WriteLine("НАВИГАЦИЯ") 'Display + Console.WriteLine("") + Console.ForegroundColor = ConsoleColor.Green + Console.WriteLine("1. Вывод данных") + Console.WriteLine("2. Ввод данных") + Console.WriteLine("3. Расчёт целых чисел") + Console.WriteLine("4. Расчёт десятичных дробей") + Console.WriteLine("5. Калькулятор") + Console.WriteLine("6. Использование циклов Do While") + Console.WriteLine("7. Использование циклов For") + Console.WriteLine("8. Условные выражения") + Console.WriteLine("9. Выберите напиток") + Console.WriteLine("50. О приложении") + Console.WriteLine("Выберите номер из списка") + Dim selection As String = Console.ReadLine + '«Case» в операторе Select не является обязательным. + 'Например, "Select selection" вместо "Select Case selection" + 'также будет работать. + Select Case selection + Case "1" 'Вывод данных + Console.Clear() 'Очищает окно консоли + HelloWorldOutput() 'Открывает приватную подпрограмму. + Case "2" 'Ввод данных + Console.Clear() + HelloWorldInput() + Case "3" 'Расчёт целых чисел + Console.Clear() + CalculatingWholeNumbers() + Case "4" 'Расчёт десятичных дробей + Console.Clear() + CalculatingDecimalNumbers() + Case "5" 'Калькулятор + Console.Clear() + WorkingCalculator() + Case "6" 'Использование циклов Do While + Console.Clear() + UsingDoWhileLoops() + Case "7" 'Использование циклов For + Console.Clear() + UsingForLoops() + Case "8" 'Условные выражения + Console.Clear() + ConditionalStatement() + Case "9" 'Выражения If/Else + Console.Clear() + IfElseStatement() 'Выберите напиток + Case "50" 'Окно сообщения «О приложении» + Console.Clear() + Console.Title = ("Выучи Х за Y минут :: О приложении") + MsgBox("Это руководство от Брайана Мартина (@BrianMartinn") + Console.Clear() + Main() + Console.ReadLine() + + End Select + End Sub + + 'Один - Я использую эти цифры для того, чтобы было проще + 'соотносить код с системой навигации. + + 'Мы используем частные подпрограммы для разделения различных + 'разделов программы. + Private Sub HelloWorldOutput() + 'Название консольного приложения + Console.Title = "Вывод данных | Выучи Х за Y минут" + 'Используйте Console.Write ("") или Console.WriteLine ("") + 'для отображения результатов. + 'Затем следует Console.Read () или Console.Readline () + 'Console.ReadLine () показывает вывод в консоли. + Console.WriteLine("Hello World") + Console.ReadLine() + End Sub + + 'Два + Private Sub HelloWorldInput() + Console.Title = "Ввод данных | Выучи Х за Y минут" + 'Переменная + 'используется для хранения пользовательских данных. + 'Объявление переменных начинается с Dim и заканчиваются + 'As VariableType (тип переменной). + + 'В этом уроке мы хотим узнать ваше имя и заставить программу + 'реагировать на это. + Dim username As String + 'Мы используем тип «string», так как ваше имя - это текстовая переменная. + Console.WriteLine("Привет, как тебя зовут? ") 'Просит ввести имя. + username = Console.ReadLine() 'Сохраняет имя в переменной username. + Console.WriteLine("Пирвет, " + username) 'Выводит: «Привет, 'имя'» + Console.ReadLine() 'Отображает вышеуказанный вывод. + + 'Вышеуказанная программа спросит ваше имя и скажет вам привет. + 'Есть и другие типы переменных, такие как целые числа (Integer), + 'мы используем Integer для обработки целых чисел. + End Sub + + 'Три + Private Sub CalculatingWholeNumbers() + Console.Title = "Расчёт целых чисел | Выучи Х за Y минут" + Console.Write("Первое число: ") 'Введите первое целое число: 1, 2, 50, 104 и т.д. + Dim a As Integer = Console.ReadLine() + Console.Write("Второе число: ") 'Введите второе целое число. + Dim b As Integer = Console.ReadLine() + Dim c As Integer = a + b + Console.WriteLine(c) + Console.ReadLine() + 'Приведенная программа сумирует два целых числа + End Sub + + 'Четыре + Private Sub CalculatingDecimalNumbers() + Console.Title = "Расчёт десятичных дробей | Выучи Х за Y минут" + 'Мы также должны уметь обрабатывать десятичные дроби. + 'Просто измените тип переменной с Integer на Double. + + 'Введите число с плавающей точкой: 1.2, 2.4, 50.1, 104.9 и т.д. + Console.Write("Первое число: ") + Dim a As Double = Console.ReadLine + Console.Write("Второе число: ") 'Введите второе число с плавающей точкой. + Dim b As Double = Console.ReadLine + Dim c As Double = a + b + Console.WriteLine(c) + Console.ReadLine() + 'Приведенный выше код может сложить две десятичных дроби. + End Sub + + 'Пять + Private Sub WorkingCalculator() + Console.Title = "Калькулятор | Выучи Х за Y минут" + 'Но что, если вам нужен калькулятор, который может обрабатывать сложение, + 'вычитание, умножение и деление? + 'Просто скопируйте и вставьте приведенный код. + Console.Write("Первое число: ") + Dim a As Double = Console.ReadLine + Console.Write("Второе число: ") + Dim b As Double = Console.ReadLine + Dim c As Double = a + b + Dim d As Double = a * b + Dim e As Double = a - b + Dim f As Double = a / b + + 'С помощью следующего кода мы можем вывести результат сложения, + 'вычитания, умножения и деления, рассчитанный выше, на экран. + Console.Write(a.ToString() + " + " + b.ToString()) + 'Мы хотим, чтобы в начале ответа было 3 пробела, для этого + 'вы можете использовать метод String.PadLeft (3). + Console.WriteLine(" = " + c.ToString.PadLeft(3)) + Console.Write(a.ToString() + " * " + b.ToString()) + Console.WriteLine(" = " + d.ToString.PadLeft(3)) + Console.Write(a.ToString() + " - " + b.ToString()) + Console.WriteLine(" = " + e.ToString.PadLeft(3)) + Console.Write(a.ToString() + " / " + b.ToString()) + Console.WriteLine(" = " + f.ToString.PadLeft(3)) + Console.ReadLine() + + End Sub + + 'Шесть + Private Sub UsingDoWhileLoops() + 'Код такой же, как и в предидущей подпрограмме + 'На этот раз мы спрашиваем, хочет ли пользователь продолжить (да или нет?) + 'Мы будем использовать цикл Do While, потому что не знаем, + 'понадобиться ли пользователю калькулятор болше одного раза. + Console.Title = "Использование циклов Do While | Выучи Х за Y минут" + Dim answer As String + 'Мы используем тип переменной "String", так как её значение текст. + Do 'Мы начаем программу с + Console.Write("Первое число: ") + Dim a As Double = Console.ReadLine + Console.Write("Второе число: ") + Dim b As Double = Console.ReadLine + Dim c As Double = a + b + Dim d As Double = a * b + Dim e As Double = a - b + Dim f As Double = a / b + + Console.Write(a.ToString() + " + " + b.ToString()) + Console.WriteLine(" = " + c.ToString.PadLeft(3)) + Console.Write(a.ToString() + " * " + b.ToString()) + Console.WriteLine(" = " + d.ToString.PadLeft(3)) + Console.Write(a.ToString() + " - " + b.ToString()) + Console.WriteLine(" = " + e.ToString.PadLeft(3)) + Console.Write(a.ToString() + " / " + b.ToString()) + Console.WriteLine(" = " + f.ToString.PadLeft(3)) + Console.ReadLine() + 'Спросите пользователя, хочет ли он продолжить, + 'в ответе учитывается регистр букв. + Console.Write("Желаете ли вы продолжить? (да / нет)") + 'Программа берет значение и записывает в переменную answer. + answer = Console.ReadLine() + 'Когда пользователь вводит «да», программа переходит к Do и снова запускается. + Loop While answer = "yes" + + End Sub + + 'Семь + Private Sub UsingForLoops() + 'Иногда программу нужно запускать только один раз. + 'В этой программе мы осуществим обратный отсчет от 10. + + Console.Title = "Использование циклов For | Выучи Х за Y минут" + 'Объявите переменные и Step (размер шага, то есть скорость уменьшения, + 'например, -1, -2, -3 и т.д.). + For i As Integer = 10 To 0 Step -1 + Console.WriteLine(i.ToString) 'Показывает значение счетчика. + Next i 'Рассчитать новое значение i. + Console.WriteLine("Поехали") + Console.ReadLine() + End Sub + + 'Восемь + Private Sub ConditionalStatement() + Console.Title = "Условные выражения | Выучи Х за Y минут" + Dim userName As String + Console.WriteLine("Привет, как тебя зовут? ") 'Спросите имя пользователя. + userName = Console.ReadLine() 'Записать имя в переменную userName. + If userName = "Адам" Then + Console.WriteLine("Привет, Адам") + Console.WriteLine("Спасибо за создание этого полезного сайта") + Console.ReadLine() + Else + Console.WriteLine("Привет " + userName) + Console.WriteLine("Вы заглянули на сайт www.learnxinyminutes.com") + Console.ReadLine() 'Программа останавливается и выводит вышеуказанный текст. + End If + End Sub + + 'Девять + Private Sub IfElseStatement() + Console.Title = "Выражения If/Else | Выучи Х за Y минут" + 'Иногда важно рассмотреть более двух альтернатив. + 'Иногда некоторые из них лучше других. + 'Когда это произойдет, нам потребуется более одного утверждения «if» (если). + 'Оператор «if» подобен торговому автомату. + 'В котором пользователь пишет код (A1, A2, A3 и т.д.), чтобы выбрать элементы. + 'Все варианты могут быть объединены в одном утверждении «if». + + Dim selection As String 'Объявить переменную для выбора + Console.WriteLine("Пожалуйста, выберите продукт из нашего прекрасного торгового автомата.") + Console.WriteLine("A1. для 7Up") + Console.WriteLine("A2. для Fanta") + Console.WriteLine("A3. для Dr. Pepper") + Console.WriteLine("A4. для Diet Coke") + + selection = Console.ReadLine() 'Сохранить выбор пользователя + If selection = "A1" Then + Console.WriteLine("7up") + ElseIf selection = "A2" Then + Console.WriteLine("Fanta") + ElseIf selection = "A3" Then + Console.WriteLine("Dr. Pepper") + ElseIf selection = "A4" Then + Console.WriteLine("Diet Coke") + Else + Console.WriteLine("Извините, у меня нет " + selection) + End If + Console.ReadLine() + + End Sub + +End Module + +``` diff --git a/ru-ru/php-composer-ru.html.markdown b/ru-ru/php-composer-ru.html.markdown index ef6e4912..4bdf1029 100644 --- a/ru-ru/php-composer-ru.html.markdown +++ b/ru-ru/php-composer-ru.html.markdown @@ -2,24 +2,26 @@ category: tool tool: composer contributors: - - ["Alesey Lysenko", "https://github.com/nasgul"] + - ["Brett Taylor", "https://github.com/glutnix"] +translators: + - ["Aleksey Lysenko", "https://github.com/nasgul"] filename: LearnComposer-ru.sh lang: ru-ru --- -[Composer](https://getcomposer.org/) это инструмент управления зависимостями в PHP. +[Composer](https://getcomposer.org/) — это инструмент управления зависимостями в PHP. Он позволяет вам декларировать библиотеки, от которых зависит ваш проект, -и он будет управлять (устанавливать / обновлять) их для вас. +и он будет управлять ими, то есть устанавливать/обновлять их для вас. # Установка ```sh # Устанавливаем composer.phar в текущую папку curl -sS https://getcomposer.org/installer | php -# Если вы используете этот подход, вам нужно будет вызвать композер следующим образом: +# Если вы используете этот подход, вам нужно будет вызвать Composer следующим образом: php composer.phar about -# Устанавливаем с бинарников ~/bin/composer +# Устанавливаем бинарный файл в ~/bin/composer # Примечание: убедитесь, что ~/bin находится в переменной PATH вашего окружения curl -sS https://getcomposer.org/installer | php -- --install-dir=~/bin --filename=composer ``` @@ -30,58 +32,59 @@ curl -sS https://getcomposer.org/installer | php -- --install-dir=~/bin --filena ## Подтверждение установки ```sh -# # Проверить версию и параметры списка +# # Проверить версию и перечислить параметры composer # Получить дополнительную помощь для параметров composer help require -# Проверьте, способен ли Composer делать то, что ему нужно, и если он обновлен -композитор диагностирует +# Проверить, способен ли Composer делать то, что ему нужно, и обновлён ли он composer diagnose -composer diag # shorthand +composer diag # краткий вариант -# Обновление Composer к последней версии +# Обновление Composer до последней версии composer self-update -composer self # shorthand +composer self # краткий вариант ``` # Использование -Композитор сохраняет ваши зависимости проекта в `composer.json`. -Вы можете отредактировать этот файл, но лучше всего позволить Composer управлять им для вас. +Composer сохраняет ваши зависимости проекта в `composer.json`. +Вы можете отредактировать этот файл, но лучше всего позволить Composer управлять им за вас. ```sh # Создать новый проект в текущей папке composer init # запускается интерактивная анкета с просьбой предоставить подробную информацию о вашем проекте. -# Оставляя их пустым, все прекрасно, если вы не делаете другие проекты зависимыми от этого. +# Вы прекрасно можете оставить ответы пустыми, если не делаете другие проекты +# зависимыми от создаваемого проекта. # Если файл composer.json уже существует, загрузите зависимости composer install -# Чтобы загрузить только производственные зависимости, т. Е. Исключая зависимости разработки +# Чтобы загрузить только зависимости для готового продукта, т.е. +# исключая зависимости для разработки composer install --no-dev -# Добавить зависимость от этого проекта +# Добавить зависимость для готового продукта к этому проекту composer require guzzlehttp/guzzle -# выяснит, какая последняя версия guzzlehttp / guzzle есть, -# загрузите ее и добавьте новую зависимость в поле require.console. +# выяснит, какая существует последняя версия guzzlehttp / guzzle, +# загрузит её и добавит новую зависимость в поле require файла composer.json. composer require guzzlehttp/guzzle:6.0.* -# будет загружать последнюю версию, соответствующую шаблону (например, 6.0.2), -# и добавить зависимость к полю require.json +# Загрузит последнюю версию, соответствующую шаблону (например, 6.0.2), +# и добавит зависимость к полю require файла composer.json composer require --dev phpunit/phpunit:~4.5.0 -# потребуется как зависимость от разработки. +# Добавит как зависимость для разработки. # Будет использовать последнюю версию> = 4.5.0 и <4.6.0 composer require-dev phpunit/phpunit:^4.5.0 -# потребуется как зависимость от разработки. Будет использовать последнюю версию> = 4.5.0 и <5.0 +# Добавит как зависимость для разработки. +# Будет использовать последнюю версию> = 4.5.0 и <5.0 # Для получения дополнительной информации о совместимости версий Composer см. -# [Документация композитора по версиям] (https://getcomposer.org/doc/articles/versions.md) -# для получения более подробной информации +# [Документацию Composer по версиям] (https://getcomposer.org/doc/articles/versions.md) # Чтобы узнать, какие пакеты доступны для установки и в настоящее время установлены composer show @@ -89,36 +92,37 @@ composer show # Чтобы узнать, какие пакеты в настоящее время установлены composer show --installed -# Чтобы найти пакет с «mailgun» в его названии или описании +# Чтобы найти пакет со строкой «mailgun» в названии или описании composer search mailgun ``` [Packagist.org](https://packagist.org/) является основным хранилищем для пакетов Composer. -Поиск там для существующих сторонних пакетов. +Существующие сторонние пакеты ищите там. -## `composer.json` vs `composer.lock` +## composer.json` и `composer.lock` -Файл `composer.json` хранит ваши параметры плавающей версии вашего проекта для каждой зависимости, -а также другую информацию. +Файл `composer.json` хранит параметры допустимых версий каждой зависимости +вашего проекта, а также другую информацию. -Файл `composer.lock` хранит точно, какую версию он загрузил для каждой зависимости. +Файл `composer.lock` хранит точную загруженную версию каждой зависимости. Никогда не редактируйте этот файл. -Если вы включите файл `composer.lock` в свой репозиторий git, -каждый разработчик установит текущую версию зависимостей. -Даже когда выпущена новая версия зависимости, Composer продолжит загрузку версии, -записанной в файле блокировки. +Если вы включите файл `composer.lock` в свой Git-репозиторий, +каждый разработчик установит версии зависимостей, которые вы используете. +Даже когда будет выпущена новая версия зависимости, Composer продолжит загрузку версии, +записанной в lock-файле. ```sh -# Если вы хотите обновить все зависимости до их новейшей версии, -# которые по-прежнему соответствуют вашим предпочтениям в версии обновление композитора +# Если вы хотите обновить все зависимости до новейших версий, +# которые по-прежнему соответствуют вашим предпочтениям для версий composer update -# Если вам нужна новая версия определенной зависимости: +# Если вам нужна новая версия определённой зависимости: composer update phpunit/phpunit -# Если вы хотите перенести пакет на более новую версию, +# Если вы хотите перенести пакет на более новую версию +#с изменением предпочитаемой версии, # вам может потребоваться сначала удалить старый пакет и его зависимости. composer remove --dev phpunit/phpunit composer require --dev phpunit/phpunit:^5.0 @@ -126,8 +130,8 @@ composer require --dev phpunit/phpunit:^5.0 ## Автозагрузчик -Composer создает класс автозагрузки, который вы можете потребовать от своего приложения. -Вы можете создавать экземпляры классов через их пространство имен. +Composer создаёт класс автозагрузки, который вы можете вызвать +из своего приложения. Вы можете создавать экземпляры классов через пространство имён. ```php require __DIR__ . '/vendor/autoload.php'; @@ -135,15 +139,12 @@ require __DIR__ . '/vendor/autoload.php'; $mailgun = new Mailgun\Mailgun("key"); ``` -### PSR-4 Autoloader +### PSR-4-совместимый автозагрузчик -### Автозагрузчик PSR-4 -Вы можете добавить свои собственные пространства имен в автозагрузчик. +Вы можете добавить в автозагрузчик свои собственные пространства имён. -Вы можете добавить свои собственные пространства имен в автозагрузчик. - -В `composer.json` добавьте поле 'autoload': +Добавьте поле `autoload` в `composer.json`: ```json { @@ -152,31 +153,31 @@ $mailgun = new Mailgun\Mailgun("key"); } } ``` -Это скажет автозагрузчику искать что-либо в пространстве имен `\ Acme \` в папке `src`. +Это скажет автозагрузчику искать что-либо в пространстве имён `\Acme` в папке `src`. Вы также можете использовать -[PSR-0, Classmap или просто список файлов для включения](https://getcomposer.org/doc/04-schema.md#autoload). -Также существует поле `autoload-dev` для пространств имен, предназначенных только для разработки. +[PSR-0, карту классов или просто список файлов для включения](https://getcomposer.org/doc/04-schema.md#autoload). +Также существует поле `autoload-dev` для пространств имён, предназначенных только для разработки. При добавлении или изменении ключа автозагрузки вам необходимо перестроить автозагрузчик: ```sh composer dump-autoload -composer dump # shorthand +composer dump # краткий вариант -# Оптимизирует пакеты PSR0 и PSR4 для загрузки классов. -# Медленно запускается, но улучшает производительность при производстве. +# Оптимизирует пакеты PSR0 и PSR4 для загрузки классов с помощью карты классов. +# Медленно запускается, но улучшает производительность готового продукта. composer dump-autoload --optimize --no-dev ``` -# Composer Кэш +# Кэш Composer ```sh -# Composer сохранит загруженные пакеты для использования в будущем. Очистите его с помощью: +# Composer хранит загруженные пакеты для использования в будущем. Очистите кэш с помощью: composer clear-cache ``` -# Поиск проблемы +# Устранение неполадок ```sh composer diagnose @@ -184,13 +185,13 @@ composer self-update composer clear-cache ``` -## Темы, которые пока (пока) не включены в этот учебник +## Темы, которые ещё (пока) не включены в этот учебник -* Создание и распространение ваших собственных пакетов на Packagist.org или в другом месте +* Создание и распространение ваших собственных пакетов на Packagist.org или в другом репозитории * Предварительные и пост-скриптовые перехватчики: запуск задач, -когда происходят определенные события композитора +когда происходят определенные события Composer -### Рекомендации +### Ссылки * [Composer - Dependency Manager for PHP](https://getcomposer.org/) * [Packagist.org](https://packagist.org/) diff --git a/ru-ru/python-ru.html.markdown b/ru-ru/python-ru.html.markdown index 43142eff..6087a686 100644 --- a/ru-ru/python-ru.html.markdown +++ b/ru-ru/python-ru.html.markdown @@ -541,7 +541,7 @@ Human.grunt() #=> "*grunt*" # Вы можете импортировать модули import math -print(math.sqrt(16)) #=> 4 +print(math.sqrt(16)) #=> 4.0 # Вы можете импортировать отдельные функции модуля from math import ceil, floor diff --git a/ru-ru/yaml-ru.html.markdown b/ru-ru/yaml-ru.html.markdown new file mode 100644 index 00000000..6eb580d9 --- /dev/null +++ b/ru-ru/yaml-ru.html.markdown @@ -0,0 +1,189 @@ +--- +language: yaml +filename: learnyaml-ru.yaml +contributors: +- [Adam Brenecki, 'https://github.com/adambrenecki'] +- [Suhas SG, 'https://github.com/jargnar'] +translators: +- [Sergei Babin, 'https://github.com/serzn1'] +lang: ru-ru +--- + +YAML как язык сериализации данных предназначен прежде всего для использования людьми. + +Это строгое надмножество JSON с добавлением синтаксически значимых переносов строк и +отступов как в Python. Тем не менее, в отличие от Python, YAML запрещает +использование табов для отступов. + +```yaml +--- # начало документа + +# Комментарий в YAML выглядит как-то так. + +###################### +# Скалярные величины # +###################### + +# Наш корневой объект (который продолжается для всего документа) будет соответствовать +# типу map, который в свою очередь соответствует словарю, хешу или объекту в других языках. +key: value +another_key: Другое значение ключа. +a_number_value: 100 +scientific_notation: 1e+12 +# Число 1 будет интерпретировано как число, а не как логический тип. Если необходимо чтобы +# значение было интерпретировано как логическое, необходимо использовать true +boolean: true +null_value: null +key with spaces: value + +# Обратите внимание что строки используются без кавычек, но могут и с кавычками. +however: 'Строка заключенная в кавычки.' +'Ключ заключенный в кавычки.': "Полезно если нужно использовать ':' в вашем ключе." +single quotes: 'Содержит ''одну'' экранированную строку' +double quotes: "Содержит несколько: \", \0, \t, \u263A, \x0d\x0a == \r\n, экранированных строк." + +# Многострочные строковые значения могут быть записаны как 'строковый блок' (используя |), +# или как 'сложенный блок' (используя '>'). +literal_block: | + Значение всего текста в этом блоке будет присвоено ключу 'literal_block', + с сохранением переноса строк. + + Объявление продолжается до удаления отступа и выравнивания с ведущим отступом. + + Любые строки с большим отступом сохраняют остатки своего отступа - + эта строка будет содержать дополнительно 4 пробела. +folded_style: > + Весь блок этого тектса будет значением 'folded_style', но в данном случае + все символы новой строки будут заменены пробелами. + + Пустые строки будут преобразованы в перенос строки. + + Строки с дополнительными отступами сохраняют их переносы строк - + этот текст появится через 2 строки. + +################## +# Типы коллекций # +################## + +# Вложения используют отступы. Отступ в 2 пробела предпочтителен (но не обязателен). +a_nested_map: + key: value + another_key: Another Value + another_nested_map: + hello: hello + +# В словарях (maps) используются не только строковые значения ключей. +0.25: a float key + +# Ключи также могут быть сложными, например многострочными. +# Мы используем ? с последующим пробелом чтобы обозначить начало сложного ключа. +? | + Этот ключ + который содержит несколько строк +: и это его значение + +# YAML также разрешает соответствия между последовательностями со сложными ключами +# Некоторые парсеры могут выдать предупреждения или ошибку +# Пример +? - Manchester United + - Real Madrid +: [2001-01-01, 2002-02-02] + +# Последовательности (эквивалент списка или массива) выглядят как-то так +# (обратите внимание что знак '-' считается отступом): +a_sequence: + - Item 1 + - Item 2 + - 0.5 # последовательности могут содержать различные типы. + - Item 4 + - key: value + another_key: another_value + - + - Это последовательность + - внутри другой последовательности + - - - Объявления вложенных последовательностей + - могут быть сжаты + +# Поскольку YAML это надмножество JSON, вы можете использовать JSON-подобный +# синтаксис для словарей и последовательностей: +json_map: {"key": "value"} +json_seq: [3, 2, 1, "takeoff"] +в данном случае кавычки не обязательны: {key: [3, 2, 1, takeoff]} + +########################## +# Дополнительные функции # +########################## + +# В YAML есть удобная система так называемых 'якорей' (anchors), которые позволяют легко +# дублировать содержимое внутри документа. Оба ключа в примере будут иметь одинаковые значения: +anchored_content: &anchor_name Эта строка будет являться значением обоих ключей. +other_anchor: *anchor_name + +# Якоря могут использоваться для дублирования/наследования свойств +base: &base + name: Каждый будет иметь одинаковое имя + +# Регулярное выражение << называется ключом объединения независимо от типа языка. +# Он используется чтобы показать что все ключи одного или более словарей должны быть +# добавлены в текущий словарь. + +foo: &foo + <<: *base + age: 10 + +bar: &bar + <<: *base + age: 20 + +# foo и bar могли бы иметь имена: Каждый из них имеет аналогичное имя + +# В YAML есть теги (tags), которые используются для явного объявления типов. +explicit_string: !!str 0.5 +# В некоторых парсерах реализованы теги для конкретного языка, пример для Python +# пример сложного числового типа. +python_complex_number: !!python/complex 1+2j + +# Мы можем использовать сложные ключи с включенными в них тегами из определенного языка +? !!python/tuple [5, 7] +: Fifty Seven +# Могло бы быть {(5, 7): 'Fifty Seven'} в Python + +####################### +# Дополнительные типы # +####################### + +# Строки и числа не единственные величины которые может понять YAML. +# YAML также поддерживает даты и время в формате ISO. +datetime: 2001-12-15T02:59:43.1Z +datetime_with_spaces: 2001-12-14 21:59:43.10 -5 +date: 2002-12-14 + +# Тег !!binary показывает что эта строка является base64-закодированным +# представлением двоичного объекта. +gif_file: !!binary | + R0lGODlhDAAMAIQAAP//9/X17unp5WZmZgAAAOfn515eXvPz7Y6OjuDg4J+fn5 + OTk6enp56enmlpaWNjY6Ojo4SEhP/++f/++f/++f/++f/++f/++f/++f/++f/+ + +f/++f/++f/++f/++f/++SH+Dk1hZGUgd2l0aCBHSU1QACwAAAAADAAMAAAFLC + AgjoEwnuNAFOhpEMTRiggcz4BNJHrv/zCFcLiwMWYNG84BwwEeECcgggoBADs= + +# YAML может использовать объекты типа ассоциативных массивов (set), как представлено ниже: +set: + ? item1 + ? item2 + ? item3 +or: {item1, item2, item3} + +# Сеты (set) являются простыми эквивалентами словарей со значениями +# типа null; запись выше эквивалентна следующей: +set2: + item1: null + item2: null + item3: null + +... # конец документа +``` + +### Больше информации + ++ [YAML оффициальный вебсайт](http://yaml.org/) ++ [YAML онлайн валидатор](http://www.yamllint.com/) diff --git a/sl-si/asciidoc-sl.html.markdown b/sl-si/asciidoc-sl.html.markdown new file mode 100644 index 00000000..52f30fbd --- /dev/null +++ b/sl-si/asciidoc-sl.html.markdown @@ -0,0 +1,136 @@ +--- +language: asciidoc +contributors: + - ["Ryan Mavilia", "http://unoriginality.rocks/"] + - ["Abel Salgado Romero", "https://twitter.com/abelsromero"] +translators: + - ["Filip Štamcar", "https://github.com/filips123"] +lang: sl-si +filename: asciidoc-sl.md +--- + +AsciiDoc je označevalni jezik, ki je podoben Markdownu in ga je mogoče uporabiti za vse od knjig do spletnih dnevnikov. Jezik, ki ga je leta 2002 ustvaril Stuart Rackham, je preprost, vendar omogoča veliko prilagoditev. + +## Glava dokumenta + +Glave so neobvezne in ne smejo vsebovati praznih vrstic. Od vsebine jih mora ločiti vsaj ena prazna vrstica. + +### Naslov + +``` += Naslov dokumenta + +Prvi stavek dokumenta. +``` + +### Naslov in avtor + +``` += Naslov dokumenta +Ime Priimek <ime.priimek@learnxinyminutes.com> + +Prvi stavek dokumenta. +``` + +### Naslov in več avtorjev + +``` + += Naslov dokumenta +Ime Priimek <ime.priimek@learnxinyminutes.com>; Janez Novak <janez.novak@pirate.com> + +Prvi stavek dokumenta. +``` + +Vrstica za revizijo + +``` += Naslov dokumenta V1 +Janez Novak <janez.novak@pirate.com> +v1.0, 2016-01-13 + +Prvi stavek dokumenta. +``` + +## Odstavki + +``` +Za odstavke ne potrebujete nič posebnega. + +Da jih ločite, dodajte prazno črto med odstavki. + +Če želite ustvariti prazno vrstico, dodajte + +in ustvarili boste prelom vrstice! +``` + +## Oblikovanje besedila + +``` +_podčrtaj za pošvno_ +*zvezdice za krepko* +*_kombinacije za zabavo_* +`krativec za monospace` +`*krepki monospace*` +``` + +## Naslovi razdelkov + +``` += Stopnja 0 (samo za naslov dokumenta) + +== Stopnja 1 <h2> + +=== Stopnja 2 <h3> + +==== Stopnja 3 <h4> + +===== Stopnja 4 <h5> + +``` + +## Seznami + +Če želite ustvariti neoštevilčen seznam, uporabite zvezdice. + +``` +* foo +* bar +* baz +``` + +Če želite ustvaril oštevilčen seznam, uporabite pike. + +``` +. predmet 1 +. predmet 2 +. predmet 3 +``` + +Seznami lahko do petkrat gnezdite tako, da dodate dodatne zvezdice ali pike. + +``` +* foo 1 +** foo 2 +*** foo 3 +**** foo 4 +***** foo 5 + +. foo 1 +.. foo 2 +... foo 3 +.... foo 4 +..... foo 5 +``` + +## Nadaljnje branje + +Obstajata dve orodji za obdelavo AsciiDoc dokumentov: + +1. [AsciiDoc](http://asciidoc.org/): izvirna implementacija v Pythonu je na voljo v glavnih distribucijah Linuxa. Stabilen in trenutno v vzdrževalnem načinu. +2. [Asciidoctor](http://asciidoctor.org/): alternativna Ruby implementacija, uporabno tudi iz Java in JavaScript. Z aktivnim razvojem si prizadeva razširiti sintakso AsciiDoc z novimi funkcijami in izhodnimi formati. + +Naslednje povezave so povezane `Asciidoctor` implementacijo: + +* [Markdown - AsciiDoc syntax comparison](http://asciidoctor.org/docs/user-manual/#comparison-by-example): primerjava skupnih elementov Markdowna in AsciiDoca. +* [Getting started](http://asciidoctor.org/docs/#get-started-with-asciidoctor): namestitev in navodila, ki omogočajo enostavne dokumente. +* [Asciidoctor User Manual](http://asciidoctor.org/docs/user-manual/): popolni priročnik z enim dokumentom s sklicevanjem na sintakso, primeri in oridji za upodabljanje. diff --git a/smalltalk.html.markdown b/smalltalk.html.markdown index 87135cf4..ae7ecb0e 100644 --- a/smalltalk.html.markdown +++ b/smalltalk.html.markdown @@ -2,7 +2,7 @@ language: Smalltalk filename: smalltalk.st contributors: - - ["Jigyasa Grover", "https://github.com/jig08"] + - ["Jigyasa Grover", "https://github.com/jigyasa-grover"] - ["tim Rowledge", "tim@rowledge.org"] --- @@ -10,18 +10,19 @@ contributors: - Smalltalk was created as the language to underpin the "new world" of computing exemplified by "human–computer symbiosis." - It was designed and created in part for educational use, more so for constructionist learning, at the Learning Research Group (LRG) of Xerox PARC by Alan Kay, Dan Ingalls, Adele Goldberg, Ted Kaehler, Scott Wallace, and others during the 1970s. -Feedback highly appreciated! Reach me at [@jigyasa_grover](https://twitter.com/jigyasa_grover) or send me an e-mail at `grover.jigyasa1@gmail.com`. +`Feedback highly appreciated! Reach me at [@jigyasa_grover](https://twitter.com/jigyasa_grover) or send me an e-mail at grover.jigyasa1@gmail.com.` ## The Basics + ### Everything is an object Yes, everything. Integers are instances of one of the numeric classes. Classes are instances of the class Metaclass and are just as manipulable as any other object. All classes are part of a single class tree; no disjoint class trees. Stack frames are objects and can be manipulated, which is how the debugger works. There are no pointers into memory locations that you can dereference and mess with. ### Functions are not called; messages are sent to objects -Work is done by sending messages to objects, which decide how to respond to that message and run a method as a result, which eventually returns some object to the original message sending code. -The system knows the class of the object receiving a message and looks up the message in that class's list of methods. If it is not found, the lookup continues in the super class until either it is found or the root of the classes is reached and there is still no relevant method. -If a suitable method is found the code is run, and the same process keeps on going with all the methods sent by that method and so on forever. -If no suitable method is found an exception is raised, which typically results in a user interface notifier to tell the user that the message was not understood. It is entirely possible to catch the exception and do something to fix the problem, which might range from 'ignore it' to 'load some new packages for this class and try again'. -A method (more strictly an instance of the class CompiledMethod) is a chunk of Smalltalk code that has been compiled into bytecodes. Executing methods start at the beginning and return to the sender when a return is encountered (we use ^ to signify 'return the follwing object') or the end of the code is reached, in which case the current object running the code is returned. +- Work is done by sending messages to objects, which decide how to respond to that message and run a method as a result, which eventually returns some object to the original message sending code. +- The system knows the class of the object receiving a message and looks up the message in that class's list of methods. If it is not found, the lookup continues in the super class until either it is found or the root of the classes is reached and there is still no relevant method. +- If a suitable method is found the code is run, and the same process keeps on going with all the methods sent by that method and so on forever. +- If no suitable method is found an exception is raised, which typically results in a user interface notifier to tell the user that the message was not understood. It is entirely possible to catch the exception and do something to fix the problem, which might range from 'ignore it' to 'load some new packages for this class and try again'. +- A method (more strictly an instance of the class CompiledMethod) is a chunk of Smalltalk code that has been compiled into bytecodes. Executing methods start at the beginning and return to the sender when a return is encountered (we use ^ to signify 'return the follwing object') or the end of the code is reached, in which case the current object running the code is returned. ### Simple syntax Smalltalk has a simple syntax with very few rules. @@ -55,7 +56,9 @@ self size > 4 ifTrue: [^argumentObject sizeRelatingTo: self]. ``` Everything here except the `^` involves sending more messages. Event the `ifTrue:` that you might think is a language control structure is just Smalltalk code. + We start by sending `size` to `self`. `self` is the object currently running the code - so in this case it is the myObject we started with. `size` is a very common message that we might anticipate tells us something about how big an object is; you could look it up with the Smalltalk tools very simply. The result we get is then sent the message `>` with the plain old integer 4 (which is an object too; no strange primitive types to pollute the system here) and nobody should be surprised the `>` is a comparison that answers true or false. That boolean (which is actually a Boolean object in Smalltalk) is sent the message `ifTrue:` with the block of code between the `[]` as its argument; obvioulsy a true boolean might be expected to run that block of code and a false to ignore it. + If the block is run then we do some more message sending to the argument object and noting the `^` we return the answer back to our starting point and it gets assigned to `result`. If the block is ignored we seem to run out of code and so `self` is returned and assigned to `result`. ## Smalltalk quick reference cheat-sheet @@ -92,179 +95,178 @@ Taken from [Smalltalk Cheatsheet](http://www.angelfire.com/tx4/cus/notes/smallta #### Transcript: ``` -Transcript clear. "clear to transcript window" -Transcript show: 'Hello World'. "output string in transcript window" -Transcript nextPutAll: 'Hello World'. "output string in transcript window" -Transcript nextPut: $A. "output character in transcript window" -Transcript space. "output space character in transcript window" -Transcript tab. "output tab character in transcript window" -Transcript cr. "carriage return / linefeed" -'Hello' printOn: Transcript. "append print string into the window" -'Hello' storeOn: Transcript. "append store string into the window" -Transcript endEntry. "flush the output buffer" +Transcript clear. "clear to transcript window" +Transcript show: 'Hello World'. "output string in transcript window" +Transcript nextPutAll: 'Hello World'. "output string in transcript window" +Transcript nextPut: $A. "output character in transcript window" +Transcript space. "output space character in transcript window" +Transcript tab. "output tab character in transcript window" +Transcript cr. "carriage return / linefeed" +'Hello' printOn: Transcript. "append print string into the window" +'Hello' storeOn: Transcript. "append store string into the window" +Transcript endEntry. "flush the output buffer" ``` #### Assignment: ``` | x y | -x _ 4. "assignment (Squeak) <-" -x := 5. "assignment" -x := y := z := 6. "compound assignment" +x _ 4. "assignment (Squeak) <-" +x := 5. "assignment" +x := y := z := 6. "compound assignment" x := (y := 6) + 1. -x := Object new. "bind to allocated instance of a class" -x := 123 class. "discover the object class" -x := Integer superclass. "discover the superclass of a class" -x := Object allInstances. "get an array of all instances of a class" -x := Integer allSuperclasses. "get all superclasses of a class" -x := 1.2 hash. "hash value for object" -y := x copy. "copy object" -y := x shallowCopy. "copy object (not overridden)" -y := x deepCopy. "copy object and instance vars" -y := x veryDeepCopy. "complete tree copy using a dictionary" +x := Object new. "bind to allocated instance of a class" +x := 123 class. "discover the object class" +x := Integer superclass. "discover the superclass of a class" +x := Object allInstances. "get an array of all instances of a class" +x := Integer allSuperclasses. "get all superclasses of a class" +x := 1.2 hash. "hash value for object" +y := x copy. "copy object" +y := x shallowCopy. "copy object (not overridden)" +y := x deepCopy. "copy object and instance vars" +y := x veryDeepCopy. "complete tree copy using a dictionary" ``` #### Constants: ``` | b | -b := true. "true constant" -b := false. "false constant" -x := nil. "nil object constant" -x := 1. "integer constants" -x := 3.14. "float constants" -x := 2e-2. "fractional constants" -x := 16r0F. "hex constant". -x := -1. "negative constants" -x := 'Hello'. "string constant" -x := 'I''m here'. "single quote escape" -x := $A. "character constant" -x := $ . "character constant (space)" -x := #aSymbol. "symbol constants" -x := #(3 2 1). "array constants" -x := #('abc' 2 $a). "mixing of types allowed" +b := true. "true constant" +b := false. "false constant" +x := nil. "nil object constant" +x := 1. "integer constants" +x := 3.14. "float constants" +x := 2e-2. "fractional constants" +x := 16r0F. "hex constant". +x := -1. "negative constants" +x := 'Hello'. "string constant" +x := 'I''m here'. "single quote escape" +x := $A. "character constant" +x := $ . "character constant (space)" +x := #aSymbol. "symbol constants" +x := #(3 2 1). "array constants" +x := #('abc' 2 $a). "mixing of types allowed" ``` #### Booleans: ``` | b x y | x := 1. y := 2. -b := (x = y). "equals" -b := (x ~= y). "not equals" -b := (x == y). "identical" -b := (x ~~ y). "not identical" -b := (x > y). "greater than" -b := (x < y). "less than" -b := (x >= y). "greater than or equal" -b := (x <= y). "less than or equal" -b := b not. "boolean not" -b := (x < 5) & (y > 1). "boolean and" -b := (x < 5) | (y > 1). "boolean or" -b := (x < 5) and: [y > 1]. "boolean and (short-circuit)" -b := (x < 5) or: [y > 1]. "boolean or (short-circuit)" -b := (x < 5) eqv: (y > 1). "test if both true or both false" -b := (x < 5) xor: (y > 1). "test if one true and other false" -b := 5 between: 3 and: 12. "between (inclusive)" -b := 123 isKindOf: Number. "test if object is class or subclass of" -b := 123 isMemberOf: SmallInteger. "test if object is type of class" -b := 123 respondsTo: sqrt. "test if object responds to message" -b := x isNil. "test if object is nil" -b := x isZero. "test if number is zero" -b := x positive. "test if number is positive" -b := x strictlyPositive. "test if number is greater than zero" -b := x negative. "test if number is negative" -b := x even. "test if number is even" -b := x odd. "test if number is odd" -b := x isLiteral. "test if literal constant" -b := x isInteger. "test if object is integer" -b := x isFloat. "test if object is float" -b := x isNumber. "test if object is number" -b := $A isUppercase. "test if upper case character" -b := $A isLowercase. "test if lower case character" +b := (x = y). "equals" +b := (x ~= y). "not equals" +b := (x == y). "identical" +b := (x ~~ y). "not identical" +b := (x > y). "greater than" +b := (x < y). "less than" +b := (x >= y). "greater than or equal" +b := (x <= y). "less than or equal" +b := b not. "boolean not" +b := (x < 5) & (y > 1). "boolean and" +b := (x < 5) | (y > 1). "boolean or" +b := (x < 5) and: [y > 1]. "boolean and (short-circuit)" +b := (x < 5) or: [y > 1]. "boolean or (short-circuit)" +b := (x < 5) eqv: (y > 1). "test if both true or both false" +b := (x < 5) xor: (y > 1). "test if one true and other false" +b := 5 between: 3 and: 12. "between (inclusive)" +b := 123 isKindOf: Number. "test if object is class or subclass of" +b := 123 isMemberOf: SmallInteger. "test if object is type of class" +b := 123 respondsTo: sqrt. "test if object responds to message" +b := x isNil. "test if object is nil" +b := x isZero. "test if number is zero" +b := x positive. "test if number is positive" +b := x strictlyPositive. "test if number is greater than zero" +b := x negative. "test if number is negative" +b := x even. "test if number is even" +b := x odd. "test if number is odd" +b := x isLiteral. "test if literal constant" +b := x isInteger. "test if object is integer" +b := x isFloat. "test if object is float" +b := x isNumber. "test if object is number" +b := $A isUppercase. "test if upper case character" +b := $A isLowercase. "test if lower case character" ``` #### Arithmetic expressions: ``` | x | -x := 6 + 3. "addition" -x := 6 - 3. "subtraction" -x := 6 * 3. "multiplication" -x := 1 + 2 * 3. "evaluation always left to right (1 + 2) * 3" -x := 5 / 3. "division with fractional result" -x := 5.0 / 3.0. "division with float result" -x := 5.0 // 3.0. "integer divide" -x := 5.0 \\ 3.0. "integer remainder" -x := -5. "unary minus" -x := 5 sign. "numeric sign (1, -1 or 0)" -x := 5 negated. "negate receiver" -x := 1.2 integerPart. "integer part of number (1.0)" -x := 1.2 fractionPart. "fractional part of number (0.2)" -x := 5 reciprocal. "reciprocal function" -x := 6 * 3.1. "auto convert to float" -x := 5 squared. "square function" -x := 25 sqrt. "square root" -x := 5 raisedTo: 2. "power function" -x := 5 raisedToInteger: 2. "power function with integer" -x := 5 exp. "exponential" -x := -5 abs. "absolute value" -x := 3.99 rounded. "round" -x := 3.99 truncated. "truncate" -x := 3.99 roundTo: 1. "round to specified decimal places" -x := 3.99 truncateTo: 1. "truncate to specified decimal places" -x := 3.99 floor. "truncate" -x := 3.99 ceiling. "round up" -x := 5 factorial. "factorial" -x := -5 quo: 3. "integer divide rounded toward zero" -x := -5 rem: 3. "integer remainder rounded toward zero" -x := 28 gcd: 12. "greatest common denominator" -x := 28 lcm: 12. "least common multiple" -x := 100 ln. "natural logarithm" -x := 100 log. "base 10 logarithm" -x := 100 log: 10. "logarithm with specified base" -x := 100 floorLog: 10. "floor of the log" -x := 180 degreesToRadians. "convert degrees to radians" -x := 3.14 radiansToDegrees. "convert radians to degrees" -x := 0.7 sin. "sine" -x := 0.7 cos. "cosine" -x := 0.7 tan. "tangent" -x := 0.7 arcSin. "arcsine" -x := 0.7 arcCos. "arccosine" -x := 0.7 arcTan. "arctangent" -x := 10 max: 20. "get maximum of two numbers" -x := 10 min: 20. "get minimum of two numbers" -x := Float pi. "pi" -x := Float e. "exp constant" -x := Float infinity. "infinity" -x := Float nan. "not-a-number" -x := Random new next; yourself. x next. "random number stream (0.0 to 1.0)" -x := 100 atRandom. "quick random number" +x := 6 + 3. "addition" +x := 6 - 3. "subtraction" +x := 6 * 3. "multiplication" +x := 1 + 2 * 3. "evaluation always left to right (1 + 2) * 3" +x := 5 / 3. "division with fractional result" +x := 5.0 / 3.0. "division with float result" +x := 5.0 // 3.0. "integer divide" +x := 5.0 \\ 3.0. "integer remainder" +x := -5. "unary minus" +x := 5 sign. "numeric sign (1, -1 or 0)" +x := 5 negated. "negate receiver" +x := 1.2 integerPart. "integer part of number (1.0)" +x := 1.2 fractionPart. "fractional part of number (0.2)" +x := 5 reciprocal. "reciprocal function" +x := 6 * 3.1. "auto convert to float" +x := 5 squared. "square function" +x := 25 sqrt. "square root" +x := 5 raisedTo: 2. "power function" +x := 5 raisedToInteger: 2. "power function with integer" +x := 5 exp. "exponential" +x := -5 abs. "absolute value" +x := 3.99 rounded. "round" +x := 3.99 truncated. "truncate" +x := 3.99 roundTo: 1. "round to specified decimal places" +x := 3.99 truncateTo: 1. "truncate to specified decimal places" +x := 3.99 floor. "truncate" +x := 3.99 ceiling. "round up" +x := 5 factorial. "factorial" +x := -5 quo: 3. "integer divide rounded toward zero" +x := -5 rem: 3. "integer remainder rounded toward zero" +x := 28 gcd: 12. "greatest common denominator" +x := 28 lcm: 12. "least common multiple" +x := 100 ln. "natural logarithm" +x := 100 log. "base 10 logarithm" +x := 100 log: 10. "floor of the log" +x := 180 degreesToRadians. "convert degrees to radians" +x := 3.14 radiansToDegrees. "convert radians to degrees" +x := 0.7 sin. "sine" +x := 0.7 cos. "cosine" +x := 0.7 tan. "tangent" +x := 0.7 arcSin. "arcsine" +x := 0.7 arcCos. "arccosine" +x := 0.7 arcTan. "arctangent" +x := 10 max: 20. "get maximum of two numbers" +x := 10 min: 20. "get minimum of two numbers" +x := Float pi. "pi" +x := Float e. "exp constant" +x := Float infinity. "infinity" +x := Float nan. "not-a-number" +x := Random new next; yourself. x next. "random number stream (0.0 to 1.0)" +x := 100 atRandom. "quick random number" ``` #### Bitwise Manipulation: ``` | b x | -x := 16rFF bitAnd: 16r0F. "and bits" -x := 16rF0 bitOr: 16r0F. "or bits" -x := 16rFF bitXor: 16r0F. "xor bits" -x := 16rFF bitInvert. "invert bits" -x := 16r0F bitShift: 4. "left shift" -x := 16rF0 bitShift: -4. "right shift" -"x := 16r80 bitAt: 7." "bit at position (0|1) [!Squeak]" -x := 16r80 highbit. "position of highest bit set" -b := 16rFF allMask: 16r0F. "test if all bits set in mask set in receiver" -b := 16rFF anyMask: 16r0F. "test if any bits set in mask set in receiver" -b := 16rFF noMask: 16r0F. "test if all bits set in mask clear in receiver" +x := 16rFF bitAnd: 16r0F. "and bits" +x := 16rF0 bitOr: 16r0F. "or bits" +x := 16rFF bitXor: 16r0F. "xor bits" +x := 16rFF bitInvert. "invert bits" +x := 16r0F bitShift: 4. "left shift" +x := 16rF0 bitShift: -4. "right shift" +"x := 16r80 bitAt: 7." "bit at position (0|1) [!Squeak]" +x := 16r80 highbit. "position of highest bit set" +b := 16rFF allMask: 16r0F. "test if all bits set in mask set in receiver" +b := 16rFF anyMask: 16r0F. "test if any bits set in mask set in receiver" +b := 16rFF noMask: 16r0F. "test if all bits set in mask clear in receiver" ``` #### Conversion: ``` | x | -x := 3.99 asInteger. "convert number to integer (truncates in Squeak)" -x := 3.99 asFraction. "convert number to fraction" -x := 3 asFloat. "convert number to float" -x := 65 asCharacter. "convert integer to character" -x := $A asciiValue. "convert character to integer" -x := 3.99 printString. "convert object to string via printOn:" -x := 3.99 storeString. "convert object to string via storeOn:" -x := 15 radix: 16. "convert to string in given base" +x := 3.99 asInteger. "convert number to integer (truncates in Squeak)" +x := 3.99 asFraction. "convert number to fraction" +x := 3 asFloat. "convert number to float" +x := 65 asCharacter. "convert integer to character" +x := $A asciiValue. "convert character to integer" +x := 3.99 printString. "convert object to string via printOn:" +x := 3.99 storeString. "convert object to string via storeOn:" +x := 15 radix: 16. "convert to string in given base" x := 15 printStringBase: 16. x := 15 storeStringBase: 16. ``` @@ -284,6 +286,7 @@ x := 15 storeStringBase: 16. x := [ y := 1. z := 2. ]. x value. "simple block usage" x := [ :argOne :argTwo | argOne, ' and ' , argTwo.]. "set up block with argument passing" Transcript show: (x value: 'First' value: 'Second'); cr. "use block with argument passing" + "x := [ | z | z := 1.]. *** localvars not available in squeak blocks" ``` @@ -303,27 +306,31 @@ Transcript show: (x value: 'First' value: 'Second'); cr. "use block with argu ``` | x | -x := 2 sqrt. "unary message" -x := 2 raisedTo: 10. "keyword message" -x := 194 * 9. "binary message" -Transcript show: (194 * 9) printString; cr. "combination (chaining)" -x := 2 perform: #sqrt. "indirect method invocation" -Transcript "Cascading - send multiple messages to receiver" +x := 2 sqrt. "unary message" +x := 2 raisedTo: 10. "keyword message" +x := 194 * 9. "binary message" +Transcript show: (194 * 9) printString; cr. "combination (chaining)" +x := 2 perform: #sqrt. "indirect method invocation" +Transcript "Cascading - send multiple messages to receiver" show: 'hello '; show: 'world'; cr. -x := 3 + 2; * 100. "result=300. Sends message to same receiver (3)" +x := 3 + 2; * 100. "result=300. Sends message to same receiver (3)" ``` #### Conditional Statements: ``` | x | -x > 10 ifTrue: [Transcript show: 'ifTrue'; cr]. "if then" -x > 10 ifFalse: [Transcript show: 'ifFalse'; cr]. "if else" -x > 10 "if then else" +x > 10 ifTrue: [Transcript show: 'ifTrue'; cr]. "if then" +x > 10 ifFalse: [Transcript show: 'ifFalse'; cr]. "if else" + +"if then else" +x > 10 ifTrue: [Transcript show: 'ifTrue'; cr] ifFalse: [Transcript show: 'ifFalse'; cr]. -x > 10 "if else then" + +"if else then" +x > 10 ifFalse: [Transcript show: 'ifFalse'; cr] ifTrue: [Transcript show: 'ifTrue'; cr]. Transcript @@ -332,7 +339,9 @@ Transcript ifTrue: ['ifTrue'] ifFalse: ['ifFalse']); cr. -Transcript "nested if then else" + +"nested if then else" +Transcript show: (x > 10 ifTrue: [x > 5 @@ -340,7 +349,9 @@ Transcript "nested if then else ifFalse: ['B']] ifFalse: ['C']); cr. -switch := Dictionary new. "switch functionality" + +"switch functionality" +switch := Dictionary new. switch at: $A put: [Transcript show: 'Case A'; cr]. switch at: $B put: [Transcript show: 'Case B'; cr]. switch at: $C put: [Transcript show: 'Case C'; cr]. @@ -351,129 +362,129 @@ result := (switch at: $B) value. ``` | x y | x := 4. y := 1. -[x > 0] whileTrue: [x := x - 1. y := y * 2]. "while true loop" -[x >= 4] whileFalse: [x := x + 1. y := y * 2]. "while false loop" -x timesRepeat: [y := y * 2]. "times repeat loop (i := 1 to x)" -1 to: x do: [:a | y := y * 2]. "for loop" -1 to: x by: 2 do: [:a | y := y / 2]. "for loop with specified increment" -#(5 4 3) do: [:a | x := x + a]. "iterate over array elements" +[x > 0] whileTrue: [x := x - 1. y := y * 2]. "while true loop" +[x >= 4] whileFalse: [x := x + 1. y := y * 2]. "while false loop" +x timesRepeat: [y := y * 2]. "times repeat loop (i := 1 to x)" +1 to: x do: [:a | y := y * 2]. "for loop" +1 to: x by: 2 do: [:a | y := y / 2]. "for loop with specified increment" +#(5 4 3) do: [:a | x := x + a]. "iterate over array elements" ``` #### Character: ``` | x y | -x := $A. "character assignment" -y := x isLowercase. "test if lower case" -y := x isUppercase. "test if upper case" -y := x isLetter. "test if letter" -y := x isDigit. "test if digit" -y := x isAlphaNumeric. "test if alphanumeric" -y := x isSeparator. "test if separator char" -y := x isVowel. "test if vowel" -y := x digitValue. "convert to numeric digit value" -y := x asLowercase. "convert to lower case" -y := x asUppercase. "convert to upper case" -y := x asciiValue. "convert to numeric ascii value" -y := x asString. "convert to string" -b := $A <= $B. "comparison" +x := $A. "character assignment" +y := x isLowercase. "test if lower case" +y := x isUppercase. "test if upper case" +y := x isLetter. "test if letter" +y := x isDigit. "test if digit" +y := x isAlphaNumeric. "test if alphanumeric" +y := x isSeparator. "test if separator char" +y := x isVowel. "test if vowel" +y := x digitValue. "convert to numeric digit value" +y := x asLowercase. "convert to lower case" +y := x asUppercase. "convert to upper case" +y := x asciiValue. "convert to numeric ascii value" +y := x asString. "convert to string" +b := $A <= $B. "comparison" y := $A max: $B. ``` #### Symbol: ``` | b x y | -x := #Hello. "symbol assignment" -y := 'String', 'Concatenation'. "symbol concatenation (result is string)" -b := x isEmpty. "test if symbol is empty" -y := x size. "string size" -y := x at: 2. "char at location" -y := x copyFrom: 2 to: 4. "substring" -y := x indexOf: $e ifAbsent: [0]. "first position of character within string" -x do: [:a | Transcript show: a printString; cr]. "iterate over the string" -b := x conform: [:a | (a >= $a) & (a <= $z)]. "test if all elements meet condition" -y := x select: [:a | a > $a]. "return all elements that meet condition" -y := x asString. "convert symbol to string" -y := x asText. "convert symbol to text" -y := x asArray. "convert symbol to array" -y := x asOrderedCollection. "convert symbol to ordered collection" -y := x asSortedCollection. "convert symbol to sorted collection" -y := x asBag. "convert symbol to bag collection" -y := x asSet. "convert symbol to set collection" +x := #Hello. "symbol assignment" +y := 'String', 'Concatenation'. "symbol concatenation (result is string)" +b := x isEmpty. "test if symbol is empty" +y := x size. "string size" +y := x at: 2. "char at location" +y := x copyFrom: 2 to: 4. "substring" +y := x indexOf: $e ifAbsent: [0]. "first position of character within string" +x do: [:a | Transcript show: a printString; cr]. "iterate over the string" +b := x conform: [:a | (a >= $a) & (a <= $z)]. "test if all elements meet condition" +y := x select: [:a | a > $a]. "return all elements that meet condition" +y := x asString. "convert symbol to string" +y := x asText. "convert symbol to text" +y := x asArray. "convert symbol to array" +y := x asOrderedCollection. "convert symbol to ordered collection" +y := x asSortedCollection. "convert symbol to sorted collection" +y := x asBag. "convert symbol to bag collection" +y := x asSet. "convert symbol to set collection" ``` #### String: ``` | b x y | -x := 'This is a string'. "string assignment" -x := 'String', 'Concatenation'. "string concatenation" -b := x isEmpty. "test if string is empty" -y := x size. "string size" -y := x at: 2. "char at location" -y := x copyFrom: 2 to: 4. "substring" -y := x indexOf: $a ifAbsent: [0]. "first position of character within string" -x := String new: 4. "allocate string object" -x "set string elements" +x := 'This is a string'. "string assignment" +x := 'String', 'Concatenation'. "string concatenation" +b := x isEmpty. "test if string is empty" +y := x size. "string size" +y := x at: 2. "char at location" +y := x copyFrom: 2 to: 4. "substring" +y := x indexOf: $a ifAbsent: [0]. "first position of character within string" +x := String new: 4. "allocate string object" +x "set string elements" at: 1 put: $a; at: 2 put: $b; at: 3 put: $c; at: 4 put: $e. -x := String with: $a with: $b with: $c with: $d. "set up to 4 elements at a time" -x do: [:a | Transcript show: a printString; cr]. "iterate over the string" -b := x conform: [:a | (a >= $a) & (a <= $z)]. "test if all elements meet condition" -y := x select: [:a | a > $a]. "return all elements that meet condition" -y := x asSymbol. "convert string to symbol" -y := x asArray. "convert string to array" -x := 'ABCD' asByteArray. "convert string to byte array" -y := x asOrderedCollection. "convert string to ordered collection" -y := x asSortedCollection. "convert string to sorted collection" -y := x asBag. "convert string to bag collection" -y := x asSet. "convert string to set collection" -y := x shuffled. "randomly shuffle string" +x := String with: $a with: $b with: $c with: $d. "set up to 4 elements at a time" +x do: [:a | Transcript show: a printString; cr]. "iterate over the string" +b := x conform: [:a | (a >= $a) & (a <= $z)]. "test if all elements meet condition" +y := x select: [:a | a > $a]. "return all elements that meet condition" +y := x asSymbol. "convert string to symbol" +y := x asArray. "convert string to array" +x := 'ABCD' asByteArray. "convert string to byte array" +y := x asOrderedCollection. "convert string to ordered collection" +y := x asSortedCollection. "convert string to sorted collection" +y := x asBag. "convert string to bag collection" +y := x asSet. "convert string to set collection" +y := x shuffled. "randomly shuffle string" ``` #### Array: Fixed length collection - - ByteArray: Array limited to byte elements (0-255) - WordArray: Array limited to word elements (0-2^32) ``` | b x y sum max | -x := #(4 3 2 1). "constant array" -x := Array with: 5 with: 4 with: 3 with: 2. "create array with up to 4 elements" -x := Array new: 4. "allocate an array with specified size" -x "set array elements" +x := #(4 3 2 1). "constant array" +x := Array with: 5 with: 4 with: 3 with: 2. "create array with up to 4 elements" +x := Array new: 4. "allocate an array with specified size" +x "set array elements" at: 1 put: 5; at: 2 put: 4; at: 3 put: 3; at: 4 put: 2. -b := x isEmpty. "test if array is empty" -y := x size. "array size" -y := x at: 4. "get array element at index" -b := x includes: 3. "test if element is in array" -y := x copyFrom: 2 to: 4. "subarray" -y := x indexOf: 3 ifAbsent: [0]. "first position of element within array" -y := x occurrencesOf: 3. "number of times object in collection" -x do: [:a | Transcript show: a printString; cr]. "iterate over the array" -b := x conform: [:a | (a >= 1) & (a <= 4)]. "test if all elements meet condition" -y := x select: [:a | a > 2]. "return collection of elements that pass test" -y := x reject: [:a | a < 2]. "return collection of elements that fail test" -y := x collect: [:a | a + a]. "transform each element for new collection" -y := x detect: [:a | a > 3] ifNone: []. "find position of first element that passes test" -sum := 0. x do: [:a | sum := sum + a]. sum. "sum array elements" -sum := 0. 1 to: (x size) do: [:a | sum := sum + (x at: a)]. "sum array elements" -sum := x inject: 0 into: [:a :c | a + c]. "sum array elements" -max := x inject: 0 into: [:a :c | (a > c) "find max element in array" +b := x isEmpty. "test if array is empty" +y := x size. "array size" +y := x at: 4. "get array element at index" +b := x includes: 3. "test if element is in array" +y := x copyFrom: 2 to: 4. "subarray" +y := x indexOf: 3 ifAbsent: [0]. "first position of element within array" +y := x occurrencesOf: 3. "number of times object in collection" +x do: [:a | Transcript show: a printString; cr]. "iterate over the array" +b := x conform: [:a | (a >= 1) & (a <= 4)]. "test if all elements meet condition" +y := x select: [:a | a > 2]. "return collection of elements that pass test" +y := x reject: [:a | a < 2]. "return collection of elements that fail test" +y := x collect: [:a | a + a]. "transform each element for new collection" +y := x detect: [:a | a > 3] ifNone: []. "find position of first element that passes test" +sum := 0. x do: [:a | sum := sum + a]. sum. "sum array elements" +sum := 0. 1 to: (x size) + do: [:a | sum := sum + (x at: a)]. "sum array elements" +sum := x inject: 0 into: [:a :c | a + c]. "sum array elements" +max := x inject: 0 into: [:a :c | (a > c) "find max element in array" ifTrue: [a] ifFalse: [c]]. -y := x shuffled. "randomly shuffle collection" -y := x asArray. "convert to array" -"y := x asByteArray." "note: this instruction not available on Squeak" -y := x asWordArray. "convert to word array" -y := x asOrderedCollection. "convert to ordered collection" -y := x asSortedCollection. "convert to sorted collection" -y := x asBag. "convert to bag collection" -y := x asSet. "convert to set collection" +y := x shuffled. "randomly shuffle collection" +y := x asArray. "convert to array" +"y := x asByteArray." "note: this instruction not available on Squeak" +y := x asWordArray. "convert to word array" +y := x asOrderedCollection. "convert to ordered collection" +y := x asSortedCollection. "convert to sorted collection" +y := x asBag. "convert to bag collection" +y := x asSet. "convert to set collection" ``` #### OrderedCollection: @@ -481,44 +492,46 @@ acts like an expandable array ``` | b x y sum max | -x := OrderedCollection with: 4 with: 3 with: 2 with: 1. "create collection with up to 4 elements" -x := OrderedCollection new. "allocate collection" -x add: 3; add: 2; add: 1; add: 4; yourself. "add element to collection" -y := x addFirst: 5. "add element at beginning of collection" -y := x removeFirst. "remove first element in collection" -y := x addLast: 6. "add element at end of collection" -y := x removeLast. "remove last element in collection" -y := x addAll: #(7 8 9). "add multiple elements to collection" -y := x removeAll: #(7 8 9). "remove multiple elements from collection" -x at: 2 put: 3. "set element at index" -y := x remove: 5 ifAbsent: []. "remove element from collection" -b := x isEmpty. "test if empty" -y := x size. "number of elements" -y := x at: 2. "retrieve element at index" -y := x first. "retrieve first element in collection" -y := x last. "retrieve last element in collection" -b := x includes: 5. "test if element is in collection" -y := x copyFrom: 2 to: 3. "subcollection" -y := x indexOf: 3 ifAbsent: [0]. "first position of element within collection" -y := x occurrencesOf: 3. "number of times object in collection" -x do: [:a | Transcript show: a printString; cr]. "iterate over the collection" -b := x conform: [:a | (a >= 1) & (a <= 4)]. "test if all elements meet condition" -y := x select: [:a | a > 2]. "return collection of elements that pass test" -y := x reject: [:a | a < 2]. "return collection of elements that fail test" -y := x collect: [:a | a + a]. "transform each element for new collection" -y := x detect: [:a | a > 3] ifNone: []. "find position of first element that passes test" -sum := 0. x do: [:a | sum := sum + a]. sum. "sum elements" -sum := 0. 1 to: (x size) do: [:a | sum := sum + (x at: a)]. "sum elements" -sum := x inject: 0 into: [:a :c | a + c]. "sum elements" -max := x inject: 0 into: [:a :c | (a > c) "find max element in collection" +x := OrderedCollection + with: 4 with: 3 with: 2 with: 1. "create collection with up to 4 elements" +x := OrderedCollection new. "allocate collection" +x add: 3; add: 2; add: 1; add: 4; yourself. "add element to collection" +y := x addFirst: 5. "add element at beginning of collection" +y := x removeFirst. "remove first element in collection" +y := x addLast: 6. "add element at end of collection" +y := x removeLast. "remove last element in collection" +y := x addAll: #(7 8 9). "add multiple elements to collection" +y := x removeAll: #(7 8 9). "remove multiple elements from collection" +x at: 2 put: 3. "set element at index" +y := x remove: 5 ifAbsent: []. "remove element from collection" +b := x isEmpty. "test if empty" +y := x size. "number of elements" +y := x at: 2. "retrieve element at index" +y := x first. "retrieve first element in collection" +y := x last. "retrieve last element in collection" +b := x includes: 5. "test if element is in collection" +y := x copyFrom: 2 to: 3. "subcollection" +y := x indexOf: 3 ifAbsent: [0]. "first position of element within collection" +y := x occurrencesOf: 3. "number of times object in collection" +x do: [:a | Transcript show: a printString; cr]. "iterate over the collection" +b := x conform: [:a | (a >= 1) & (a <= 4)]. "test if all elements meet condition" +y := x select: [:a | a > 2]. "return collection of elements that pass test" +y := x reject: [:a | a < 2]. "return collection of elements that fail test" +y := x collect: [:a | a + a]. "transform each element for new collection" +y := x detect: [:a | a > 3] ifNone: []. "find position of first element that passes test" +sum := 0. x do: [:a | sum := sum + a]. sum. "sum elements" +sum := 0. 1 to: (x size) + do: [:a | sum := sum + (x at: a)]. "sum elements" +sum := x inject: 0 into: [:a :c | a + c]. "sum elements" +max := x inject: 0 into: [:a :c | (a > c) "find max element in collection" ifTrue: [a] ifFalse: [c]]. -y := x shuffled. "randomly shuffle collection" -y := x asArray. "convert to array" -y := x asOrderedCollection. "convert to ordered collection" -y := x asSortedCollection. "convert to sorted collection" -y := x asBag. "convert to bag collection" -y := x asSet. "convert to set collection" +y := x shuffled. "randomly shuffle collection" +y := x asArray. "convert to array" +y := x asOrderedCollection. "convert to ordered collection" +y := x asSortedCollection. "convert to sorted collection" +y := x asBag. "convert to bag collection" +y := x asSet. "convert to set collection" ``` #### SortedCollection: @@ -526,43 +539,45 @@ like OrderedCollection except order of elements determined by sorting criteria ``` | b x y sum max | -x := SortedCollection with: 4 with: 3 with: 2 with: 1. "create collection with up to 4 elements" -x := SortedCollection new. "allocate collection" -x := SortedCollection sortBlock: [:a :c | a > c]. "set sort criteria" -x add: 3; add: 2; add: 1; add: 4; yourself. "add element to collection" -y := x addFirst: 5. "add element at beginning of collection" -y := x removeFirst. "remove first element in collection" -y := x addLast: 6. "add element at end of collection" -y := x removeLast. "remove last element in collection" -y := x addAll: #(7 8 9). "add multiple elements to collection" -y := x removeAll: #(7 8 9). "remove multiple elements from collection" -y := x remove: 5 ifAbsent: []. "remove element from collection" -b := x isEmpty. "test if empty" -y := x size. "number of elements" -y := x at: 2. "retrieve element at index" -y := x first. "retrieve first element in collection" -y := x last. "retrieve last element in collection" -b := x includes: 4. "test if element is in collection" -y := x copyFrom: 2 to: 3. "subcollection" -y := x indexOf: 3 ifAbsent: [0]. "first position of element within collection" -y := x occurrencesOf: 3. "number of times object in collection" -x do: [:a | Transcript show: a printString; cr]. "iterate over the collection" -b := x conform: [:a | (a >= 1) & (a <= 4)]. "test if all elements meet condition" -y := x select: [:a | a > 2]. "return collection of elements that pass test" -y := x reject: [:a | a < 2]. "return collection of elements that fail test" -y := x collect: [:a | a + a]. "transform each element for new collection" -y := x detect: [:a | a > 3] ifNone: []. "find position of first element that passes test" -sum := 0. x do: [:a | sum := sum + a]. sum. "sum elements" -sum := 0. 1 to: (x size) do: [:a | sum := sum + (x at: a)]. "sum elements" -sum := x inject: 0 into: [:a :c | a + c]. "sum elements" -max := x inject: 0 into: [:a :c | (a > c) "find max element in collection" +x := SortedCollection + with: 4 with: 3 with: 2 with: 1. "create collection with up to 4 elements" +x := SortedCollection new. "allocate collection" +x := SortedCollection sortBlock: [:a :c | a > c]. "set sort criteria" +x add: 3; add: 2; add: 1; add: 4; yourself. "add element to collection" +y := x addFirst: 5. "add element at beginning of collection" +y := x removeFirst. "remove first element in collection" +y := x addLast: 6. "add element at end of collection" +y := x removeLast. "remove last element in collection" +y := x addAll: #(7 8 9). "add multiple elements to collection" +y := x removeAll: #(7 8 9). "remove multiple elements from collection" +y := x remove: 5 ifAbsent: []. "remove element from collection" +b := x isEmpty. "test if empty" +y := x size. "number of elements" +y := x at: 2. "retrieve element at index" +y := x first. "retrieve first element in collection" +y := x last. "retrieve last element in collection" +b := x includes: 4. "test if element is in collection" +y := x copyFrom: 2 to: 3. "subcollection" +y := x indexOf: 3 ifAbsent: [0]. "first position of element within collection" +y := x occurrencesOf: 3. "number of times object in collection" +x do: [:a | Transcript show: a printString; cr]. "iterate over the collection" +b := x conform: [:a | (a >= 1) & (a <= 4)]. "test if all elements meet condition" +y := x select: [:a | a > 2]. "return collection of elements that pass test" +y := x reject: [:a | a < 2]. "return collection of elements that fail test" +y := x collect: [:a | a + a]. "transform each element for new collection" +y := x detect: [:a | a > 3] ifNone: []. "find position of first element that passes test" +sum := 0. x do: [:a | sum := sum + a]. sum. "sum elements" +sum := 0. 1 to: (x size) + do: [:a | sum := sum + (x at: a)]. "sum elements" +sum := x inject: 0 into: [:a :c | a + c]. "sum elements" +max := x inject: 0 into: [:a :c | (a > c) "find max element in collection" ifTrue: [a] ifFalse: [c]]. -y := x asArray. "convert to array" -y := x asOrderedCollection. "convert to ordered collection" -y := x asSortedCollection. "convert to sorted collection" -y := x asBag. "convert to bag collection" -y := x asSet. "convert to set collection" +y := x asArray. "convert to array" +y := x asOrderedCollection. "convert to ordered collection" +y := x asSortedCollection. "convert to sorted collection" +y := x asBag. "convert to bag collection" +y := x asSet. "convert to set collection" ``` #### Bag: @@ -570,32 +585,32 @@ like OrderedCollection except elements are in no particular order ``` | b x y sum max | -x := Bag with: 4 with: 3 with: 2 with: 1. "create collection with up to 4 elements" -x := Bag new. "allocate collection" -x add: 4; add: 3; add: 1; add: 2; yourself. "add element to collection" -x add: 3 withOccurrences: 2. "add multiple copies to collection" -y := x addAll: #(7 8 9). "add multiple elements to collection" -y := x removeAll: #(7 8 9). "remove multiple elements from collection" -y := x remove: 4 ifAbsent: []. "remove element from collection" -b := x isEmpty. "test if empty" -y := x size. "number of elements" -b := x includes: 3. "test if element is in collection" -y := x occurrencesOf: 3. "number of times object in collection" -x do: [:a | Transcript show: a printString; cr]. "iterate over the collection" -b := x conform: [:a | (a >= 1) & (a <= 4)]. "test if all elements meet condition" -y := x select: [:a | a > 2]. "return collection of elements that pass test" -y := x reject: [:a | a < 2]. "return collection of elements that fail test" -y := x collect: [:a | a + a]. "transform each element for new collection" -y := x detect: [:a | a > 3] ifNone: []. "find position of first element that passes test" -sum := 0. x do: [:a | sum := sum + a]. sum. "sum elements" -sum := x inject: 0 into: [:a :c | a + c]. "sum elements" -max := x inject: 0 into: [:a :c | (a > c) "find max element in collection" +x := Bag with: 4 with: 3 with: 2 with: 1. "create collection with up to 4 elements" +x := Bag new. "allocate collection" +x add: 4; add: 3; add: 1; add: 2; yourself. "add element to collection" +x add: 3 withOccurrences: 2. "add multiple copies to collection" +y := x addAll: #(7 8 9). "add multiple elements to collection" +y := x removeAll: #(7 8 9). "remove multiple elements from collection" +y := x remove: 4 ifAbsent: []. "remove element from collection" +b := x isEmpty. "test if empty" +y := x size. "number of elements" +b := x includes: 3. "test if element is in collection" +y := x occurrencesOf: 3. "number of times object in collection" +x do: [:a | Transcript show: a printString; cr]. "iterate over the collection" +b := x conform: [:a | (a >= 1) & (a <= 4)]. "test if all elements meet condition" +y := x select: [:a | a > 2]. "return collection of elements that pass test" +y := x reject: [:a | a < 2]. "return collection of elements that fail test" +y := x collect: [:a | a + a]. "transform each element for new collection" +y := x detect: [:a | a > 3] ifNone: []. "find position of first element that passes test" +sum := 0. x do: [:a | sum := sum + a]. sum. "sum elements" +sum := x inject: 0 into: [:a :c | a + c]. "sum elements" +max := x inject: 0 into: [:a :c | (a > c) "find max element in collection" ifTrue: [a] ifFalse: [c]]. -y := x asOrderedCollection. "convert to ordered collection" -y := x asSortedCollection. "convert to sorted collection" -y := x asBag. "convert to bag collection" -y := x asSet. "convert to set collection" +y := x asOrderedCollection. "convert to ordered collection" +y := x asSortedCollection. "convert to sorted collection" +y := x asBag. "convert to bag collection" +y := x asSet. "convert to set collection" ``` #### Set: @@ -606,60 +621,61 @@ uses identity test (== rather than =) ``` | b x y sum max | -x := Set with: 4 with: 3 with: 2 with: 1. "create collection with up to 4 elements" -x := Set new. "allocate collection" -x add: 4; add: 3; add: 1; add: 2; yourself. "add element to collection" -y := x addAll: #(7 8 9). "add multiple elements to collection" -y := x removeAll: #(7 8 9). "remove multiple elements from collection" -y := x remove: 4 ifAbsent: []. "remove element from collection" -b := x isEmpty. "test if empty" -y := x size. "number of elements" -x includes: 4. "test if element is in collection" -x do: [:a | Transcript show: a printString; cr]. "iterate over the collection" -b := x conform: [:a | (a >= 1) & (a <= 4)]. "test if all elements meet condition" -y := x select: [:a | a > 2]. "return collection of elements that pass test" -y := x reject: [:a | a < 2]. "return collection of elements that fail test" -y := x collect: [:a | a + a]. "transform each element for new collection" -y := x detect: [:a | a > 3] ifNone: []. "find position of first element that passes test" -sum := 0. x do: [:a | sum := sum + a]. sum. "sum elements" -sum := x inject: 0 into: [:a :c | a + c]. "sum elements" -max := x inject: 0 into: [:a :c | (a > c) "find max element in collection" +x := Set with: 4 with: 3 with: 2 with: 1. "create collection with up to 4 elements" +x := Set new. "allocate collection" +x add: 4; add: 3; add: 1; add: 2; yourself. "add element to collection" +y := x addAll: #(7 8 9). "add multiple elements to collection" +y := x removeAll: #(7 8 9). "remove multiple elements from collection" +y := x remove: 4 ifAbsent: []. "remove element from collection" +b := x isEmpty. "test if empty" +y := x size. "number of elements" +x includes: 4. "test if element is in collection" +x do: [:a | Transcript show: a printString; cr]. "iterate over the collection" +b := x conform: [:a | (a >= 1) & (a <= 4)]. "test if all elements meet condition" +y := x select: [:a | a > 2]. "return collection of elements that pass test" +y := x reject: [:a | a < 2]. "return collection of elements that fail test" +y := x collect: [:a | a + a]. "transform each element for new collection" +y := x detect: [:a | a > 3] ifNone: []. "find position of first element that passes test" +sum := 0. x do: [:a | sum := sum + a]. sum. "sum elements" +sum := x inject: 0 into: [:a :c | a + c]. "sum elements" +max := x inject: 0 into: [:a :c | (a > c) "find max element in collection" ifTrue: [a] ifFalse: [c]]. -y := x asArray. "convert to array" -y := x asOrderedCollection. "convert to ordered collection" -y := x asSortedCollection. "convert to sorted collection" -y := x asBag. "convert to bag collection" -y := x asSet. "convert to set collection" +y := x asArray. "convert to array" +y := x asOrderedCollection. "convert to ordered collection" +y := x asSortedCollection. "convert to sorted collection" +y := x asBag. "convert to bag collection" +y := x asSet. "convert to set collection" ``` #### Interval: ``` | b x y sum max | -x := Interval from: 5 to: 10. "create interval object" +x := Interval from: 5 to: 10. "create interval object" x := 5 to: 10. -x := Interval from: 5 to: 10 by: 2. "create interval object with specified increment" +x := Interval from: 5 to: 10 by: 2. "create interval object with specified increment" x := 5 to: 10 by: 2. -b := x isEmpty. "test if empty" -y := x size. "number of elements" -x includes: 9. "test if element is in collection" -x do: [:k | Transcript show: k printString; cr]. "iterate over interval" -b := x conform: [:a | (a >= 1) & (a <= 4)]. "test if all elements meet condition" -y := x select: [:a | a > 7]. "return collection of elements that pass test" -y := x reject: [:a | a < 2]. "return collection of elements that fail test" -y := x collect: [:a | a + a]. "transform each element for new collection" -y := x detect: [:a | a > 3] ifNone: []. "find position of first element that passes test" -sum := 0. x do: [:a | sum := sum + a]. sum. "sum elements" -sum := 0. 1 to: (x size) do: [:a | sum := sum + (x at: a)]. "sum elements" -sum := x inject: 0 into: [:a :c | a + c]. "sum elements" -max := x inject: 0 into: [:a :c | (a > c) "find max element in collection" +b := x isEmpty. "test if empty" +y := x size. "number of elements" +x includes: 9. "test if element is in collection" +x do: [:k | Transcript show: k printString; cr]. "iterate over interval" +b := x conform: [:a | (a >= 1) & (a <= 4)]. "test if all elements meet condition" +y := x select: [:a | a > 7]. "return collection of elements that pass test" +y := x reject: [:a | a < 2]. "return collection of elements that fail test" +y := x collect: [:a | a + a]. "transform each element for new collection" +y := x detect: [:a | a > 3] ifNone: []. "find position of first element that passes test" +sum := 0. x do: [:a | sum := sum + a]. sum. "sum elements" +sum := 0. 1 to: (x size) + do: [:a | sum := sum + (x at: a)]. "sum elements" +sum := x inject: 0 into: [:a :c | a + c]. "sum elements" +max := x inject: 0 into: [:a :c | (a > c) "find max element in collection" ifTrue: [a] ifFalse: [c]]. -y := x asArray. "convert to array" -y := x asOrderedCollection. "convert to ordered collection" -y := x asSortedCollection. "convert to sorted collection" -y := x asBag. "convert to bag collection" -y := x asSet. "convert to set collection" +y := x asArray. "convert to array" +y := x asOrderedCollection. "convert to ordered collection" +y := x asSortedCollection. "convert to sorted collection" +y := x asBag. "convert to bag collection" +y := x asSet. "convert to set collection" ``` #### Associations: @@ -676,65 +692,68 @@ uses identity test (== rather than =) ``` | b x y | -x := Dictionary new. "allocate collection" -x add: #a->4; add: #b->3; add: #c->1; add: #d->2; yourself. "add element to collection" -x at: #e put: 3. "set element at index" -b := x isEmpty. "test if empty" -y := x size. "number of elements" -y := x at: #a ifAbsent: []. "retrieve element at index" -y := x keyAtValue: 3 ifAbsent: []. "retrieve key for given value with error block" -y := x removeKey: #e ifAbsent: []. "remove element from collection" -b := x includes: 3. "test if element is in values collection" -b := x includesKey: #a. "test if element is in keys collection" -y := x occurrencesOf: 3. "number of times object in collection" -y := x keys. "set of keys" -y := x values. "bag of values" +x := Dictionary new. "allocate collection" +x add: #a->4; + add: #b->3; + add: #c->1; + add: #d->2; yourself. "add element to collection" +x at: #e put: 3. "set element at index" +b := x isEmpty. "test if empty" +y := x size. "number of elements" +y := x at: #a ifAbsent: []. "retrieve element at index" +y := x keyAtValue: 3 ifAbsent: []. "retrieve key for given value with error block" +y := x removeKey: #e ifAbsent: []. "remove element from collection" +b := x includes: 3. "test if element is in values collection" +b := x includesKey: #a. "test if element is in keys collection" +y := x occurrencesOf: 3. "number of times object in collection" +y := x keys. "set of keys" +y := x values. "bag of values" x do: [:a | Transcript show: a printString; cr]. "iterate over the values collection" x keysDo: [:a | Transcript show: a printString; cr]. "iterate over the keys collection" x associationsDo: [:a | Transcript show: a printString; cr]."iterate over the associations" x keysAndValuesDo: [:aKey :aValue | Transcript "iterate over keys and values" show: aKey printString; space; show: aValue printString; cr]. -b := x conform: [:a | (a >= 1) & (a <= 4)]. "test if all elements meet condition" -y := x select: [:a | a > 2]. "return collection of elements that pass test" -y := x reject: [:a | a < 2]. "return collection of elements that fail test" -y := x collect: [:a | a + a]. "transform each element for new collection" -y := x detect: [:a | a > 3] ifNone: []. "find position of first element that passes test" -sum := 0. x do: [:a | sum := sum + a]. sum. "sum elements" -sum := x inject: 0 into: [:a :c | a + c]. "sum elements" -max := x inject: 0 into: [:a :c | (a > c) "find max element in collection" +b := x conform: [:a | (a >= 1) & (a <= 4)]. "test if all elements meet condition" +y := x select: [:a | a > 2]. "return collection of elements that pass test" +y := x reject: [:a | a < 2]. "return collection of elements that fail test" +y := x collect: [:a | a + a]. "transform each element for new collection" +y := x detect: [:a | a > 3] ifNone: []. "find position of first element that passes test" +sum := 0. x do: [:a | sum := sum + a]. sum. "sum elements" +sum := x inject: 0 into: [:a :c | a + c]. "sum elements" +max := x inject: 0 into: [:a :c | (a > c) "find max element in collection" ifTrue: [a] ifFalse: [c]]. -y := x asArray. "convert to array" -y := x asOrderedCollection. "convert to ordered collection" -y := x asSortedCollection. "convert to sorted collection" -y := x asBag. "convert to bag collection" -y := x asSet. "convert to set collection" - -Smalltalk at: #CMRGlobal put: 'CMR entry'. "put global in Smalltalk Dictionary" -x := Smalltalk at: #CMRGlobal. "read global from Smalltalk Dictionary" -Transcript show: (CMRGlobal printString). "entries are directly accessible by name" -Smalltalk keys do: [ :k | "print out all classes" +y := x asArray. "convert to array" +y := x asOrderedCollection. "convert to ordered collection" +y := x asSortedCollection. "convert to sorted collection" +y := x asBag. "convert to bag collection" +y := x asSet. "convert to set collection" + +Smalltalk at: #CMRGlobal put: 'CMR entry'. "put global in Smalltalk Dictionary" +x := Smalltalk at: #CMRGlobal. "read global from Smalltalk Dictionary" +Transcript show: (CMRGlobal printString). "entries are directly accessible by name" +Smalltalk keys do: [ :k | "print out all classes" ((Smalltalk at: k) isKindOf: Class) ifFalse: [Transcript show: k printString; cr]]. -Smalltalk at: #CMRDictionary put: (Dictionary new). "set up user defined dictionary" -CMRDictionary at: #MyVar1 put: 'hello1'. "put entry in dictionary" -CMRDictionary add: #MyVar2->'hello2'. "add entry to dictionary use key->value combo" -CMRDictionary size. "dictionary size" -CMRDictionary keys do: [ :k | "print out keys in dictionary" +Smalltalk at: #CMRDictionary put: (Dictionary new). "set up user defined dictionary" +CMRDictionary at: #MyVar1 put: 'hello1'. "put entry in dictionary" +CMRDictionary add: #MyVar2->'hello2'. "add entry to dictionary use key->value combo" +CMRDictionary size. "dictionary size" +CMRDictionary keys do: [ :k | "print out keys in dictionary" Transcript show: k printString; cr]. -CMRDictionary values do: [ :k | "print out values in dictionary" +CMRDictionary values do: [ :k | "print out values in dictionary" Transcript show: k printString; cr]. -CMRDictionary keysAndValuesDo: [:aKey :aValue | "print out keys and values" +CMRDictionary keysAndValuesDo: [:aKey :aValue | "print out keys and values" Transcript show: aKey printString; space; show: aValue printString; cr]. -CMRDictionary associationsDo: [:aKeyValue | "another iterator for printing key values" +CMRDictionary associationsDo: [:aKeyValue | "another iterator for printing key values" Transcript show: aKeyValue printString; cr]. -Smalltalk removeKey: #CMRGlobal ifAbsent: []. "remove entry from Smalltalk dictionary" -Smalltalk removeKey: #CMRDictionary ifAbsent: []. "remove user dictionary from Smalltalk dictionary" +Smalltalk removeKey: #CMRGlobal ifAbsent: []. "remove entry from Smalltalk dictionary" +Smalltalk removeKey: #CMRDictionary ifAbsent: []. "remove user dictionary from Smalltalk dictionary" ``` #### Internal Stream: @@ -742,8 +761,7 @@ Smalltalk removeKey: #CMRDictionary ifAbsent: []. "remove user diction | b x ios | ios := ReadStream on: 'Hello read stream'. ios := ReadStream on: 'Hello read stream' from: 1 to: 5. -[(x := ios nextLine) notNil] - whileTrue: [Transcript show: x; cr]. +[(x := ios nextLine) notNil] whileTrue: [Transcript show: x; cr]. ios position: 3. ios position. x := ios next. @@ -756,8 +774,7 @@ ios := ReadWriteStream on: 'Hello read stream' from: 1 to: 5. ios := ReadWriteStream with: 'Hello read stream'. ios := ReadWriteStream with: 'Hello read stream' from: 1 to: 10. ios position: 0. -[(x := ios nextLine) notNil] - whileTrue: [Transcript show: x; cr]. +[(x := ios nextLine) notNil] whileTrue: [Transcript show: x; cr]. ios position: 6. ios position. ios nextPutAll: 'Chris'. @@ -778,8 +795,7 @@ ios nextPutAll: 'Hello File'; cr. ios close. ios := FileStream oldFileNamed: 'ios.txt'. -[(x := ios nextLine) notNil] - whileTrue: [Transcript show: x; cr]. +[(x := ios nextLine) notNil] whileTrue: [Transcript show: x; cr]. ios position: 3. x := ios position. x := ios next. @@ -791,80 +807,80 @@ ios close. #### Date: ``` | x y | -x := Date today. "create date for today" -x := Date dateAndTimeNow. "create date from current time/date" -x := Date readFromString: '01/02/1999'. "create date from formatted string" -x := Date newDay: 12 month: #July year: 1999 "create date from parts" -x := Date fromDays: 36000. "create date from elapsed days since 1/1/1901" -y := Date dayOfWeek: #Monday. "day of week as int (1-7)" -y := Date indexOfMonth: #January. "month of year as int (1-12)" -y := Date daysInMonth: 2 forYear: 1996. "day of month as int (1-31)" -y := Date daysInYear: 1996. "days in year (365|366)" -y := Date nameOfDay: 1 "weekday name (#Monday,...)" -y := Date nameOfMonth: 1. "month name (#January,...)" -y := Date leapYear: 1996. "1 if leap year; 0 if not leap year" -y := x weekday. "day of week (#Monday,...)" -y := x previous: #Monday. "date for previous day of week" -y := x dayOfMonth. "day of month (1-31)" -y := x day. "day of year (1-366)" -y := x firstDayOfMonth. "day of year for first day of month" -y := x monthName. "month of year (#January,...)" -y := x monthIndex. "month of year (1-12)" -y := x daysInMonth. "days in month (1-31)" -y := x year. "year (19xx)" -y := x daysInYear. "days in year (365|366)" -y := x daysLeftInYear. "days left in year (364|365)" -y := x asSeconds. "seconds elapsed since 1/1/1901" -y := x addDays: 10. "add days to date object" -y := x subtractDays: 10. "subtract days to date object" -y := x subtractDate: (Date today). "subtract date (result in days)" -y := x printFormat: #(2 1 3 $/ 1 1). "print formatted date" -b := (x <= Date today). "comparison" +x := Date today. "create date for today" +x := Date dateAndTimeNow. "create date from current time/date" +x := Date readFromString: '01/02/1999'. "create date from formatted string" +x := Date newDay: 12 month: #July year: 1999 "create date from parts" +x := Date fromDays: 36000. "create date from elapsed days since 1/1/1901" +y := Date dayOfWeek: #Monday. "day of week as int (1-7)" +y := Date indexOfMonth: #January. "month of year as int (1-12)" +y := Date daysInMonth: 2 forYear: 1996. "day of month as int (1-31)" +y := Date daysInYear: 1996. "days in year (365|366)" +y := Date nameOfDay: 1 "weekday name (#Monday,...)" +y := Date nameOfMonth: 1. "month name (#January,...)" +y := Date leapYear: 1996. "1 if leap year; 0 if not leap year" +y := x weekday. "day of week (#Monday,...)" +y := x previous: #Monday. "date for previous day of week" +y := x dayOfMonth. "day of month (1-31)" +y := x day. "day of year (1-366)" +y := x firstDayOfMonth. "day of year for first day of month" +y := x monthName. "month of year (#January,...)" +y := x monthIndex. "month of year (1-12)" +y := x daysInMonth. "days in month (1-31)" +y := x year. "year (19xx)" +y := x daysInYear. "days in year (365|366)" +y := x daysLeftInYear. "days left in year (364|365)" +y := x asSeconds. "seconds elapsed since 1/1/1901" +y := x addDays: 10. "add days to date object" +y := x subtractDays: 10. "subtract days to date object" +y := x subtractDate: (Date today). "subtract date (result in days)" +y := x printFormat: #(2 1 3 $/ 1 1). "print formatted date" +b := (x <= Date today). "comparison" ``` #### Time: ``` | x y | -x := Time now. "create time from current time" -x := Time dateAndTimeNow. "create time from current time/date" -x := Time readFromString: '3:47:26 pm'. "create time from formatted string" -x := Time fromSeconds: (60 * 60 * 4). "create time from elapsed time from midnight" -y := Time millisecondClockValue. "milliseconds since midnight" -y := Time totalSeconds. "total seconds since 1/1/1901" -y := x seconds. "seconds past minute (0-59)" -y := x minutes. "minutes past hour (0-59)" -y := x hours. "hours past midnight (0-23)" -y := x addTime: (Time now). "add time to time object" -y := x subtractTime: (Time now). "subtract time to time object" -y := x asSeconds. "convert time to seconds" -x := Time millisecondsToRun: [ "timing facility" +x := Time now. "create time from current time" +x := Time dateAndTimeNow. "create time from current time/date" +x := Time readFromString: '3:47:26 pm'. "create time from formatted string" +x := Time fromSeconds: (60 * 60 * 4). "create time from elapsed time from midnight" +y := Time millisecondClockValue. "milliseconds since midnight" +y := Time totalSeconds. "total seconds since 1/1/1901" +y := x seconds. "seconds past minute (0-59)" +y := x minutes. "minutes past hour (0-59)" +y := x hours. "hours past midnight (0-23)" +y := x addTime: (Time now). "add time to time object" +y := x subtractTime: (Time now). "subtract time to time object" +y := x asSeconds. "convert time to seconds" +x := Time millisecondsToRun: [ "timing facility" 1 to: 1000 do: [:index | y := 3.14 * index]]. -b := (x <= Time now). "comparison" +b := (x <= Time now). "comparison" ``` #### Point: ``` | x y | -x := 200@100. "obtain a new point" -y := x x. "x coordinate" -y := x y. "y coordinate" -x := 200@100 negated. "negates x and y" -x := (-200@-100) abs. "absolute value of x and y" -x := (200.5@100.5) rounded. "round x and y" -x := (200.5@100.5) truncated. "truncate x and y" -x := 200@100 + 100. "add scale to both x and y" -x := 200@100 - 100. "subtract scale from both x and y" -x := 200@100 * 2. "multiply x and y by scale" -x := 200@100 / 2. "divide x and y by scale" -x := 200@100 // 2. "divide x and y by scale" -x := 200@100 \\ 3. "remainder of x and y by scale" -x := 200@100 + 50@25. "add points" -x := 200@100 - 50@25. "subtract points" -x := 200@100 * 3@4. "multiply points" -x := 200@100 // 3@4. "divide points" -x := 200@100 max: 50@200. "max x and y" -x := 200@100 min: 50@200. "min x and y" -x := 20@5 dotProduct: 10@2. "sum of product (x1*x2 + y1*y2)" +x := 200@100. "obtain a new point" +y := x x. "x coordinate" +y := x y. "y coordinate" +x := 200@100 negated. "negates x and y" +x := (-200@-100) abs. "absolute value of x and y" +x := (200.5@100.5) rounded. "round x and y" +x := (200.5@100.5) truncated. "truncate x and y" +x := 200@100 + 100. "add scale to both x and y" +x := 200@100 - 100. "subtract scale from both x and y" +x := 200@100 * 2. "multiply x and y by scale" +x := 200@100 / 2. "divide x and y by scale" +x := 200@100 // 2. "divide x and y by scale" +x := 200@100 \\ 3. "remainder of x and y by scale" +x := 200@100 + 50@25. "add points" +x := 200@100 - 50@25. "subtract points" +x := 200@100 * 3@4. "multiply points" +x := 200@100 // 3@4. "divide points" +x := 200@100 max: 50@200. "max x and y" +x := 200@100 min: 50@200. "min x and y" +x := 20@5 dotProduct: 10@2. "sum of product (x1*x2 + y1*y2)" ``` #### Rectangle: @@ -878,23 +894,24 @@ Rectangle fromUser. Display restoreAfter: [ Display fillWhite. -myPen := Pen new. "get graphic pen" +myPen := Pen new. "get graphic pen" myPen squareNib: 1. -myPen color: (Color blue). "set pen color" -myPen home. "position pen at center of display" -myPen up. "makes nib unable to draw" -myPen down. "enable the nib to draw" -myPen north. "points direction towards top" -myPen turn: -180. "add specified degrees to direction" -myPen direction. "get current angle of pen" -myPen go: 50. "move pen specified number of pixels" -myPen location. "get the pen position" -myPen goto: 200@200. "move to specified point" -myPen place: 250@250. "move to specified point without drawing" -myPen print: 'Hello World' withFont: (TextStyle default fontAt: 1). -Display extent. "get display width@height" -Display width. "get display width" -Display height. "get display height" +myPen color: (Color blue). "set pen color" +myPen home. "position pen at center of display" +myPen up. "makes nib unable to draw" +myPen down. "enable the nib to draw" +myPen north. "points direction towards top" +myPen turn: -180. "add specified degrees to direction" +myPen direction. "get current angle of pen" +myPen go: 50. "move pen specified number of pixels" +myPen location. "get the pen position" +myPen goto: 200@200. "move to specified point" +myPen place: 250@250. "move to specified point without drawing" +myPen print: 'Hello World' + withFont: (TextStyle default fontAt: 1). +Display extent. "get display width@height" +Display width. "get display width" +Display height. "get display height" ]. ``` @@ -902,6 +919,7 @@ Display height. "get display height" #### Dynamic Message Calling/Compiling: ``` | receiver message result argument keyword1 keyword2 argument1 argument2 | + "unary message" receiver := 5. message := 'factorial' asSymbol. @@ -923,11 +941,14 @@ keyword1 := 'between:' asSymbol. keyword2 := 'and:' asSymbol. argument1 := 10. argument2 := 20. + result := receiver perform: (keyword1, keyword2) asSymbol withArguments: (Array with: argument1 with: argument2). + result := Compiler evaluate: ((receiver storeString), ' ', keyword1, (argument1 storeString) , ' ', keyword2, (argument2 storeString)). + result := (Message new setSelector: (keyword1, keyword2) asSymbol @@ -935,67 +956,67 @@ result := (Message sentTo: receiver. ``` -#### Class/Meta-class: +#### Class/Meta-Class: ``` | b x | -x := String name. "class name" -x := String category. "organization category" -x := String comment. "class comment" -x := String kindOfSubclass. "subclass type - subclass: variableSubclass, etc" -x := String definition. "class definition" -x := String instVarNames. "immediate instance variable names" -x := String allInstVarNames. "accumulated instance variable names" -x := String classVarNames. "immediate class variable names" -x := String allClassVarNames. "accumulated class variable names" -x := String sharedPools. "immediate dictionaries used as shared pools" -x := String allSharedPools. "accumulated dictionaries used as shared pools" -x := String selectors. "message selectors for class" -x := String sourceCodeAt: #size. "source code for specified method" -x := String allInstances. "collection of all instances of class" -x := String superclass. "immediate superclass" -x := String allSuperclasses. "accumulated superclasses" -x := String withAllSuperclasses. "receiver class and accumulated superclasses" -x := String subclasses. "immediate subclasses" -x := String allSubclasses. "accumulated subclasses" -x := String withAllSubclasses. "receiver class and accumulated subclasses" -b := String instSize. "number of named instance variables" -b := String isFixed. "true if no indexed instance variables" -b := String isVariable. "true if has indexed instance variables" -b := String isPointers. "true if index instance vars contain objects" -b := String isBits. "true if index instance vars contain bytes/words" -b := String isBytes. "true if index instance vars contain bytes" -b := String isWords. "true if index instance vars contain words" -Object withAllSubclasses size. "get total number of class entries" +x := String name. "class name" +x := String category. "organization category" +x := String comment. "class comment" +x := String kindOfSubclass. "subclass type - subclass: variableSubclass, etc" +x := String definition. "class definition" +x := String instVarNames. "immediate instance variable names" +x := String allInstVarNames. "accumulated instance variable names" +x := String classVarNames. "immediate class variable names" +x := String allClassVarNames. "accumulated class variable names" +x := String sharedPools. "immediate dictionaries used as shared pools" +x := String allSharedPools. "accumulated dictionaries used as shared pools" +x := String selectors. "message selectors for class" +x := String sourceCodeAt: #size. "source code for specified method" +x := String allInstances. "collection of all instances of class" +x := String superclass. "immediate superclass" +x := String allSuperclasses. "accumulated superclasses" +x := String withAllSuperclasses. "receiver class and accumulated superclasses" +x := String subclasses. "immediate subclasses" +x := String allSubclasses. "accumulated subclasses" +x := String withAllSubclasses. "receiver class and accumulated subclasses" +b := String instSize. "number of named instance variables" +b := String isFixed. "true if no indexed instance variables" +b := String isVariable. "true if has indexed instance variables" +b := String isPointers. "true if index instance vars contain objects" +b := String isBits. "true if index instance vars contain bytes/words" +b := String isBytes. "true if index instance vars contain bytes" +b := String isWords. "true if index instance vars contain words" +Object withAllSubclasses size. "get total number of class entries" ``` #### Debugging: ``` | a b x | -x yourself. "returns receiver" -String browse. "browse specified class" -x inspect. "open object inspector window" +x yourself. "returns receiver" +String browse. "browse specified class" +x inspect. "open object inspector window" x confirm: 'Is this correct?'. -x halt. "breakpoint to open debugger window" +x halt. "breakpoint to open debugger window" x halt: 'Halt message'. x notify: 'Notify text'. -x error: 'Error string'. "open up error window with title" -x doesNotUnderstand: #cmrMessage. "flag message is not handled" -x shouldNotImplement. "flag message should not be implemented" -x subclassResponsibility. "flag message as abstract" -x errorImproperStore. "flag an improper store into indexable object" -x errorNonIntegerIndex. "flag only integers should be used as index" -x errorSubscriptBounds. "flag subscript out of bounds" -x primitiveFailed. "system primitive failed" - -a := 'A1'. b := 'B2'. a become: b. "switch two objects" +x error: 'Error string'. "open up error window with title" +x doesNotUnderstand: #cmrMessage. "flag message is not handled" +x shouldNotImplement. "flag message should not be implemented" +x subclassResponsibility. "flag message as abstract" +x errorImproperStore. "flag an improper store into indexable object" +x errorNonIntegerIndex. "flag only integers should be used as index" +x errorSubscriptBounds. "flag subscript out of bounds" +x primitiveFailed. "system primitive failed" + +a := 'A1'. b := 'B2'. a become: b. "switch two objects" Transcript show: a, b; cr. ``` -#### Misc +#### Miscellaneous ``` | x | -"Smalltalk condenseChanges." "compress the change file" -x := FillInTheBlank request: 'Prompt Me'. "prompt user for input" +"Smalltalk condenseChanges." "compress the change file" +x := FillInTheBlank request: 'Prompt Me'. "prompt user for input" Utilities openCommandKeyHelp ``` @@ -1016,7 +1037,7 @@ Most Smalltalks are either free as in OSS or have a free downloadable version wi * [Smalltalk-72 Manual](http://www.bitsavers.org/pdf/xerox/parc/techReports/Smalltalk-72_Instruction_Manual_Mar76.pdf) * [GNU Smalltalk User's Guide](https://www.gnu.org/software/smalltalk/manual/html_node/Tutorial.html) -#### Historical doc +#### Historical Documentation(s) * [BYTE: A Special issue on Smalltalk](https://archive.org/details/byte-magazine-1981-08) * [Smalltalk-72 Manual](http://www.bitsavers.org/pdf/xerox/parc/techReports/Smalltalk-72_Instruction_Manual_Mar76.pdf) * [Smalltalk, Objects, and Design](https://books.google.co.in/books?id=W8_Une9cbbgC&printsec=frontcover&dq=smalltalk&hl=en&sa=X&ved=0CCIQ6AEwAWoVChMIw63Vo6CpyAIV0HGOCh3S2Alf#v=onepage&q=smalltalk&f=false) diff --git a/solidity.html.markdown b/solidity.html.markdown index 4ff770eb..d215180d 100644 --- a/solidity.html.markdown +++ b/solidity.html.markdown @@ -5,6 +5,7 @@ contributors: - ["Nemil Dalal", "https://www.nemil.com"] - ["Joseph Chow", ""] - ["Bhoomtawath Plinsut", "https://github.com/varshard"] + - ["Shooter", "https://github.com/liushooter"] --- Solidity lets you program on [Ethereum](https://www.ethereum.org/), a @@ -237,7 +238,7 @@ uint x[][5]; // arr with 5 dynamic array elements (opp order of most languages) // Dictionaries (any type to any other type) mapping (string => uint) public balances; balances["charles"] = 1; -console.log(balances["ada"]); // is 0, all non-set key values return zeroes +// balances["ada"] result is 0, all non-set key values return zeroes // 'public' allows following from another contract contractName.balances("charles"); // returns 1 // 'public' created a getter (but not setter) like the following: @@ -403,8 +404,12 @@ event LogSent(address indexed from, address indexed to, uint amount); // note ca // Call LogSent(from, to, amount); -// For an external party (a contract or external entity), to watch using -// the Web3 Javascript library: +/** + +For an external party (a contract or external entity), to watch using +the Web3 Javascript library: + +// The following is Javascript code, not Solidity code Coin.LogSent().watch({}, '', function(error, result) { if (!error) { console.log("Coin transfer: " + result.args.amount + @@ -415,6 +420,8 @@ Coin.LogSent().watch({}, '', function(error, result) { "Receiver: " + Coin.balances.call(result.args.to)); } } +**/ + // Common paradigm for one contract to depend on another (e.g., a // contract that depends on current exchange rate provided by another) diff --git a/standard-ml.html.markdown b/standard-ml.html.markdown index b34f1c08..0ba42f39 100644 --- a/standard-ml.html.markdown +++ b/standard-ml.html.markdown @@ -272,6 +272,9 @@ fun evenly_positioned_elems (odd::even::xs) = even::evenly_positioned_elems xs datatype temp = C of real | F of real + +(* Declaring a new C temp value... + val t: temp = C 45.0 *) fun temp_to_f t = case t of diff --git a/stylus.html.markdown b/stylus.html.markdown new file mode 100644 index 00000000..1c5ddd32 --- /dev/null +++ b/stylus.html.markdown @@ -0,0 +1,228 @@ +--- +language: stylus +filename: learnStylus.styl +contributors: + - ["Salomão Neto", "https://github.com/salomaosnff"] + - ["Isaac Henrique", "https://github.com/Isaachi1"] +translators: + - ["Divay Prakash", "https://github.com/divayprakash"] +--- + +Stylus is a dynamic stylesheet preprocessor language that is compiled into CSS. It aims to add functionality to CSS without breaking compatibility across web browsers. +It does this using variables, nesting, mixins, functions and more. + +Stylus syntax is very flexible. You can use standard CSS syntax and leave the semicolon (;), colon (:) and even the ({) and (}) optional, making your code even more readable. + +Stylus does not provide new style options, but gives functionality that lets you make your CSS much more dynamic. + +```scss + +/* Code style +==============================*/ + +/* Keys, semicolon, and colon are optional in Stylus. */ + +body { + background: #000; +} + +body { + background: #000 +} + +body { + background #000 +} + +body + background #000 + +body + background: #000; + +body + background: #000 + +// Single-line comments are removed when Stylus is compiled into CSS. + +/* Multi-line comments are preserved. */ + + +/* Selectors +==============================*/ + +/* Selecting elements within another element */ +body { + background: #000000; + h1 { + color: #FF0000; + } +} + +/* Or if you prefer... */ +body + background #000000 + h1 + color #FF0000 + + +/* Getting parent element reference +==============================*/ +a { + color: #0088dd; + &:hover { + color: #DD8800; + } +} + + +/* Variables +==============================*/ + + +/* + You can store a CSS value (such as the color) of a variable. + Although it is optional, it is recommended to add $ before a variable name + so you can distinguish a variable from another CSS value. +*/ + +$primary-color = #A3A4FF +$secondary-color = #51527F +$body-font = 'Roboto', sans-serif + +/* You can use variables throughout your style sheet. +Now, if you want to change the color, you only have to make the change once. */ + +body + background-color $primary-color + color $secondary-color + font-family $body-font + +/* After compilation: */ +body { + background-color: #A3A4FF; + color: #51527F; + font-family: 'Roboto', sans-serif; +} + +/ * +This is much easier to maintain than having to change color +each time it appears throughout your style sheet. +* / + + +/* Mixins +==============================*/ + +/* If you find that you are writing the same code for more than one +element, you may want to store that code in a mixin. + +center() + display block + margin-left auto + margin-right auto + left 0 + right 0 + +/* Using the mixin */ +body { + center() + background-color: $primary-color +} + +/* After compilation: */ +div { + display: block; + margin-left: auto; + margin-right: auto; + left: 0; + right: 0; + background-color: #A3A4FF; +} + +/* You can use mixins to create a shorthand property. */ + +size($width, $height) + width $width + height $height + +.rectangle + size(100px, 60px) + +.square + size(40px, 40px) + +/* You can use a mixin as a CSS property. */ +circle($ratio) + width $ratio * 2 + height $ratio * 2 + border-radius $ratio + +.ball + circle 25px + + +/* Interpolation +==============================*/ + +vendor(prop, args) + -webkit-{prop} args + -moz-{prop} args + {prop} args + +border-radius() + vendor('border-radius', arguments) + +box-shadow() + vendor('box-shadow', arguments) + +button + border-radius 1px 2px / 3px 4px + + +/* Functions +==============================*/ + +/* Functions in Stylus allow you to perform a variety of tasks, such as recalling some data. */ + +body { + background darken(#0088DD, 50%) // Dim color #0088DD by 50% +} + +/* Creating your own function */ +add(a, b) + a + b + +body + padding add(10px, 5) + + +/* Conditions +==============================*/ +compare(a, b) + if a > b + bigger + else if a < b + smaller + else + equal + +compare(5, 2) // => bigger +compare(1, 5) // => smaller +compare(10, 10) // => equal + + +/* Iterations +==============================*/ + +/* +Repeat loop syntax for: +for <val-name> [, <key-name>] in <expression> +*/ + +for $item in (1..2) /* Repeat block 12 times */ + .col-{$item} + width ($item / 12) * 100% /* Calculate row by column number */ +``` + +Now that you know a little about this powerful CSS preprocessor, you're ready to create more dynamic style sheets. To learn more, visit the official stylus documentation at http://stylus-lang.com. diff --git a/tcsh.html.markdown b/tcsh.html.markdown index 80411ea6..e38b7a27 100644 --- a/tcsh.html.markdown +++ b/tcsh.html.markdown @@ -1,5 +1,6 @@ --- -language: tcsh +category: tool +tool: tcsh filename: LearnTCSH.csh contributors: - ["Nicholas Christopoulos", "https://github.com/nereusx"] diff --git a/th-th/pascal.th.html.markdown b/th-th/pascal.th.html.markdown new file mode 100644 index 00000000..05e37a28 --- /dev/null +++ b/th-th/pascal.th.html.markdown @@ -0,0 +1,236 @@ +--- +language: Pascal +filename: learnpascal.pas +contributors: + - ["Ganesha Danu", "http://github.com/blinfoldking"] + - ["Keith Miyake", "https://github.com/kaymmm"] +translator: + - ["Worajedt Sitthidumrong", "https://bitbucket.org/wrj"] +lang: th-th +--- + +> Pascal (ปาสกาล) เป็นภาษาโปรแกรมมิ่งทั้งแบบ imperative และ procedural ที่ออกแบบโดย Niklaus Wirth (นิเคล้า เวิร์ท) เมื่อปี 1968-69 และเผยแพร่ตอน 1970 โดยเน้นให้เป็นภาษาที่เล็ก มีประสิทธิภาพ เพื่อเสริมการเขียนโปรแกรมที่มีแนวปฏิบัติที่ดีด้วยการใช้โครงสร้างของตัวภาษา และโครงสร้างข้อมูลมากำกับ ชื่อของภาษานี้ตั้งเป็นเกียรติให้กับนักคณิตศาสตร์ชาวฝรั่งเศส, นักปรัชญา และนักฟิสิกส์ ชื่อ Blaise Pascal (เบลส ปาสกาล) ข้อมูลจาก : [วิกิพีเดีย][1] + +การคอมไพล์และรันโค้ดภาษาปาสกาลนี้ สามารถใช้ปาสกาลคอมไพลเลอร์ฟรีชื่อ Free Pascal ได้ โดย [ดาวน์โหลดที่นี่][2] + +ด้านล่างจะเป็นโครงสร้างภาษาหลัก ๆ ที่ต้องเข้าใจก่อน ปาสกาลจะเป็นภาษาที่เข้มงวดกับโครงสร้างโค้ดมาก + +```pascal +//โปรแกรมปาสกาล +//คอมเม้นต์เขียนแบบนี้ ใช้สแลชสองครั้ง +{ + แต่ถ้าต้องการคอมเม้นหลาย ๆ บรรทัด + ให้ใช้ วงเล็บปีกกา (curly brackets) + เนื้อหาอยู่บรรทัดเดียวกันกับปีกกาได้ +} + +//อย่างแรก ต้องประกาศ ชื่อโปรแกรม +program learn_pascal; //<-- ห้ามลืม semicolon + +const + { + ประกาศค่าคงที่ (constant) ในบล็อคนี้ + } +type + { + ประกาศชนิดข้อมูลของเราเองที่นี่ ไม่ว่าจะเป็น ชนิดข้อมูลทั่วไป + หรือจะเป็นคลาส + } +var + { + ตัวแปร ในภาษาปาสกาล ไม่เหมือนกับภาษาอื่น ๆ + เพราะต้องประกาศในบล็อค var ก่อนใช้งานเสมอ + } + +//มาถึงส่วนโปรแกรมหลัก หรือ main fucntion นั่นเอง +begin + { + โค้ดเราทำงานอะไร อย่างไร ก็เริ่มรันจากตรงนี้ + } +end. // จบการทำงานของ _โปรแกรม_ เราจะจบด้วย จุลภาค "." +``` + +โค้ดต่อจากนี้ จะเป็นการอธิบายประกาศตัวแปรของปาสกาล + +```pascal +//การประกาศตัวแปร ทำได้แบบนี้ +//var ชื่อตัวแปร : ชนิด ; +var a:integer; +var b:integer; + +//หรือแบบที่นิยมมากกว่า คือเอามาเก็บในบล็อค var ทั้งหมด +var + a : integer; + b : integer; + +//ถ้าจะเอาแบบสั้น ๆ บรรทัดเดียว ก็ทำได้ ทำได้พร้อมกันหลาย ๆ ตัวแปรด้วย +var a,b : integer; +``` + +โค้ดตัวอย่างนี้เป็นโปรแกรม Learn\_More ที่เป็นโครงสร้างโปรแกรมง่าย ๆ ที่จบสมบูรณ์หนึ่งโปรแกรม มีบล็อค program, const, type, main (Begin..End.) + +```pascal +program Learn_More; +// มาต่อเรื่อง ชนิดของข้อมูล (data types) และ ตัวดำเนินการ (operators) + +const + PI = 3.141592654; + GNU = 'GNU''s Not Unix'; + // ค่าคงที่ ให้ตั้งชื่อเป็น ตัวพิมพ์ใหญ่ ทั้งหมด ใช้กับชนิดข้อมูลใดๆ ก็ได้ + // ค่าคงที่ ก็ตามชื่อเลย กำหนดค่าแล้ว ไม่สามารถเปลี่ยนแปลงได้ขณะรัน + +// การประกาศชนิดข้อมูลของเราเอง +// "ชนิด" ของตัวแปรสองแบบนี้ จะนำไปใช้ด้านล่าง +type + ch_array : array [0..255] of char; + // อะเรย์ เป็นชนิดข้อมูลที่มี ความยาว/ช่องเก็บข้อมูล และ ชนิดข้อมูล + // โค้ดด้านบน เป็นการประกาศอะเรย์ของตัวอักษา 255 ตัวอักษา + // ซึ่งได้ ความยาว/ช่องเก็บข้อมูลในตัวแปรตัวนี้ 256 ช่องที่เป็นข้อความ + md_array : array of array of integer; + // ด้านบนนี้ เป็นตัวอย่าง อะเรย์สองมิติของเลขจำนวนเต็ม + // อะเรย์ ยังซ้อนกับอะเรย์ได้อีกด้วย ทำให้สร้าง อะเรย์หลายมิติได้ + // เรายังสามารถสร้าง อะเรย์ที่มีความยาวช่องเท่ากับศูนย์ (0) ได้อีกด้วย + // ซึ่งทำให้เกิด อะเรย์ที่จำนวนช่องยืดหยุ่นได้ (dymaically sized array) + +// การประกาศตัวแปร : ชื่อตัวแปรเหล่านี้จะนำไปใช้ด้านล่างต่อไป +var + int, c, d : integer; + // ประกาศในบล็อค var มีตัวแปรสามตัวเป็นอินทีเจอร์ + // ชนิดจำนวนเต็ม แบบ 16 bit มีช่วงข้อมูล [-32,768.. 32,767] + // »int« ในที่นี้เป็น "ชื่อตัวแปร" ที่ต้นฉบับตั้งให้สอดคล้องกับชนิดข้อมูล + // อย่าสับสนกับบางภาษาที่มีชนิด int ประกาศหน้าชื่อตัวแปร + r : real; + // ตัวแปร r เป็นชนิดเรียล (real) หรือเลขทศนิยม + // real มีช่วงข้อมูล [3.4E-38..3.4E38] + bool : boolean; + // ข้อมูลชนิดบูเลียน (boolean) มีค่าได้สองแบบ คือ True/False + ch : char; + // ตัวแปร ch เป็นชนิดตัวอักษร (ชาร์? คาร์?) หรือคาแรกเตอร์ + // ตัวอักษรเป็นแบบ ASCII 8 bit ดังนั้นจะไม่ใช่ UTF, Unicode + str : string; + // ตัวแปรสตริงจะเก็บข้อความ หรือ char หลาย ๆ ตัว + // ชนิดข้อมูลนี้ไม่เป็นมาตรฐานภาษาแต่คอมไพเลอร์ปาสกาลก็มักจะมีให้ + // ทั่ว ๆ ไปแล้ว จะเป็นอะเรย์ของ char ความยาวตั้งต้น 255 + s : string[50]; + // แบบนี้คือ กำหนดความยาว string เอง ให้เก็บ char 50 ตัว + // แบบนี้ก็ทำให้ประหยัดหน่วยความจำมากขึ้นนั่นเอง + my_str: ch_array; + // ชนิดตัวแปร ใช้เป็นชนิดที่เรากำหนดเองก็ได้ อย่างตอนนี้ + // ch_array เป็น "ชนิดข้อมูล" ที่เราสร้างขึ้นมาในบล็อค type + my_2d : md_array; + // ตัวแปรแบบอะเรย์ที่ไม่ประกาศขนาด (dynamically sized array) + // ก่อนเอาไปใช้จริงต้องระบุขนาดก่อนใช้เสมอ + + // ชนิดข้อมูลแบบ integer เพิ่มเติม + b : byte; // มีช่วงข้อมูล [0..255] + shi : shortint; // มีช่วงข้อมูล [-128..127] + smi : smallint; // มีช่วงข้อมูล [-32,768..32,767] (standard Integer) + w : word; // มีช่วงข้อมูล [0..65,535] + li : longint; // มีช่วงข้อมูล [-2,147,483,648..2,147,483,647] + lw : longword; // มีช่วงข้อมูล [0..4,294,967,295] + c : cardinal; // ก็คือ longword + i64 : int64; // มีช่วงข้อมูล + // [-9223372036854775808..9223372036854775807] + qw : qword; // มีช่วงข้อมูล [0..18,446,744,073,709,551,615] + + // ชนิดข้อมูลแบบ real เพิ่มเติม + rr : real; // มีช่วงข้อมูลที่ขึ้นกับระบบปฏิบัติการ + // (เช่นเป็นแบบ 8-bit, 16-bit, ฯลฯ) + rs : single; // มีช่วงข้อมูล [1.5E-45..3.4E38] + rd : double; // มีช่วงข้อมูล [5.0E-324 .. 1.7E308] + re : extended; // มีช่วงข้อมูล [1.9E-4932..1.1E4932] + rc : comp; // มีช่วงข้อมูล [-2E64+1 .. 2E63-1] + +Begin + // การกำหนดค่าตัวแปรให้ขณะประกาศ + int := 1; + r := 3.14; + ch := 'a'; // ใช้ single quote เหมือนกันทั้ง char และ string + str := 'apple'; + bool := true; + // ภาษาปาสกาล มอง "ชื่อเฉพาะ" แบบไม่สนพิมพ์ใหญ่พิมพ์เล็ก + // (case-insensitive language) + // ตัวดำเนินการแบบคณิตศาสตร์ (arithmethic operation) + int := 1 + 1; // int = 2 ซึ่งจะกำหนดทับค่าเดิมด้านบนที่เคยประกาศ + int := int + 1; // int = 2 + 1 = 3 นำค่าตอนนี้ (2) มา +1 ได้ 3 + int := 4 div 2; // int = 2 หารด้วย div จะได้ผลเป็น integer เสมอ + int := 3 div 2; // int = 1 + int := 1 div 2; // int = 0 + + bool := true or false; // bool = true + bool := false and true; // bool = false + bool := true xor true; // bool = false + + r := 3 / 2; // หารด้วย / จะได้ผลเป็น real เสมอ + r := int; // เรากำหนดค่า integer ให้ตัวแปร real ได้ + // แต่ทำกลับกัน โดยกำหนด real ให้ integer ไม่ได้ + + c := str[1]; // กำหนดค่าแรกใน array str ให้ตัวแปร c ที่เป็น char + str := 'hello' + 'world'; // เรารวม string เข้าด้วยกันด้วย + + + my_str[0] := 'a'; // กำหนดค่าให้ string เฉพาะตำแหน่งแบบอะเรย์ทั่วไป + + setlength(my_2d,10,10); // ปรับขนาดอะเรย์ 2 มิติให้เป็นขนาด 10x10 + // โดยตัวแปร my_2d นี้สร้างแล้วด้านบน + for c := 0 to 9 do // อะเรย์เริ่มจาก 0 และจบที่ ความยาว-1 + for d := 0 to 9 do // ตัวนับ (counter) จำเป็นต้องประกาศก่อนใช้ + my_2d[c,d] := c * d; + // กำหนดอะเรย์หลายมิติ ด้วยการใช้วงเล็บก้ามปู (square brackets) + +End. +// จบโปรแกรมบริบูรณ์ ด้วย "." +``` + +ด้านล่าง เป็นตัวอย่างการเขียนโปรแกรมปาสกาลชื่อ Functional\_Programming + +```pascal +program Functional_Programming; + +Var + i, dummy : integer; + +function factorial_recursion(const a: integer) : integer; +{ ทำการคำนวณแฟคทอเรียลซ้ำ ๆ ของเลขจำนวนเต็ม โดยผ่านพารามิเตอร์ a + ถ้าจะประกาศตัวแปรโลคอลในฟังก์ชั่น ก็ทำได้ โดยการใช้บล็อค var ภายในฟังก์ชั่น + เช่น : + var + local_a : integer; +} +Begin + If a >= 1 Then + { ฟังก์ชั่นนี้คืนค่ากลับ โดยการกำหนดค่าที่ผ่านทางพารามิเตอร์ a + นำมาคูณกับฟังก์ชั่นที่ผ่าน a-1 สุดท้ายก็กำหนดค่าลงไปให้กับฟังก์ชั่นตรงๆ } + factorial_recursion := a * factorial_recursion(a-1) + Else + factorial_recursion := 1; +End; // จบ ฟังก์ชั่น ด้วย ";" หลัง End ไม่เหมือนกับจบ โปรแกรม ที่จะใช้ "." + +procedure get_integer(var i : integer; dummy : integer); +{ เรารับ input จากผู้ใช้มาเก็บใน parameter i ที่เป็น integer ที่ตั้งขึ้นใน + พารามิเตอร์ โดยใช้ var ประกาศ ทำให้ค่าที่รับเข้ามาจะเปลี่ยนปรับได้จาก + ภายนอกการประกาศพารามิเตอร์นี้ ส่วน dummy เป็นตัวแปรที่ปรับเปลี่ยนได้ + "เฉพาะจากภายในฟังก์ชั่น,โพรซีเยอร์นั้น ๆ } +Begin + write('Enter an integer: '); + readln(i); + dummy := 4; // dummy จะไม่ทำให้ค่าที่ได้รับมาครั้งแรกใน main block เปลี่ยน +End; + +//--------------------// +// main program block +//--------------------// +Begin + dummy := 3; + get_integer(i, dummy); + writeln(i, '! = ', factorial_recursion(i)); + // พิมพ์ค่า i! + writeln('dummy = ', dummy); // จะให้ค่าเป็น '3' เสมอ + // เพราะจะไม่เปลี่ยนเนื่องด้วย + // การประกาศพารามิเตอร์ใน + // โพรซีเยอร์ get_integer ด้านบน +End. + +``` + +[1]: https://en.wikipedia.org/wiki/Pascal_(programming_language) +[2]: https://www.freepascal.org/ diff --git a/toml.html.markdown b/toml.html.markdown index 814e57e7..385a2437 100755 --- a/toml.html.markdown +++ b/toml.html.markdown @@ -32,7 +32,7 @@ boolean = true dateTime = 1979-05-27T07:32:00-08:00 scientificNotation = 1e+12 "key can be quoted" = true # Both " and ' are fine -"key may contains" = "letters, numbers, underscores, and dashes" +"key may contain" = "letters, numbers, underscores, and dashes" # A bare key must be non-empty, but an empty quoted key is allowed "" = "blank" # VALID but discouraged @@ -225,26 +225,26 @@ color = "gray" # sub-table will belong to the nearest table element above it. [[fruit]] - name = "apple" + name = "apple" # I am a property in fruit table/map - [fruit.Geometry] + [fruit.geometry] shape = "round" - note = "I am an fruit's property" + note = "I am a property in geometry table/map" [[fruit.color]] name = "red" - note = "I am an array's item in apple" + note = "I am an array item in apple fruit's table/map" [[fruit.color]] name = "green" - note = "I am in the same array than red" + note = "I am in the same array as red" [[fruit]] name = "banana" [[fruit.color]] name = "yellow" - note = "I am an array's item too but banana's one" + note = "I am an array item in banana fruit's table/map" ``` In JSON land, this code will be: diff --git a/tr-tr/clojure-tr.html.markdown b/tr-tr/clojure-tr.html.markdown new file mode 100644 index 00000000..64970945 --- /dev/null +++ b/tr-tr/clojure-tr.html.markdown @@ -0,0 +1,490 @@ +--- +language: clojure +lang: tr-tr +filename: learnclojure-tr.clj +contributors: + - ["Adam Bard", "http://adambard.com/"] +translators: + - ["Seçkin KÜKRER", "https://leavenha.github.io"] +--- + +[JVM]: https://tr.wikipedia.org/wiki/Java_sanal_makinesi +[STM]: https://en.wikipedia.org/wiki/Software_transactional_memory + +Clojure, Lisp dialekti, barınan bir dildir. [JVM][JVM] üzerinde barınıyor. Clojure, Lisp'in tüm gücü ve kendi mantalitesi ile mükemmel bir genel-amaçlı programlama dilidir. Clojure, Eş-zamanlı programlama, Makrolar, Fonksiyonel Programlama, Tembel yapılar ve daha fazlasını vaadediyor. + +(Bu örnekleri çalıştırmak için Clojure 1.2 versionu veya daha yenisine sahip olmalısınız.) + + +```clojure +; Noktalı Virgül, satırı yorumlamak için kullanılır. + +; Clojure programları formlardan meydana gelir, +; Parantezlerle çevirili değerler, boşluk ile ayrılır. --Virgül ile değil-- +; +; Clojure okuyucusu*, listedeki ilk elemanı çağırılacak bir fonksiyon +; Veya makro, geri kalan ifadeleri o çağırıma argüman olarak kabul eder. +; + +; Bir dosyadaki ilk çağırım isim-uzayı tanımlamak için `ns` olmalı. +(ns clojure-öğren) + +; +; Bir diğer yorumlama seçeneği de, ifade-içi. Bu diyez (`#`), ve alt çizgi +; İle başlar ve herhangi bir s-ifade'ye uygulanabilir. +; +#_(bu çağırım değerlendirilmeyecektir) + +; Öncelikle fonksiyon çağırımları ve temel işlemler: + +; Örnek bir fonksiyon çağırımı: +; (örnek-bir-fonksiyon ilk-argüman ikinci-argüman) + +; `str` aldığı argümanları bir karakter katarı olarak geri verir. +(str "Merhaba" " " "dünya!") ; => "Merhaba dünya!" + +; Matematik, oldukça sezgisel ve basit +(+ 1 1) ; => 2 +(- 2 1) ; => 1 +(* 1 2) ; => 2 +(/ 2 1) ; => 2 + +; Eşitlik için `=` +(= 1 1) ; => true +(= 2 1) ; => false + +; `not` beklediğiniz gibi, mantıksal ifadeleri tersine çevirir. +(not true) ; => false + +; Clojure formları, iç-içe çağırılabilir +; Değerlendirilen çağırımlar bir üst form'a argüman +; Olarak verilir. +(+ 1 (- 3 2)) ; = 1 + (3 - 2) => 2 + +; Tipler +;;;;;;;;;;;;; + +; Clojure, Java'nın temel tipleri olan mantıksal (boolean), +; Tam sayılar (int) ve karakter katarlarını (string) kullanır. +; Değerleri denetlemek için `class` fonksiyonunu kullanın. +(class 1) ; Tam sayı sabitleri ön-tanımlı olarak `java.lang.Long` ile tanımlanır. +(class 1.); Kayan noktalı sayı sabitleri +; Ön-tanımlı olarak `java.lang.Double` ile tanımlanır. +(class ""); Karakter katarı sabitleri her zaman, --sadece-- çift tırnak +; ile tanımlanır ve ön-tanımlı olarak `java.lang.String` tipindedir. +(class false) ; Mantıksal değer sabitleri, `java.lang.Boolean`. +(class nil); "Null", (tanımsız) değerler `nil` ile tanımlanır. + +; Clojure okuyucusu her paranter ifadesini bir çağırım olarak +; değerlendirdiğinden bir liste tanımlamak için çağırımı durdurmalıyız. +'(+ 1 2) ; => (+ 1 2) +; ((quote (+ 1 2)) için bir kısa yoldur) + +; Alıntılanmış listeleri çağırabilirsiniz. +(eval '(+ 1 2)) ; => 3 + +; Koleksiyonlar ve Ardışıklar +;;;;;;;;;;;;;;;;;;; + +; Listeler bağlı-liste veri yapısı, +; Vektörler dizi altyapısı kullanır. +(class '(1 2 3)); => clojure.lang.PersistentList +(class [1 2 3]); => clojure.lang.PersistentVector + +; Bir liste `(1 2 3)` şeklinde gösterilebilir, yazılabilir. +; Fakat bu listeyi, Alıntılamalıyız --Quote--. +; Bu, onu bir fonksiyon çağırımı olarak değil, +; bir liste olarak değerlendirilmesini sağlayacaktır. +; Ayrıca, `(list 1 2 3)` tamamen `'(1 2 3)` ifadesi ile +; eşdeğerdir. + +; 'Koleksiyonlar' sadece bir veri grubudur. +; Vektörler ve Listeler, koleksiyondur: +(coll? '(1 2 3)) ; => true +(coll? [1 2 3]) ; => true + +; 'Ardışıklar' (seqs), bir veri listesinin soyut tanımlamasıdır. +; Sadece listeler ardışıktır. +(seq? '(1 2 3)) ; => true +(seq? [1 2 3]) ; => false + +; Bir ardışık, ulaşıldığında sadece giriş verisi vermelidir. +; Yani, ardışıklar tembel olabilir. | Sonsuz ardışıklar tanımlanabilir. +(range 4) ; => (0 1 2 3) +(range) ; => (0 1 2 3 4 ...) (sonsuz bir ardışık) +(take 4 (range)) ; (0 1 2 3) + +; Bu yapılarda ekleme işlemi için `cons` kullanılır. +(cons 4 [1 2 3]) ; => (4 1 2 3) +(cons 4 '(1 2 3)) ; => (4 1 2 3) + +; `conj` bir koleksiyona en verimli şekilde veri ekler. +; Bu, listeler için liste başına, vektörler için ise vektör sonuna demektir. +(conj [1 2 3] 4) ; => [1 2 3 4] +(conj '(1 2 3) 4) ; => (4 1 2 3) + +; `concat` koleksiyonları birleştirmek için kullanılır. +(concat [1 2] '(3 4)) ; => (1 2 3 4) + +; `filter` ve `map` koleksiyonlarla işlem yapmak için +; ön-tanımlı yüksek-seviyeli fonksiyonlardır. +; +; ps: `inc` argümanını bir arttıran bir fonksiyon. +(map inc [1 2 3]) ; => (2 3 4) +(filter even? [1 2 3]) ; => (2) + +; Koleksiyonları indirgemek için `reduce` kullanılır. +(reduce + [1 2 3 4]) +; = (+ (+ (+ 1 2) 3) 4) +; => 10 + +; Reduce, bir ilk-tanım değeri alabilir. +(reduce conj [] '(3 2 1)) +; = (conj (conj (conj [] 3) 2) 1) +; => [3 2 1] + +; Fonksiyonlar +;;;;;;;;;;;;;;;;;;;;; + +; Yeni bir fonksiyon oluşturmak için `fn` kullanın. +; Bir fonksiyon her zaman son ifadesini döndürür. +(fn [] "Merhaba Dünya!") ; => fn + +; Fonksiyonu çağırmak için bir çift paranteze daha ihtiyaç var. +((fn [] "Merhaba Dünya!")) ; => "Merhaba Dünya!" + +; İsim uzayında bir değişken tanımlamak için `def` +; kullanılır. +(def x 1) +x ; => 1 + +; Bir değişkene fonksiyon değeri atamak için, +(def merhaba-dünya (fn [] "Merhaba Dünya!")) +(merhaba-dünya) ; => "Merhaba Dünya!" + +; Bu süreci, `defn` ile kısaltabiliriz. +(defn hello-world [] "Merhaba Dünya!") + +; `defn` fonksiyon çağırımındaki üçüncü eleman +; --vektör-- bir argüman listesidir. Fonksiyonun alacağı +; argümanları tanımlar. +(defn merhaba [isim] + (str "Merhaba " isim)) +(merhaba "Dünya!") ; => "Merhaba Dünya!" + +; Ayrıca, `#()` kısa yolunu, fonksiyon deklare etmek için +; kullanabiliriz. +(def merhaba2 #(str "Merhaba " %1)) +(merhaba2 "Dünya!") ; => "Merhaba Dünya!" + +; Çok düzeyli fonksiyonlar da tanımlanabilir, +(defn merhaba3 + ([] "Merhaba Dünya!") + ([isim] (str "Merhaba " isim))) +(merhaba3) ; => "Merhaba Dünya!" +(merhaba3 "A. NESİN!") ; => "Hello A. NESİN!" + +; Fonksiyonlar, belirsiz-sayıda argüman alabilir, +; ve bunları sizin için bir ardışıkta depolayabilir. +(defn argüman-sayısı [& argümanlarım] + (str "Verilen argüman sayısı:" (count argümanlarım) ", argümanlar: " argümanlarım)) +(argüman-sayısı "Öğün" "Çalış" "Güven") +; => "Verilen argüman sayısı:3, argümanlar: ("Öğün" "Çalış" "Güven")" + +; Elbette, sıradan ve belirsiz-sayılı fonksiyon argümanlarını +; harmanlayabilirsiniz. +(defn merhabalar [ev-sahibi & misafirler] + (str "Merhabalar, " misafirler ". Benim adım " ev-sahibi ".")) +(merhabalar "İklim" "Ayşe" "Fatma" "Nurdan") +; => "Merhabalar, (\"Ayşe\" \"Fatma\" \"Nurdan\"). Benim adım İklim." + + +; Eşlemeler +;;;;;;;;;; + +; Hash-Maps, Array-Maps +; Hash-Eşlemeleri ve Dizi-Eşlemeleri bir arayüzü paylaşırlar. +; Hash-Eşlemeleri daha hızlıdır, fakat anahtar sıralaması tutmazlar. +(class {:a 1 :b 2 :c 3}) ; => clojure.lang.PersistentArrayMap +(class (hash-map :a 1 :b 2 :c 3)) ; => clojure.lang.PersistentHashMap + +; Dizi-Eşlemeleri bir çok işlem sırasında otomatik olarak Hash-Eşlemelerine +; dönüşürler. Eğer yeterince büyürlerse, endişelenmenize gerek yoktur. + +; Eşlemeler anahtar değeri olarak herhangi hash-ifadesi (hashable) +; alabilirler. Ama çoğunlukla, bu iş için anahtar-kelimeler `keyword` +; kullanılır. +; Anahtar-kelimeler, karakter katarları gibidirler, fakat +; bir kaç artıları vardır. +(class :a) ; => clojure.lang.Keyword + +(def karakterkatarı-eşlemesi {"a" 1, "b" 2, "c" 3}) +karakterkatarı-eşlemesi ; => {"a" 1, "b" 2, "c" 3} + +(def anahtar-eşlemesi {:a 1, :b 2, :c 3}) +anahtar-eşlemesi ; => {:a 1, :c 3, :b 2} + +; Bu arada, virgüller her zaman boşluk olarak değerlendirilir +; ve etkisizdirler. + +; Bir eşlemeleden fonksiyon notasyonu ile değer çağırmak, +(karakterkatarı-eşlemesi "a") ; => 1 +(anahtar-eşlemesi :a) ; => 1 + +; Keyword tipleri kendi değerlerini argüman olarak aldıkları bir +; eşlemeden değer notasyonu ile çağırabilirler. +(:b anahtar-eşlemesi) ; => 2 + +; Bu notasyonu, bir karakter katarı ile denemeyiniz. +;("a" karakterkatarı-eşlemesi) +; => Exception: java.lang.String cannot be cast to clojure.lang.IFn + +; Verilmemiş bir değeri çağırmak, `nil` döndürecektir. +(karakterkatarı-eşlemesi "d") ; => nil + +; Eşlemelere yeni değerler eklemek için `assoc` kullanırız. +(def yeni-anahtar-eşlemesi (assoc anahtar-eşlemesi :d 4)) +yeni-anahtar-eşlemesi ; => {:a 1, :b 2, :c 3, :d 4} + +; Ama unutmayın, Clojure veri yapıları değişmezdir! +anahtar-eşlemesi ; => {:a 1, :b 2, :c 3} + +; Değer silmek için ise `dissoc` kullanılır. +(dissoc anahtar-eşlemesi :a :b) ; => {:c 3} + +; Kümeler +;;;;;; + +(class #{1 2 3}) ; => clojure.lang.PersistentHashSet +(set [1 2 3 1 2 3 3 2 1 3 2 1]) ; => #{1 2 3} + +; `conj` ile bir değer eklenir. +(conj #{1 2 3} 4) ; => #{1 2 3 4} + +; `disj` ile değer çıkarılır. +(disj #{1 2 3} 1) ; => #{2 3} + +; Fonksiyon notasyonu kümelerde de tanımlıdır. +; Kendi içlerinde değer arayan bir fonksiyon olarak +; kullanılabilirler. +(#{1 2 3} 1) ; => 1 +(#{1 2 3} 4) ; => nil + +; `clojure.sets` isim-uzayında daha fazla fonksiyon vardır. + +; Kullanışlı Formlar +;;;;;;;;;;;;;;;;; + +; Clojure için mantıksal yapılar bir özel-form'dur. +; Ve diğer fonksiyonlar gibi kullanılabilir. +; `if` fonksiyonunun ilk argümanı bir test ifadesidir. +(if true "ya şundadır" "ya bunda") ; => "ya şundadır" +; İkinci ifade doğru, üçüncü ifade ise yanlışsa ifadeleridir. +; Eğer test terimi doğru olarak değerlendirilirse, +; doğru ifadesi, yanlışsa yanlış ifadesi değerlendirilir ve döndürülür. +; +; Bir yanlışsa ifadesi yoksa `nil` döndürülür. +(if false "a") ; => nil + +; Yerel geçici-değişken tanımlamak için `let` kullanılır. +; İfadelerin varlığı `let` çağırımı ile sınırlıdır. +(let [a 1 b 2] + (> a b)) ; => false + +; İfade ve çağırımları `do` ile gruplayabilirsiniz. +; Çağırımların sonuncusu `do` ifadesinin değeri olarak +; döndürülecektir. +(do + (print "Selamlar!") + "Dünya!") ; => "Dünya!" (prints "Selamlar!") + +; Fonksiyonlar kapalı bir `do` ifadesi ile çevrelenmiştir. +(defn yazdır-ve-selamla! [isim] + (println "Merhaba, " isim "!") + (str "Merhaba, " isim "!")) +(yazdır-ve-selamla! "Zübeyde") ;=> "Merhaba, Zübeyde!" ("Merhaba, Zübeyde!" yazdırır.) + +; `let` ifadesi de kapalı bir `do` ile gelmektedir. +(let [isim "Ayten"] + (print "Merhabalar, " isim) + (str "Merhabalar, " isim)) ; => "Merhabalar, " ("Merhabalar, Ayten" yazdırır) + +; Sıralama-makroları (-> ve ->>) ile veri dönüşümünü daha temiz ifade +; edebilirsiniz. +; Bu makrolar ilk argümanı sonraki her çağırımın içine yerleştirir. +; +; `->` makrosu, ifadeyi çağırımların ilk argümanı olacak şekilde yerleştirir. +(-> + {:a 1 :b 2} + (assoc :c 3) ;=> (assoc {:a 1 :b 2} :c 3) + (dissoc :b)) + +; Bu ifade aşağıdaki şekilde yazılabilir: +; (dissoc (assoc {:a 1 :b 2} :c 3) :b) +; ve `{:a 1 :c 3}` olarak değer bulur. + +; Sondan-Sıralama-Makrosu (->>) ise aynı şeyi yapar, +; tek fark ise, ifadeyi, çağırımların son argümanı olarak yerleştirir. +; +(->> + (range 10) ;=> '(0 1 2 3 4 5 6 7 8 9) + (map inc) ;=> (map inc (range 10)) + (filter odd?) ;=> (filter odd? (map inc (range 10))) + (into [])) ;=> (into [] (filter odd? (map inc (range 10)))) + ; Sonuç: [1 3 5 7 9] + +; Bir ifadedeki önceki veri dönüşümlerinin sonucunu nereye +; koyacağınız konusunda daha fazla özgürlük istediğiniz bir durumda, +; Sıralama-Makrolarından daha özgür bi' şey kullanmak istersiniz; +; `as->` makrosu ile dönüşümlerin çıktısına bir isim atayabilir +; ve ardışık çağırımlarda yer tutucu olarak kullanabilirsiniz. + +(as-> [1 2 3] girdi + (map inc girdi);=> ifadeyi isterseniz çağırımın son argümanı olarak, + (nth girdi 2) ;=> veya çağırımın ilk argümanı olarak, + (conj [4 5 6] girdi [8 9 10])) ;=> ya da istediğiniz sırada kullanabilirsiniz. +;=> [4 5 6 4 [8 9 10]] + + + +; Modüller +;;;;;;;;;;;;;;; + +; `use` çağırdığınız modüldeki tüm tanımlara erişmenize olanak verir. +(use 'clojure.set) + +; Şu anda, küme fonksiyonlarını kullanabiliriz. +(intersection #{1 2 3} #{2 3 4}) ; => #{2 3} +(difference #{1 2 3} #{2 3 4}) ; => #{1} + +; Ayrıca eklenecek fonksiyonları seçebilirsiniz de: +(use '[clojure.set :only [intersection]]) + +; Bir modülü eklemek için `require` kullanılır. +(require 'clojure.string) + +; İsim-uzayı kapsamlı çağırımlar aşağıdaki şekildedir: +; isim-uzayı/fonksiyon-ismi --isim uzayı ismi ve fonksiyon ismi +; arasına eğik çizgi koymanız yeterli. +; Burada, modül `clojure.string` ve fonksiyon ismi `blank?` +(clojure.string/blank? "") ; => true + +; Ekleme sırasında, bir modüle takma-ad verilebilir. +(require '[clojure.string :as str]) +(str/replace "Bu bir özet metindir, test için kullanılabilir!" + #"[aeıioöuü]" str/upper-case) +; => "BU bIr ÖzEt mEtIndIr, tEst IçIn kUllAnIlAbIlIr!" +; (#"", burada düzenli ifadeler için bir sözdizimsel-şekerlemeyi ifade eder) + +; Bir isim-uzayı tanımlamasında `require` kullanılabilir. +; `ns` bir makrodur ve `require` (ve `use`, ama lütfen kullanmayın) +; dahil olmak üzere bir çok çağırım için işlevsellik sağlamaktadır. +; Bu notasyonu kullanırsanız, modüllerinizi alıntılamak zorunda kalmazsınız. +(ns test + (:require + [clojure.string :as str] + [clojure.set :as set])) + + +; Java +;;;;;;;;;;;;;;;;; + +; Java, kocaman ve kullanışlı bir standart kütüphaneye sahip, +; Clojure, Java etkileşimi ile, bundan yararlanabilirsiniz. + +; `import` diğer modüller gibi, bir java modülü de ele alabilir. +; Date, bir Java modülü. +(import java.util.Date) + +; `ns` çağırımında da kullanabilirsiniz. +(ns test + (:import java.util.Date + java.util.Calendar)) + +; Bir Java nesnesinden oluşturmak için `new` çağırımını kullanabilirsiniz. +(new Date) + +; Ayrıca Clojure Okuyucusu, size bunun daha farklı bir yolunu sunar: +; Sınıf isminin sonuna koyulacak bir nokta `.` ile +; bu yapılabilir. +(Date.) ; <bir tarih nesnesi> + +; `.` --nokta-- çağırımı, size nesnelerdeki metotlara erişme imkanı verir. +(. (new Date) getTime) ; <bir zaman-damgası> +(.getTime (Date.)) ; Üstteki ifade ile tamamen aynı sonucu verir. + +; Sınıf içindeki statik metotlara erişmek için `/` ayracını +; sınıf ile metot ismi birleştirmek için kullanabilirsiniz. +; (örnekSınıf/statikMetot) +(System/currentTimeMillis) ; <bir zaman-damgası> (`system` her zaman sunulur) + +; Sınıflarla işlem yaparken, `doto` bu süreci kolaylaştırabilir. +; İlk argüman sınıf nesnesi, sonraki her çağırım, nesne üzerinde yapılır. +(import java.util.Calendar) +(doto (Calendar/getInstance) + (.set 2000 1 1 0 0 0) ; => `set` metodu, `doto` ifadesine verilen + ; sınıf nesnesi üzerinde çağırılır. + .getTime) ; => Bir tarih nesnesi. set to 2000-01-01 00:00:00 + + +; STM +;;;;;;;;;;;;;;;;; + +; 'Software Transactional Memory' Clojure'un değişmez veri yapılarını +; ele alırken kullandığı bir mekanizmadır. Clojure içinde bunu kullanan +; birkaç yapı vardır. + +; Bir `atom` en basitidir. Bir ilkleme-değeri verin. +(def benim-atomum (atom {})) + +; Bir atomu güncellemek için `swap!` kullanılır. +; `swap!` fonksiyonu, ilk argüman olarak aldığı atomu, ikinci argüman +; olarak aldığı fonksiyona uygular. Bu fonksiyona ek argümanlar ise +; fonksiyondan sonra gelirler. +(swap! benim-atomum assoc :a 1) +; benim-atomum'un değerini (assoc {} :a 1) ifadesinin sonucu ile değiştirir. +(swap! benim-atomum assoc :b 2) +; benim-atomum'un değerini (assoc {:a 1} :b 2) ifadesinin sonucu ile değiştirir. + +; `deref` ile, atomun değerini çözümleyebilirsiniz. +benim-atomum ;=> Atom<#...> (Atom ifadesi döndürür) +@benim-atomum ; => {:a 1 :b 2} + +; İşte, `atom` kullanan basit bir sayaç. +(def sayaç (atom 0)) ;=> Şu anki isim uzayına, `sayaç` ile, 0 başlangıç +; değeri ile bir atom tanımladık. +(defn sayaç-arttır [benim-atomum] + (swap! sayaç inc)) ;=> Atom'un değerini bir arttır. + +(sayaç-arttır sayaç) +(sayaç-arttır sayaç) +(sayaç-arttır sayaç) +(sayaç-arttır sayaç) +(sayaç-arttır sayaç) +(sayaç-arttır sayaç) + +@sayaç ; => 6 + +; Diğer STM yapıları `ref`'ler ve `agent`'lar. +; Ref'ler: http://clojure.org/refs +; Agent'lar: http://clojure.org/agents +``` + +### Çevirim-içi içerikler + +Bu içerik, Rich Hickey'nin derin yazılım geliştirme anlayışına ve John McCarthy'nin vizyonu olan Lisp'in, Clojure'a miras verdiklerini anlamak için elbette yeterli değildir. Fakat fonksiyonel paradigma ve bu paradigmanın modern bir Lisp lehçesinde kullanımına göz kırpmış oldunuz. + +Clojure.org, bir çok içerik ve makale var. (İngilizce içerik): +[http://clojure.org/](http://clojure.org/) + +Clojuredocs.org, örneklerle bezenmiş Clojure dökümantasyonu: +[http://clojuredocs.org/quickref/Clojure%20Core](http://clojuredocs.org/quickref/Clojure%20Core) + +4Clojure, interaktif bir şekilde FP ve Clojure yeteneklerinizi geliştirmenize olanak veriyor: +[http://www.4clojure.com/](http://www.4clojure.com/) + +Clojure-doc.org, Başlangıç için bir içeriklere sahip: +[http://clojure-doc.org/](http://clojure-doc.org/) + +BraveClojure, bir başka clojure öğreten web sitesi: +[https://www.braveclojure.com/](https://www.braveclojure.com/) diff --git a/tr-tr/html-tr.html.markdown b/tr-tr/html-tr.html.markdown new file mode 100644 index 00000000..b4afe7df --- /dev/null +++ b/tr-tr/html-tr.html.markdown @@ -0,0 +1,157 @@ +--- +language: html +filename: learnhtml-tr.txt +contributors: + - ["Christophe THOMAS", "https://github.com/WinChris"] +translators: + - ["Kemal MUTLU", "https://github.com/kemtake"] + - ["Nuri Akman", "https://github.com/vedia"] +lang: tr-tr +--- + +HTML, HyperText Markup Language (Hiper Metin İşaretleme Dili) anlamına gelir. + +Web sayfaları yazmamızı sağlayan bir dildir. Bu işaretleme dili, metin ve verilerin nasıl gösterilmesi gerektiği kodlanarak web sayfaları yazmamızı sağlar. Aslında, html dosyaları basit metin dosyalarıdır. + +Bu işaretleme nedir? Sayfanın verilerini, açılış etiketleri ve kapanış etiketleri ile çevreleyerek düzenleme yöntemidir. Bu işaretleme, içerdiği metne anlam vermeyi sağlar. Diğer bilgisayar dillerinde olduğu gibi, HTML’nin birçok sürümü vardır. Burada HTML5 hakkında konuşacağız. + +**NOT :** Etkilerin nasıl çalıştıklarını anlamak, çıktılarını görebilmek için [codepen](https://codepen.io/) gibi bir siteden de faydalanabilirsiniz. Bu makale temel olarak HTML sözdizimi ve bazı yararlı ipuçlarıyla ilgilidir. + +```html +<!-- Yorumlar bu satır gibi eklenir! --> + +<!-- + Yorumlar + birden + fazla + satıra + yayılabilir! +--> + +<!-- #################### Başlık #################### --> + +<!-- İşte, analiz edeceğimiz örnek bir HTML dosyası. --> + + +<!doctype html> + <html> + <head> + <title>Benim Sitem</title> + </head> + <body> + <h1>Merhaba dünya!</h1> + <a href="http://codepen.io/anon/pen/xwjLbZ"> + Bunun ne olduğuna bir bak. + </a> + <p>Bu bir paragraftır.</p> + <p>Bu başka bir paragraf.</p> + <ul> + <li>Bu, numaralandırılmamış bir listede bulunan bir öğe/maddedir (madde imi)</li> + <li>Bu başka bir öğe</li> + <li>Ve bu listedeki son öğe </li> + </ul> + </body> + </html> + +<!-- +Bir HTML dosyası, tarayıcıya her zaman sayfanın HTML olduğunu belirterek başlar. +--> +<!doctype html> + +<!-- Bundan sonra, bir <html> etiketi açılarak başlar. --> +<html> + +<!-- dosyanın sonu </html> etiketi ile kapatılır. --> +</html> + +<!-- Sayfada, bu son etiketten sonra hiçbir şey bulunmamalıdır. --> + +<!-- Açılış ve kapanış etiketleri arasında (<html> </html>) şunları bulunur: --> + +<!-- <head> ile tanımlanan bir sayfa başlığu (bu, </head> ile kapatılmalıdır). --> +<!-- Baslik, gösterilmeyen bazi aciklamalar ve ek bilgiler icerir; buna üstveri denir. --> + +<head> + <!-- <title> etiketi, tarayıcıda gösterilecek başlığı gösterir. Pencerenin başlık çubuğu ve sekme adı.--> + <title>Benim Sitem</title> +</head> + +<!-- <head> bölümünden sonra, <body> etiketi gelir. --> +<!-- Bu noktaya kadar, tarif edilen hiçbir şey tarayıcı penceresinde görünmez. --> +<!-- <body> etiketinden sonra görüntülenecek içeriğe yer verilir. --> + +<body> + <!-- h1 etiketi bir başlık oluşturur. --> + <h1>Merhaba Dünya!</h1> + <!-- + Ayrıca başlıklar <h1> etiketinden <h6> etiketine kadar gidebilir. + <h1> etiketi en önemli, <h6> etiketi en düşük öncelikli başlığı yazmamızı sağlar. + --> + + <!-- href="" özniteliğine verilen URL'ye bir köprü oluşturur. --> + <a href="http://codepen.io/anon/pen/xwjLbZ"> + Bunun ne olduğuna bir bak. + </a> + + <!-- <p> etiketi, html sayfasına metin eklememize izin verir. --> + <p>Bu bir paragraftır.</p> + <p>Bu başka bir paragraf.</p> + + <!-- <ul> etiketi bir madde imi listesi oluşturur. --> + <!-- + Numaralandırılmış bir listeye sahip olmak için <ol> etiketi de kullanılabilir. Bu durumda 1. madde 2. madde vb. şekilde gider. + --> + <ul> + <li>Bu, numaralandırılmamış bir bir liste kalemidir (madde imi)</li> + <li>Bu başka bir öğe</li> + <li>Ve bu listedeki son öğe</li> + </ul> +</body> + +<!-- İşte bir html dosyası oluşturmak bu kadar basit. --> + +<!-- Ancak birçok farklı HTML etiketi türü de eklenebilir. --> + +<!-- <img /> etiketi bir resim eklemek için kullanılır. --> +<!-- +Resmin kaynağı, src = "" özniteliği kullanılarak belirtilir. +Kaynak, bir URL veya bilgisayarınızdaki bir dosyanın yolu olabilir. +--> +<img src="http://i.imgur.com/XWG0O.gif"/> + +<!-- HTML'de bir Tablo oluşturmak da mümkündür. --> + +<!-- Bir <table> elemanı açarız. --> +<table> + + <!-- <tr> bir satır oluşturmamızı sağlar. --> + <tr> + <!-- <th> tablo sütununa bir başlık vermemize izin verir. --> + <th>Birinci Başlık</th> + <th>İkinci Başlık</th> + </tr> + + <tr> + <!-- <td> bir tablo hücresi oluşturmamızı sağlar. --> + <td>ilk satırın, ilk hücresi (sutunu)</td> + <td>ilk satırın, ikinci hücresi (sutunu)</td> + </tr> + + <tr> + <td>ikinci satırın, ilk hücresi (sutunu) </td> + <td>ikinci satırın, ikinci hücresi (sutunu)</td> + </tr> +</table> + +``` + +## Kullanım + +HTML içeriği, .html veya .htm ile biten dosyalara yazılır. Mim türü text/html . +HTML olarak yazılmış dosyalar, `.html` veya `.htm` dosya uzantısına sahiptirler. mime type'ı ise `text/html` dir. + +## Daha fazla bilgi için + +* [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) diff --git a/tr-tr/python-tr.html.markdown b/tr-tr/python-tr.html.markdown index 01285080..99a3eb4e 100644 --- a/tr-tr/python-tr.html.markdown +++ b/tr-tr/python-tr.html.markdown @@ -458,7 +458,7 @@ Human.grunt() #=> "*grunt*" # Modülleri sayfaya dahil edebilirsiniz import math -print math.sqrt(16) #=> 4 +print math.sqrt(16) #=> 4.0 # Modül içerisinden spesifik bir fonksiyonu getirebilirsiniz from math import ceil, floor diff --git a/typescript.html.markdown b/typescript.html.markdown index 6feaca45..55d8cefe 100644 --- a/typescript.html.markdown +++ b/typescript.html.markdown @@ -203,8 +203,8 @@ p1.age = 25; // Error, p1.x is read-only var p2 = { name: "John", age: 60 }; var p3: Person = p2; // Ok, read-only alias for p2 -p3.x = 35; // Error, p3.x is read-only -p2.x = 45; // Ok, but also changes p3.x because of aliasing +p3.age = 35; // Error, p3.age is read-only +p2.age = 45; // Ok, but also changes p3.age because of aliasing class Car { readonly make: string; @@ -223,6 +223,30 @@ moreNumbers[5] = 5; // Error, elements are read-only moreNumbers.push(5); // Error, no push method (because it mutates array) moreNumbers.length = 3; // Error, length is read-only numbers = moreNumbers; // Error, mutating methods are missing + +// Iterators and Generators + +// for..of statement +// iterate over the list of values on the object being iterated +let arrayOfAnyType = [1, "string", false]; +for (const val of arrayOfAnyType) { + console.log(val); // 1, "string", false +} + +let list = [4, 5, 6]; +for (const i of list) { + console.log(i); // "4", "5", "6" +} + +// for..in statement +// iterate over the list of keys on the object being iterated +for (const i in list) { + console.log(i); // "0", "1", "2", +} + + + + ``` ## Further Reading diff --git a/uk-ua/python-ua.html.markdown b/uk-ua/python-ua.html.markdown index 2406678d..23bc1796 100644 --- a/uk-ua/python-ua.html.markdown +++ b/uk-ua/python-ua.html.markdown @@ -654,7 +654,7 @@ i.age # => виникає помилка атрибуту # Ви можете імпортувати модулі import math -print(math.sqrt(16)) # => 4 +print(math.sqrt(16)) # => 4.0 # Ви можете імпортувати окремі функції з модуля from math import ceil, floor diff --git a/vim.html.markdown b/vim.html.markdown index 0eb2c37e..5b84a3ea 100644 --- a/vim.html.markdown +++ b/vim.html.markdown @@ -94,10 +94,10 @@ that aims to make getting started with vim more approachable! Vim is based on the concept on **modes**. -Command Mode - vim starts up in this mode, used to navigate and write commands -Insert Mode - used to make changes in your file -Visual Mode - used to highlight text and do operations to them -Ex Mode - used to drop down to the bottom with the ':' prompt to enter commands +- Command Mode - vim starts up in this mode, used to navigate and write commands +- Insert Mode - used to make changes in your file +- Visual Mode - used to highlight text and do operations to them +- Ex Mode - used to drop down to the bottom with the ':' prompt to enter commands ``` i # Puts vim into insert mode, before the cursor position @@ -122,9 +122,9 @@ Ex Mode - used to drop down to the bottom with the ':' prompt to enter comm Vim can be thought of as a set of commands in a 'Verb-Modifier-Noun' format, where: -Verb - your action -Modifier - how you're doing your action -Noun - the object on which your action acts on +- Verb - your action +- Modifier - how you're doing your action +- Noun - the object on which your action acts on A few important examples of 'Verbs', 'Modifiers', and 'Nouns': diff --git a/visualbasic.html.markdown b/visualbasic.html.markdown index 63f224b7..221c1eb3 100644 --- a/visualbasic.html.markdown +++ b/visualbasic.html.markdown @@ -139,7 +139,7 @@ Module Module1 'Five Private Sub WorkingCalculator() - Console.Title = "The Working Calculator| Learn X in Y Minutes" + Console.Title = "The Working Calculator | Learn X in Y Minutes" 'However if you'd like the calculator to subtract, divide, multiple and 'add up. 'Copy and paste the above again. diff --git a/vyper.html.markdown b/vyper.html.markdown new file mode 100644 index 00000000..fec1a79f --- /dev/null +++ b/vyper.html.markdown @@ -0,0 +1,872 @@ +--- +language: Vyper +filename: learnVyper.vy +contributors: + - ["Kenny Peluso", "kennyp.herokuapp.com"] +--- + +> The content of this document is largely inspired by ["Learn Solidity in Y Minutes"](https:#github.com/adambard/learnxinyminutes-docs/blob/master/solidity.html.markdown) + +Vyper lets you program on [Ethereum](https:#www.ethereum.org/), a +blockchain-based virtual machine that allows the creation and +execution of smart contracts, without requiring centralized or trusted parties. It was +designed to improve upon Solidity, another smart contract language for Ethereum, by +limiting unsafe practices and enhancing readability; Vyper seeks to optimize the +security and auditability of smart contracts. + +Vyper is an experimental, statically typed, contract programming language meant to +resemble Python. Like objects in OOP, each contract contains state variables, functions, +and common data types. Contract-specific features include event notifiers for listeners, +and custom global variables, global constants. + +Some Ethereum contract examples include crowdfunding, voting, and blind auctions. + +--- + +## Table of Contents + +- Intro +- Example +1. Data types and associated methods +2. Data structures +3. Simple operators +4. Global variables of note +5. Functions and more + a. functions + b. events +6. Branching and loops +7. Objects/contracts + a. calling external contracts + b. ERC20 built-in + c. following an interface +8. Other keywords + a. selfdestruct +9. Contract design notes + a. obfuscation + b. storage optimization + c. data access in blockchain + d. cron job + e. observer pattern +10. Security +11. Style notes +12. Natspec comments +- Other documents + +--- + +## Intro + +From [the docs](https://media.readthedocs.org/pdf/vyper/latest/vyper.pdf) +the foundational tenants of Vyper are: + +1. *Security* +2. *Language and compiler simplicity* +3. *Auditability* + +This allows for the following features: + +1. *Bounds and overflow checking* + - On the arithmetic and array level + - There are no dynamic arrays in Vyper +2. *Support for signed integers and decimal fixed point numbers* +3. *Decidability* - You can always compute precise upper bound on gas cost +4. *Strong typing* - for built-in and custom types +5. *Small and understandable compiler code* +6. *Limited support for pure functions* + - Anything marked `@constant` is not allowed to change the state + +Following the principles and goals, Vyper does not provide the following features: + +1. *Modifiers* (defining parts of functions elsewhere) +2. *Class inheritance* +3. *Inline assembly* +4. *Function overloading* +5. *Operator overloading* +6. *Recursive calling* +7. *Infinite-length loops* +8. *Binary fixed point* (decimal fixed point is used for its exactness) + +WITH THE RAPID CHANGES IN ETHEREUM, THIS DOCUMENT IS UNLIKELY TO STAY UP TO +DATE, SO YOU SHOULD FOLLOW THE LATEST VYPER DOCS AND ETHEREUM BLOG FOR THE LATEST. +ALL CODE HERE IS PROVIDED AS IS, WITH SUBSTANTIAL RISK OF ERRORS OR DEPRECATED CODE +PATTERNS. + +This document primarily discusses syntax, and so excludes many +popular design patterns. + +As Vyper and Ethereum are under active development, experimental or beta +features are typically marked, and subject to change. Pull requests welcome. + +This document describes Vyper version `0.1.0-beta.8`. + +*All of the following code exists for educational purposes only!* +*None of the following code should be used in production as-is!* + +## Example + +```python +# First, a simple todo list contract +# Implements CRUD operations for tasks + +# todo.vy (note .vy extension) +### **** START EXAMPLE **** ### + +# Start with Natspec comment +# used for documentation + +# @title SimpleBank v1 +# @author kennyp +# @notice This is a simple bank. + +# Vyper contracts must obey a particular order: +# struct -> interface -> events -> globals and constants -> functions +# Additionally, like Python, Vyper functions must be defined in the file +# before they're called. + +# Structs + +struct Task: + done: bool + deleted: bool + task: string[100] + metadata: bytes32 + +# Interfaces + +contract AnotherContract(): + def fetch() -> bytes32: constant + def inform(_taskId: uint256, _status: uint256) -> bool: modifying + +# Events + +# Events - publicize actions to external listeners +# `indexed` means that it's easier to search/filter on this field +TaskStatus: event({_taskId: indexed(uint256), _status: uint256}) + +# Global Variables + +# State variables are values which are permanently stored in contract storage +# State vars consist of any value persisting beyond any function's scope +# and are permanently stored in contract storage + +# You can define your own, custom, unmutable constants +CREATED: constant(uint256) = 0 +COMPLETED: constant(uint256) = 1 +DELETED: constant(uint256) = 2 + +# The `public` built-in allows for this address to be read externally +# without defining a `get()` constant function +owner: public(address) +other: public(address) + +# uint256 means "unsigned positive integer between 0 and 2^256 - 1" +# Overflow protection is built-in to Vyper +taskCount: uint256 +tasks: map(uint256, Task) # dictionary: key=uint256, value: Task struct + +# Private Functions + +# Start each function with Pythonic decorators +# These decorators resemble Natspec but are actually enforced by Vyper's compiler +# These decorators are: +# @public XOR @private (either one or the other) +# @public (if any contract/user can call it) +# @private (if only internal functions can call it) +# @payable (if the function is payable i.e. accepting ETH) +# @constant (if the function is not modifying anything on-chain) +@private +def _changeTaskStatus( \ + _sender: address, \ + _taskId: uint256, \ + _status: uint256, \ + ): + # backslashes (\) allow for multi-line code + # Natspec comments are particularly helpful for documentation and readibility + # Natspec can be included using familiar Pythonic docstring syntax + """ + @notice + @dev `_sender` MUST be `self.owner` + @param _sender Who is triggering this function + @param _task The description of the task (only useful when task added) + """ + # NOTE: Private functions do not have access to `msg.sender` + # SIDE NOTE: `msg.sender` refers to whoever immediately called the function of + # immediate scope. In other words, if I call a function that calls another + # in-contract, public function, then `msg.sender` turns from my address to + # the address of the current contract. + assert _sender == self.owner # failed assertions cause calls/transactions to fail + # Note that unlike Solidity, `self.` is required to query the contract's state + # Control flow is Pythonic, as is much of Vyper: + _task: string[100] # initialized to default value + _data: bytes32 = sha3(convert(_sender, bytes32)) # owner is obfuscated (but still visible in logs) + if _status == CREATED: # control flow mimics python + # How a new struct is instantiated: + self.tasks[_taskId] = Task({ \ + done: False, deleted: False, task: _task, metadata: _data \ + }) + elif _status == COMPLETED: + # Modifying an existing struct: + self.tasks[_taskId].done = True + elif _status == DELETED: + self.tasks[_taskId].deleted = True + AnotherContract(self.other).inform(_taskId, _status) # modifying external call + log.TaskStatus(_taskId, _status) # emit an event + +# Public Functions + +# Pythonic constructor - can receive none or many arguments +@public +def __init__(_owner: address, _other_contract: address): + """ + @dev Called once and only upon contract depoyment + """ + self.owner = _owner + self.other = _other_contract + +# NOTE: Pythonic whitespace rules are mandated in Vyper + +@public +def addTask(_task: string[100]) -> uint256: + """ + @notice Adds a task to contract + @param _task Description of task + @return Id of newly minted task + """ + # msg.sender gives the address of who/what contract is calling this function + self._changeTaskStatus(msg.sender, self.taskCount, CREATED) + self.tasks[self.taskCount].task = _task + self.taskCount += 1 + return self.taskCount - 1 + +@public +def addSpecialTask(_task: string[100]) -> uint256: + """ + @notice Adds a task with metadata pulled from elsewhere + @param _task Description of task + @return Id of newly minted task + """ + self._changeTaskStatus(msg.sender, self.taskCount, CREATED) + self.tasks[self.taskCount].task = _task + self.tasks[self.taskCount].metadata = AnotherContract(self.other).fetch() + self.taskCount += 1 + return self.taskCount - 1 + +@public +def completeTask(_taskId: uint256): + """ + @notice Marks a task as "completed" + @param _taskId Id of task to complete + """ + self._changeTaskStatus(msg.sender, _taskId, COMPLETED) + +@public +def deleteTask(_taskId: uint256): + """ + @notice Adds a task to contract + @param _taskId Id of task to delete + """ + self._changeTaskStatus(msg.sender, _taskId, DELETED) + +@public +@constant # allows function to run locally/off blockchain +def getTask(_taskId: uint256) -> string[100]: + """ + @notice Getter for a task's description + @param _taskId Id of task with desired description + @return Description of task + """ + return self.tasks[_taskId].task + +### **** END EXAMPLE **** ### + + +# Now, the basics of Vyper + + +# --- + + +# 1. DATA TYPES AND ASSOCIATED METHODS +# uint256 used for currency amount and for dates (in unix time) +x: uint256 + +# int of 128 bits, cannot be changed after contract deployment +# with 'constant', compiler replaces each occurrence with actual value +a: constant(int128) = 5 + +# All state variables (those outside a function) +# are by default 'internal' and accessible inside contract +# Need to explicitly set to 'public' to allow external contracts to access +# A getter is automatically created, but NOT a setter +# Can only be called in the contract's scope (not within functions) +# Add 'public' field to indicate publicly/externally accessible +a: public(int128) + +# No random functions built in, use other contracts for randomness + +# Type casting is limited but exists +b: int128 = 5 +x: uint256 = convert(b, uint256) + +# Types of accounts: +# Contract Account: f(creator_addr, num_transactions)=address set on contract creation +# External Account: (person/external entity): f(public_key)=address + +# Addresses - An address type can hold an Ethereum address which +# equates to 20 bytes or 160 bits. It returns in hexadecimal notation +# with a leading 0x. No arithmetic allowed +owner: public(address) + +# Members can be invoked on all addresses: +owner.balance # returns balance of address as `wei_value` +owner.codesize # returns code size of address as `int128` +owner.is_contract # `True` if Contract Account + +# All addresses can be sent ether via `send()` built-in +@public +@payable +def sendWei(any_addr: address): + send(any_addr, msg.value) + +# Bytes available +a: bytes[2] +b: bytes[32] +c: bytes32 +# `b` and `c` are 2 different types + +# Bytes are preferable to strings since Vyper currently offers better +# support for bytes i.e. more built-ins to deal with `bytes32`, `bytes32` +# can be returned from functions and strings[] can't be, UTF8 (string encoding) +# uses more storage, etc. + +# There are no dynamically sized bytes, similar to how there are no +# dynamic arrays + +# Fixed-size byte arrays (Strings) +a: string[100] +b: string[8] +c: string[108] = concat(a, b) # check the latest docs for more built-ins + +# Time +t1: timedelta +t2: timestamp +# Both types are built-in "custom type" variants of `uint256` +# `timedelta` values can be added but not `timestamp` values + +# Money +m: wei_value +# Also has the base type `uint256` like `timestamp` and `timedelta` +# 1 unit of WEI (a small amount of ETH i.e. ether) + +# Custom types +# specify units used in the contract: +units: { + cm: "centimeter", + km: "kilometer" +} +# usage: +a: int128(cm) +b: uint256(km) + +# BY DEFAULT: all values are set to 0 on instantiation + +# `clear()` can be called on most types +# Does NOT destroy value, but sets value to 0, the initial value + + +# --- + + +# 2. DATA STRUCTURES +# Arrays +bytes32[5] nicknames; # static array +bytes32[] names; # dynamic array +uint newLength = names.push("John"); # adding returns new length of the array +# Length +names.length; # get length +names.length = 1; # lengths can be set (for dynamic arrays in storage only) + +# Multidimensional Arrays +# At initialization, array dimensions must be hard-coded or constants +# Initialize a 10-column by 3-row, multidimensional fixed array +ls: (uint256[10])[3] # parentheses are optional +@public +def setToThree(): + # Multidimensional Array Access and Write + # access indices are reversed + # set element in row 2 (3rd row) column 5 (6th column) to 3 + self.ls[2][5] = 3 + +# Dictionaries (any simple type to any other type including structs) +theMap: map(uint256, bytes32) +theMap[5] = sha3("charles") +# theMap[255] result is 0, all non-set key values return zeroes +# To make read public, make a getter that accesses the mapping +@public +def getMap(_idx: uint256) -> bytes32: + """ + @notice Get the value of `theMap` at `_idx` + """ + return self.theMap[_idx] + +self.getMap(5) # returns sha3("charles") in bytes32 + +# Nested mappings +aMap: map(address, map(address, uint256)) +# NOTE: Mappings are only allowed as state variables +# NOTE: Mappings are not iterable; can only be accessed + +# To delete (reset the mapping's value to default at a key) +clear(balances["John"]) +clear(balances); # sets all elements to 0 + +# Unlike other languages, CANNOT iterate through all elements in +# mapping, without knowing source keys - can build data structure +# on top to do this + +# Structs +struct Struct: + owner: address + _balance: uint256 # balance is a reserved keyword, is a member for addresses + +exampleStuct: Struct + +@public +def foo() -> uint256: + self.exampleStuct = Struct({owner: msg.sender, _balance: 5}) + self.exampleStuct._balance = 10 + self.exampleStuct._balance = 5 # set to new value + clear(self.exampleStuct._balance) + clear(self.exampleStuct) + return self.exampleStuct._balance + + +# Data locations: Memory vs. storage vs. calldata - all complex types (arrays, +# structs) have a data location +# 'memory' does not persist, 'storage' does +# Default is 'storage' for local and state variables; 'memory' for func params +# stack holds small local variables + +# for most types, can explicitly set which data location to use + + +# --- + + +# 3. SIMPLE OPERATORS +# Comparisons, bit operators and arithmetic operators are provided +# exponentiation: ** +# modulo: % +# maximum: max(x, y) +# AND: bitwise_and(x, y) +# bitwise shift: shift(x, _shift) +# where x,y are uint256 +# _shift is int128 + +# 4. GLOBAL VARIABLES OF NOTE +# ** self ** +self # address of contract +# often used at end of contract life to transfer remaining balance to party: +self.balance # balance of current contract +self.someFunction() # calls func externally via call, not via internal jump + +# ** msg - Current message received by the contract ** +# Ethereum programmers take NOTE: this `msg` object is smaller than elsewhere +msg.sender # address of sender +msg.value # amount of ether provided to this contract in wei, the function should be marked `@payable` +msg.gas # remaining gas + +# ** tx - This transaction ** +# Ethereum programmers take NOTE: this `tx` object is smaller than elsewhere +tx.origin # address of sender of the transaction + +# ** block - Information about current block ** +block.timestamp # time at current block (uses Unix time) +# Note that `block.timestamp` can be manipulated by miners, so be careful +block.number # current block number +block.difficulty # current block difficulty + +# ** storage - Persistent storage hash ** +storage['abc'] = 'def'; # maps 256 bit words to 256 bit words + + +# --- + + +# 5. FUNCTIONS AND MORE + +# A. FUNCTIONS +# Simple function +function increment(uint x) returns (uint) { + x += 1; + return x; +} + +# Functions can return many arguments +@public +@constant +def increment(x: uint256, y: uint256) -> (uint256, uint256): + x += 1 + y += 1 + return (x, y) + +# Call previous functon +@public +@constant +def willCall() -> (uint256, uint256): + return self.increment(1,1) + +# One should never have to call a function / hold any logic outside +# outside the scope of a function in Vyper + +# '@constant' +# indicates that function does not/cannot change persistent vars +# Constant function execute locally, not on blockchain +y: uint256 +@public +@constant +def increment(x: uint256) -> uint256: + x += 1 + y += 1 # this line would fail + # y is a state variable => can't be changed in a constant function + + +# 'Function Decorators' +# Used like python decorators but are REQUIRED by Vyper +# @public - visible externally and internally (default for function) +# @private - only visible in the current contract +# @constant - doesn't change state +# @payable - receive ether/ETH +# @nonrentant(<unique_key>) - Function can only be called once, both externally +# and internally. Used to prevent reentrancy attacks + +# Functions hare not hoisted +# Functions cannot be assigned to a variable +# Functions cannot be recursive + +# All functions that receive ether must be marked 'payable' +@public +@payable +def depositEther(): + self.balances[msg.sender] += msg.value + + +# B. EVENTS +# Events are notify external parties; easy to search and +# access events from outside blockchain (with lightweight clients) +# typically declare after contract parameters + +# Declare +LogSent: event({_from: indexed(address), address: indexed(_to), _amount: uint256}) +# Call +log.LogSent(from, to, amount) + +/** +For an external party (a contract or external entity), to watch using +the Web3 Javascript library: + +# The following is Javascript code, not Vyper code +Coin.LogSent().watch({}, '', function(error, result) { + if (!error) { + console.log("Coin transfer: " + result.args.amount + + " coins were sent from " + result.args.from + + " to " + result.args.to + "."); + console.log("Balances now:\n" + + "Sender: " + Coin.balances.call(result.args.from) + + "Receiver: " + Coin.balances.call(result.args.to)); + } +} +**/ + +# Common paradigm for one contract to depend on another (e.g., a +# contract that depends on current exchange rate provided by another) + + +# --- + + +# 6. BRANCHING AND LOOPS + +# All basic logic blocks from Python work - including if/elif/else, for, +# while, break, continue, return - but no switch + +# Syntax same as Python, but no type conversion from non-boolean +# to boolean (comparison operators must be used to get the boolean val) + +# REMEMBER: Vyper does not allow resursive calls or infinite loops + + +# --- + + +# 7. OBJECTS/CONTRACTS +# REMEMBER: Vyper does not allow for inheritance or imports + +# A. CALLING EXTERNAL CONTRACTS +# You must define an interface to an external contract in the current contract + +contract InfoFeed(): + def getInfo() -> uint256: constant + +info: uint256 + +@public +def __init__(_source: address): + self.info = InfoFeed(_source).getInfo() + + +# B. ERC20 BUILT-IN +# Using the `ERC20` keyword implies that the contract at the address +# follows the ERC20 token standard, allowing you to safely call +# functions like `transfer()`, etc. + +tokenAddress: address(ERC20) + +@public +def transferIt(_to: address, _amt: uint256(wei)): + self.tokenAddress.transfer(_to, _amt) + + +# C. FOLLOWING AN INTERFACE +# Vyper is experimenting with using the following syntax at the top of +# a `.vy` file to specify what interfaces are followed by the contract +# This allows interfaces to be better organized, registered, and recognized + +import interfaces.some_interface as SomeInterface +implements: SomeInterface +# <rest of contract> + + +# --- + + +# 8. OTHER KEYWORDS + +# A. selfdestruct() +# selfdestruct current contract, sending funds to address (often creator) +selfdestruct(SOME_ADDRESS); + +# removes storage/code from current/future blocks +# helps thin clients, but previous data persists in blockchain + +# Common pattern, lets owner end the contract and receive remaining funds +@public +def endItAll() { + assert msg.sender == self.creator # Only let the contract creator do this + selfdestruct(self.creator) # Makes contract inactive, returns funds + +# May want to deactivate contract manually, rather than selfdestruct +# (ether sent to selfdestructed contract is lost) + + +# B. sha3() +# Encrypts strings and other data +# Very important on the blockchain +# Takes 1 argument, `concat()` can be called beforehand +# All strings passed are concatenated before hash action +sha3(concat("ab", "cd")) # returns bytes32 + + +# --- + + +# 9. CONTRACT DESIGN NOTES + +# A. Obfuscation +# All variables are publicly viewable on blockchain, so anything +# that is private needs to be obfuscated (e.g., hashed w/secret) +# Oftentimes, a "commit-reveal" scheme is employed + +# Step 1. Commit +# Place a commitment by sending output of `sha3()` +sha3("a secret"); # btyes32 commit +sha3(concat("secret", "other secret", "salt")); # commit multiple things +# The `sha3()` calculation should occur off-chain, only the bytes32 +# output should be inputted into some `commit()` function +commits: map(address, bytes32) +@public +def commit(commitment: bytes32): + self.commits[msg.sender] = commitment + +# Step 2. Reveal +# Send your previously committed data so the contract can check +# if your commitment was honest +@public +def reveal(_secret: string[100], _salt: string[100]) -> bool: + return sha3(concat(_secret, _salt)) == self.commits[msg.sender] + + +# B. Storage optimization +# Writing to blockchain can be expensive, as data stored forever; encourages +# smart ways to use memory (eventually, compilation will be better, but for now +# benefits to planning data structures - and storing min amount in blockchain) + +# Cost can often be high for items like multidimensional arrays +# (cost is for storing data - not declaring unfilled variables) + + +# C. Data access in blockchain +# Cannot restrict human or computer from reading contents of +# transaction or transaction's state + +# While 'private' prevents other *contracts* from reading data +# directly - any other party can still read data in blockchain + +# All data to start of time is stored in blockchain, so +# anyone can observe all previous data and changes + + +# D. Cron Job +# Contracts must be manually called to handle time-based scheduling; +# can create external code to regularly ping or provide incentives +# (ether) for others to ping + + +# E. Observer Pattern +# An Observer Pattern lets you register as a subscriber and +# register a function which is called by the oracle (note, the oracle +# pays for this action to be run) +# Some similarities to subscription in Pub/sub + +# This is an abstract contract, both client and server classes import, +# the client should implement + +### **** START EXAMPLE **** ### + +contract SomeOracleCallback(): + def oracleCallback(_value: uint256, _time: timestamp, _info: bytes32): modifying + +MAX_SUBS: constant(uint256) = 100 +numSubs: public(uint256) # number of subscribers +subs: map(uint256, address) # enumerates subscribers + +@public +def addSub(_sub: address) -> uint256: + """ + @notice Add subscriber + @param _sub Address to add + @return Id of newly added subscriber + """ + self.subs[self.numSubs] = _sub + self.numSubs += 1 + return self.numSubs - 1 + +@private +def notify(_value: uint256, _time: timestamp, _info: bytes32) -> bool: + """ + @notice Notify all subscribers + @dev Check `numSubs` first; Watch out for gas costs! + @param _value whatever + @param _time what have you + @param _info what else + @return True upon successful completion + """ + j: uint256 + for i in range(MAX_SUBS): + j = convert(i, uint256) # `i` is int128 by default + if j == self.numSubs: + return True + SomeOracleCallback(self.subs[j]).oracleCallback(_value, _time, _info) + +@public +def doSomething(): + """ + @notice Do something and notify subscribers + """ + # ...something... + whatever: uint256 = 6 + what_have_you: timestamp + what_else: bytes32 = sha3("6") + self.notify(whatever, what_have_you, what_else) + +# Now, your client contract can addSubscriber by importing SomeOracleCallback +# and registering with Some Oracle + +### **** END EXAMPLE **** ### + + +# --- + + +# 10. SECURITY +# Bugs can be disastrous in Ethereum contracts - and even popular patterns in +# Vyper may be found to be antipatterns + +# See security links at the end of this doc + + +# --- + + +# 11. STYLE NOTES +# Based on Python's PEP8 style guide +# Full Style guide: http:#solidity.readthedocs.io/en/develop/style-guide.html + +# Quick summary: +# 4 spaces for indentation +# Two lines separate contract declarations (and other top level declarations) +# Avoid extraneous spaces in parentheses +# Can omit curly braces for one line statement (if, for, etc) +# else should be placed on own line + +# Specific to Vyper: +# arguments: snake_case +# events, interfaces, structs: PascalCase +# public functions: camelCase +# private functions: _prefaceWithUnderscore + + +# --- + + +# 12. NATSPEC COMMENTS +# used for documentation, commenting, and external UIs + +# Contract natspec - always above contract definition +# @title Contract title +# @author Author name + +# Function natspec +# Should include in docstring of functions in typical Pythonic fashion +# @notice Information about what function does; shown when function to execute +# @dev Function documentation for developer + +# Function parameter/return value natspec +# @param someParam Some description of what the param does +# @return Description of the return value + +``` + +## Additional resources +- [Installation](https://vyper.readthedocs.io/en/latest/installing-vyper.html) +- [Vyper Docs](https://media.readthedocs.org/pdf/vyper/latest/vyper.pdf) +- [Vyper GitHub (under active dev)](https://github.com/ethereum/vyper) +- [Tools and Resources](https://github.com/ethereum/vyper/wiki/Vyper-tools-and-resources) +- [Online Compiler](https://vyper.online/) + +## Sample contracts +- [Uniswap](https://github.com/Uniswap/contracts-vyper) +- [Generalized Governance](https://github.com/kpeluso/gdg) +- [Dynamic Arrays](https://github.com/kpeluso/vyper-dynamic-array) + +## Security +Vyper is secure by design, but it may be helpful to understand what Vyper is +protecting you from. +- [Thinking About Smart Contract Security](https:#blog.ethereum.org/2016/06/19/thinking-smart-contract-security/) +- [Smart Contract Security](https:#blog.ethereum.org/2016/06/10/smart-contract-security/) +- [Hacking Distributed Blog](http:#hackingdistributed.com/) + +## Style +- [Vyper Style Guide WIP](https://github.com/ethereum/vyper/issues/905) + - Heavily derived from [Solidity's style guide](http:#solidity.readthedocs.io/en/latest/style-guide.html) ... + - ... which, in turn, is heavily derived from Python's [PEP 8](https:#www.python.org/dev/peps/pep-0008/) style guide. + +## Editors +- [Vyper for VS Code (alpha)](https://github.com/p-/vscode-vyper) + +## Future To Dos +- Update to current Vyper release +- List of common design patterns + +*Feel free to send a pull request with any edits - or email* `pelusoken -/at-/ gmail` + diff --git a/yaml.html.markdown b/yaml.html.markdown index 8683971e..09c5dfc5 100644 --- a/yaml.html.markdown +++ b/yaml.html.markdown @@ -121,7 +121,7 @@ other_anchor: *anchor_name base: &base name: Everyone has same name -# The regexp << is called Merge Key Language-Independent Type. It is is used to +# The regexp << is called Merge Key Language-Independent Type. It is used to # indicate that all the keys of one or more specified maps should be inserted # into the current map. diff --git a/zh-cn/awk-cn.html.markdown b/zh-cn/awk-cn.html.markdown index 3fea782b..8ee2db2c 100644 --- a/zh-cn/awk-cn.html.markdown +++ b/zh-cn/awk-cn.html.markdown @@ -1,5 +1,6 @@ --- -language: awk +category: tool +tool: awk contributors: - ["Marshall Mason", "http://github.com/marshallmason"] translators: diff --git a/zh-cn/make-cn.html.markdown b/zh-cn/make-cn.html.markdown index 4cdf1e63..76dde941 100644 --- a/zh-cn/make-cn.html.markdown +++ b/zh-cn/make-cn.html.markdown @@ -1,5 +1,6 @@ --- -language: make +category: tool +tool: make contributors: - ["Robert Steed", "https://github.com/robochat"] - ["Jichao Ouyang", "https://github.com/jcouyang"] @@ -38,7 +39,7 @@ Makefile 用于定义如何创建目标文件, 比如如何从源码到可执行 # … # prerequisites(依赖) 是可选的, recipe(做法) 也可以多个或者不给. -# 下面这个任务没有给 prerequisites, 只会在目标文件 file0.txt 文件不存在是跑 +# 下面这个任务没有给 prerequisites, 只会在目标文件 file0.txt 文件不存在时执行 file0.txt: echo "foo" > file0.txt # 试试 `make file0.txt` @@ -46,12 +47,12 @@ file0.txt: # 注意: 即使是这些注释, 如果前面有 TAB, 也会发送给 shell, 注意看 `make file0.txt` 输出 # 如果提供 prerequisites, 则只有 prerequisites 比 target 新时会执行 -# 比如下面这个任务只有当 file1.txt 比 file0.txt 新时才会执行. +# 比如下面这个任务只有当 file0.txt 比 file1.txt 新时才会执行. file1.txt: file0.txt cat file0.txt > file1.txt - # 这里跟shell里的命令式一毛一样的. + # 这里跟shell里的命令式一模一样. @cat file0.txt >> file1.txt - # @ 不会把命令往 stdout 打印. + # @ 不会把命令打印到 stdout. -@echo 'hello' # - 意思是发生错误了也没关系. # 试试 `make file1.txt` 吧. @@ -234,7 +235,7 @@ ls: * # include foo.mk sport = tennis -# 一些逻辑语句 if else 什么的, 顶个写 +# 流程控制语句 (如if else 等等) 顶格写 report: ifeq ($(sport),tennis) @echo 'game, set, match' diff --git a/zh-cn/python-cn.html.markdown b/zh-cn/python-cn.html.markdown index deb94cdc..65f125d1 100644 --- a/zh-cn/python-cn.html.markdown +++ b/zh-cn/python-cn.html.markdown @@ -439,7 +439,7 @@ Human.grunt() # => "*grunt*" # 我们可以导入其他模块 import math -print math.sqrt(16) # => 4 +print math.sqrt(16) # => 4.0 # 我们也可以从一个模块中导入特定的函数 from math import ceil, floor diff --git a/zh-cn/solidity-cn.html.markdown b/zh-cn/solidity-cn.html.markdown new file mode 100644 index 00000000..ec684997 --- /dev/null +++ b/zh-cn/solidity-cn.html.markdown @@ -0,0 +1,825 @@ +--- +language: Solidity +filename: learnSolidity-cn.sol +lang: zh-cn +contributors: + - ["Nemil Dalal", "https://www.nemil.com"] + - ["Joseph Chow", ""] + - ["Bhoomtawath Plinsut", "https://github.com/varshard"] + - ["Shooter", "https://github.com/liushooter"] +translators: + - ["Bob Jiang", "https://github.com/bobjiang"] +--- + +Solidity 使你在[以太坊](https://www.ethereum.org/)上编程,一个基于区块链的虚拟机, +允许创建和执行智能合约,无需中心化的或可信的一方。 + +Solidity 是一种与 Javascript 和 C 的相似的、静态类型的合约编程语言。与OOP(面向对象)中 +的对象一样,每个合约都包含状态变量、函数和公共数据类型。合约特定功能包括修饰符(guard)子句, +事件通知的侦听器及自定义的全局变量。 + +以太坊合约的例子包括众筹、投票以及盲拍(私密拍卖)。 + +Solidity 代码中存在高风险和高成本的错误,因此你必须非常小心地进行测试并慢慢地发布。**随着 +以太坊的快速变化,本文档不可能是最新的,所以你应该关注最新的的 solidity 聊天室和以太网博客。 +照搬这里的代码,会存在重大错误或弃用代码模式的风险。(说人话--别照抄例子中的代码)** + +与其他代码不同,可能还需要添加如暂停、弃用和限制使用的设计模式,来降低风险。本文档主要讨论语法, +因此排除了许多流行的设计模式。 + +由于 Solidity 和以太坊正在积极开发,通常会标记为实验或 beta 特性,并很可能会更改。因此欢迎 +提交更改请求。 + +```javascript +// 首先,一个简单的银行合约 +// 允许存款、取款、以及检查余额 + +// simple_bank.sol (注意 .sol 后缀) +/* **** 例子开始 **** */ + +// 声明源文件的编译器版本 +pragma solidity ^0.4.19; + +// 开始 Natspec 注释(三个斜杠) +// 用作文档 - 及UI元素、动作的描述性数据 + +/// @title SimpleBank +/// @author nemild + +/* 'contract' 和其他语言的 'class' 类似 (类变量、继承等) */ +contract SimpleBank { // 单词首字母大写 + // 声明函数外的状态变量,合约生命周期内可用 + + // 地址映射到余额的字典,总是要小心数字的溢出攻击 + mapping (address => uint) private balances; + + // "private" 的意思是其他合约不能直接查询余额,但对于区块链上的其他方来说,数据仍然是可见的。 + + address public owner; + // 'public' 使用户或合约可以从外部读取(不可写) + + // Events(事件) - 向外部监听器发布动作 + event LogDepositMade(address accountAddress, uint amount); + + // Constructor(构造函数)(译者注:solidity 从0.4.22开始使用 constructor() 作为构造函数) + function SimpleBank() public { + // msg 提供了发送给合约的消息详情 + // msg.sender 是合约的调用者(这里是合约创建者的地址) + owner = msg.sender; + } + + /// @notice 存款 ether (以太币) + /// @return 存款后用户的余额 + function deposit() public payable returns (uint) { + // 使用 'require' 来检测用户的输入,'assert' 是内部常量 + // 我们要确保不会发生溢出问题(上溢) + require((balances[msg.sender] + msg.value) >= balances[msg.sender]); + + balances[msg.sender] += msg.value; + // 状态变量不需要 "this." 或 "self." + // 默认情况下,所有值都设置为数据类型的初始值 + + LogDepositMade(msg.sender, msg.value); // 触发事件 + + return balances[msg.sender]; + } + + /// @notice 从银行取款以太币 (ether) + /// @dev 不会返回任何多余的以太币(ether) + /// @param withdrawAmount 取款的数量 + /// @return 用户还剩下的余额 + function withdraw(uint withdrawAmount) public returns (uint remainingBal) { + require(withdrawAmount <= balances[msg.sender]); + + // 注意在发送任何交易,即通过 .transfer .send 调用外部函数之前,马上减掉取款数量 + // 这可以允许调用者使用递归请求大于其余额的金额。目标是在调用外部函数之前提交状态, + // 包括.transfer / .send + balances[msg.sender] -= withdrawAmount; + + // 这会自动引发失败,也就是说还原了更新的余额 + msg.sender.transfer(withdrawAmount); + + return balances[msg.sender]; + } + + /// @notice 获取余额 + /// @return 用户的余额 + // 'view' 防止函数编辑状态变量;允许函数本地运行或链下运行 + function balance() view public returns (uint) { + return balances[msg.sender]; + } +} +// ** 例子结束 ** + + +// 下面, solidity 基础 + +// 1. 数据类型与关联的方法 +// uint 类型用作现金数量(没有双浮点型或单浮点型)及日期(用 unix 时间) +uint x; + +// 256字节的 int, 实例化后不能改变 +int constant a = 8; +int256 constant a = 8; // 和上一行一样,这里256字节显性化了 +uint constant VERSION_ID = 0x123A1; // 16进制常量 +// 'constant' 关键字, 编译器在每个出现的地方替换为实际的值 + +// 所有的状态变量(函数之外的那些),默认是 'internal' 的,只能在合约及所有继承的合约内 +// 可以访问。需要显性的设置为 'public' 才能允许外部合约访问。 +int256 public a = 8; + +// 对于 int 和 uint,可以显性的设置位数(从8位到256位,8位跳跃),如int8, int16, int24 +uint8 b; +int64 c; +uint248 e; + +// 当心不要溢出以及免收此类攻击,例如,对于加法最好这么做: +uint256 c = a + b; +assert(c >= a); // assert 测试内部不变的值;require 用来测试用户输入 +// 更多通用算法问题的例子,参考 Zeppelin's SafeMath library +// https://github.com/OpenZeppelin/zeppelin-solidity/blob/master/contracts/math/SafeMath.sol + + +// 没有内建的随机函数,使用其他合约获得随机数 + +// 类型转换 +int x = int(b); + +bool b = true; // 或 'var b = true;' 隐含的类型 + +// 地址 - 20个字节或160位以太坊地址(16进制数字),不允许进行运算 +address public owner; + +// 账户类型: +// 合约账户:在创建时设置地址(创建者地址函数,交易发送) +// 外部账户:(个人账户)从公钥创建的地址 + +// 'public' 的含义是自动创建的 getter 方法,而不是 setter 方法可以公开的、外部访问。 + +// 所有地址都可以进行转账 +owner.transfer(SOME_BALANCE); // 失败后还原 + +// 还可以调用较低级别的 .send , 转账失败会返回 false +if (owner.send) {} +// 记住:用 'if' 包着 send 函数,因为合约地址执行这些函数转账时,可能会失败 +// 另外,确保转账前先减掉余额,因为存在递归调用的风险。 + +// 检查余额 +owner.balance; // 所有者的余额(用户或合约) + + +// 字符类型,从1到32位可用 +byte a; // byte 等同于 byte1 +bytes2 b; +bytes32 c; + +// 动态大小的字符 +bytes m; // 特殊的数组,等同于 byte[],比 byte1 到 byte32 更贵 +// 尽可能不用 bytes + +// 等同于 bytes,但不允许长度或索引的访问 +string n = "hello"; // UTF8存储,注意双引号而不是单引号 +// 字符功能未来会增加,推荐使用 bytes32 或 bytes + +// 推断类型 +// var 会根据第一次赋值决定类型,不能用来作为函数的参数 +var a = true; +// 小心使用,推断可能带来错误的类型,例如,int8,而计数器需要的是 int16 + +// 函数可以用 var 类型赋值给变量 +function a(uint x) returns (uint) { + return x * 2; +} +var f = a; +f(22); // 调用 + +// 默认的,所有值实例化后都设为 0 + +// 大多数类型上可以调用删除(不会销毁值,而是设置为0,初始值) +uint x = 5; + + +// 集合 +(x, y) = (2, 7); // 多值的赋值 + + +// 2. 数据结构 +// 数组 +bytes32[5] nicknames; // 静态数组 +bytes32[] names; // 动态数组 +uint newLength = names.push("John"); // 添加返回数组的新长度 +// 长度 +names.length; // 获得数组长度 +names.length = 1; // 可以设定长度(仅针对 storage 中的动态数组) + +// 多维数组 +uint x[][5]; // 5个动态数组元素的数组(和多数语言的顺序相反) + +// 字典类型 (任一类型到其他类型的映射) +mapping (string => uint) public balances; +balances["charles"] = 1; +// balances["ada"]得到 0, 所有没有设定key值的,返回0 +// 'public' 允许跟着(调用)另一份合约 +contractName.balances("charles"); // returns 1 +// 'public' 创建 getter (而不是 setter )如下: +function balances(string _account) returns (uint balance) { + return balances[_account]; +} + +// 内嵌的 mapping +mapping (address => mapping (address => uint)) public custodians; + +// 删除 +delete balances["John"]; +delete balances; // 所有元素设为 0 + +// 不像其他语言,不知道 keys 的话不能列出 mapping 中的所有元素 - 可以在这之上构建数据结构 + +// 结构 +struct Bank { + address owner; + uint balance; +} +Bank b = Bank({ + owner: msg.sender, + balance: 5 +}); +// 或 +Bank c = Bank(msg.sender, 5); + +c.balance = 5; // 设为新值 +delete b; +// 设为初始值,结构内所有变量设为0,除了 mapping + +// 枚举 +enum State { Created, Locked, Inactive }; // 常常作为状态机 +State public state; // 声明枚举变量 +state = State.Created; +// 枚举类型可以显性化的转换为 ints +uint createdState = uint(State.Created); // 0 + +// 数据位置:内存(Memory) vs. 存储(storage) vs. 调用数据(calldata) +// 所有复杂类型(数据、结构)都有一个数据位置,内存数据不持久,而存储的数据是持久的。 +// 本地变量和状态变量默认是存储,函数参数默认是内存。堆栈存放较小的本地变量 + +// 多数类型,可以显性化的设定使用的数据位置 + + +// 3. 简单操作符 +// solidity 提供了比较、位运算及数学运算的功能 +// 指数运算: ** +// 异或运算: ^ +// 按位取反: ~ + + +// 4. 值得注意的全局变量 +// ** this ** +this; // 合约的地址 +// 常常用在合约生命周期结束前,转走剩下的余额 +this.balance; +this.someFunction(); // 通过 call 的方式而不是内部跳转的方式,从外部调用函数 + +// ** msg - 合约收到的当前消息 ** ** +msg.sender; // 发送者的地址 +msg.value; // 该合约内的以太币数量(单位 wei),该函数应该标记为 "payable" +msg.data; // 字符,完整的调用数据 +msg.gas; // 剩余 gas + +// ** tx - 交易信息 ** +tx.origin; // 本次交易的发送者地址 +tx.gasprice; // 本次交易的 gas price + +// ** block - 当前区块信息 ** +now; // 当前时间(大概)block.timestamp的别名 (采用的 Unix 时间) +// 注意这个可能被矿工操纵,因此请小心使用 + +block.number; // 当前区块号 +block.difficulty; // 当前区块难度 +block.blockhash(1); // 返回 bytes32,只对最近 256 个区块有效 +block.gasLimit(); + +// ** 存储 - 持久化存储哈希 ** +storage['abc'] = 'def'; // 256 位单词 到 256 位单词的映射 + + +// 4. 函数及更多 +// A. 函数 +// 简单函数 +function increment(uint x) returns (uint) { + x += 1; + return x; +} + +// 函数可以通过指定返回的参数名,来返回多个参数 +function increment(uint x, uint y) returns (uint x, uint y) { + x += 1; + y += 1; +} +// 调用前一个函数 +uint (a,b) = increment(1,1); + +// 'view' ('constant'的别名) +// 表明函数不会改变持久化的变量,View函数会本地执行,而不是链上运行。 +// 注意:constant 关键字很快会废弃。 +uint y = 1; + +function increment(uint x) view returns (uint x) { + x += 1; + y += 1; // 这一行会失败 + // y 是一个状态变量,不能在 view 的函数里改变 y +} + +// 'pure' 比 'view' 或 'constant' 更加严格,甚至不允许读取状态变量 +// 具体的规则很复杂,请参考 +// view/pure: +// http://solidity.readthedocs.io/en/develop/contracts.html#view-functions + +// '函数可见性指示器' +// 'view'可以有以下修饰符,包括: +// public - 内部及外部可见(函数的默认值) +// external - 仅外部可见(包括 this 发起的调用) +// private - 仅当前合约可见 +// internal - 仅当前合约及继承的合约可见 + +// 通常,显性的标记每个函数是个好主意 + +// 函数的挂起 - 可以将函数赋值给变量 +function a() { + var z = b; + b(); +} + +function b() { + +} + +// 所有接收 ether 的函数必须标记为 'payable' +function depositEther() public payable { + balances[msg.sender] += msg.value; +} + + +// 首选循环来递归(最大的调用堆栈深度是 1024),另外不要设置没有限制的循环, +// 因为这可能会达到 gas limit + +// B. 事件 +// 事件通知外部各方; 易于搜索和访问来自外部区块链(使用轻客户端)的事件 +// 通常在合约参数之后声明 + +// 通常,首字母大写并在前面加上 Log ,防止与函数混淆 + +// 声明 +event LogSent(address indexed from, address indexed to, uint amount); // 注意 capital first letter + +// 调用 +LogSent(from, to, amount); + +/* + // 对于外部方(合约或外部实体),使用 Web3 Javascript 库来监听 + // 以下是javascript代码,不是solidity代码 + Coin.LogSent().watch({}, '', function(error, result) { + if (!error) { + console.log("Coin transfer: " + result.args.amount + + " coins were sent from " + result.args.from + + " to " + result.args.to + "."); + console.log("Balances now:\n" + + "Sender: " + Coin.balances.call(result.args.from) + + "Receiver: " + Coin.balances.call(result.args.to)); + } + } + +*/ + +// 一个合约依赖另一个合约的共同范例(例如,合约取决于另一个合约提供的当前汇率) + +// C. 修饰器 +// 修饰器验证函数的输入,例如最小余额或用户身份验证; 类似于其他语言的保护子句 + +// '_' (下划线)经常用在代码的最后一行,表明被调用的函数放在那里 +modifier onlyAfter(uint _time) { require (now >= _time); _; } +modifier onlyOwner { require(msg.sender == owner) _; } +// 常用于状态机 +modifier onlyIfStateA (State currState) { require(currState == State.A) _; } + +// 修饰器紧跟在函数声明之后 +function changeOwner(newOwner) +onlyAfter(someTime) +onlyOwner() +onlyIfState(State.A) +{ + owner = newOwner; +} + +// 下划线可以包含在代码结束之前,但明显地返回将跳过后面的代码,因此谨慎使用 +modifier checkValue(uint amount) { + _; + if (msg.value > amount) { + uint amountToRefund = amount - msg.value; + msg.sender.transfer(amountToRefund); + } +} + + +// 6. 判断和循环 + +// 所有基本的逻辑判断都有效 - 包括 if else, for, while, break, continue +// return - 但不跳转 + +// 语法同 javascript, 但没有从非布尔值到布尔值的类型转换 +// (必须使用比较操作符获得布尔变量值) + +// 请注意由用户行为决定的循环 - 因为合约对于代码块具有最大量的 gas 限制 - +// 如果超过限制该代码则将失败 +// 例如: +for(uint x = 0; x < refundAddressList.length; x++) { + refundAddressList[x].transfer(SOME_AMOUNT); +} + +// 上述两个错误: +// 1. 转账失败会阻塞循环完成,钱被占用 +// 2. 该循环可能会很长(根据需要赔偿的用户数量而定),并且也可能由于超过一个区块最大 gas 限制 +// 而总是失败。你应该让人们自己从他们的子账户取款并标记取款完成 +// 例如,首选拉动式的付款,而不是推动式的付款 + + +// 7. 对象与合约 + +// A. 调用外部合约 +contract InfoFeed { + function info() returns (uint ret) { return 42; } +} + +contract Consumer { + InfoFeed feed; // 指向区块链上的一个合约 + + // 设置 feed 为已存在的合约实例 + function setFeed(address addr) { + // 当心类型自动转换;不会调用构造函数 + feed = InfoFeed(addr); + } + + // 设置 feed 为一个合约的新实例 + function createNewFeed() { + feed = new InfoFeed(); // 创建新实例,调用构造函数 + } + + function callFeed() { + // 最后的括号调用合约,可选择的增加自定义的 ether 或 gas 价格 + feed.info.value(10).gas(800)(); + } +} + +// B. 继承 + +// 和顺序有关,最后继承的合约(如 'def')可以覆盖之前已继承合约的部分 +contract MyContract is abc, def("a custom argument to def") { + +// 覆盖函数 + function z() { + if (msg.sender == owner) { + def.z(); // 调用覆盖的函数 + super.z(); // 调用继承的上层合约的函数 + } + } +} + +// 抽象函数 +function someAbstractFunction(uint x); +// 不可以编译,因此用在基础或抽象合约中,等待实现 + +// C. 导入 + +import "filename"; +import "github.com/ethereum/dapp-bin/library/iterable_mapping.sol"; + + +// 8. 其他关键字 + +// A. 自毁 +// 自毁当前的合约,转账资金到一个地址(常常是创建者的地址) +selfdestruct(SOME_ADDRESS); + +// 从当前或以后的区块中移除存储或代码,会帮助客户端瘦身,但之前的数据会永久在区块链中 + +// 常见模式,让所有者结束合约并收回剩余的资金 +function remove() { + if(msg.sender == creator) { // 只有合约的创建者可以这么做 + selfdestruct(creator); // 自毁合约,返还资金 + } +} + +// 可能希望手动停用合约,而不是自毁 +// (发送到自毁合约的 ether 会丢失掉) + + +// 9. 注意合约的设计 + +// A. 困惑 +// 区块链上所有变量都是公开可见的,因此任何私有的需求变得很困惑。(好比哈希的秘密) + +// 步骤: 1. 承诺某事, 2. 揭示承诺 +keccak256("some_bid_amount", "some secret"); // commit + +// 以后调用合约的 reveal 函数,展示出用 SHA3 哈希的 bid 加 secret +reveal(100, "mySecret"); + +// B. 存储优化 +// 写入区块链可能很昂贵,因为数据是永久存储的;鼓励用巧妙的方法使用内存 +//(最终,编译会更好,但现在有利于规划数据结构 - 并将最小数量存储在区块链中) + +// 多维数组这样的变量可能会成本很高 +// (成本用于存储数据 - 而不是声明未填充的变量) + +// C. 区块链中的数据访问 +// 不能限制人或计算机读取交易或交易状态的内容 + +// 然而 'private' 可以防止其他*合约*直接读取数据 - 任意其他方仍然可以从区块链读取数据 + +// 从开始的所有数据都存在区块链上,因此任何人都可以查看之前的所有数据和变化 + +// D. 定时任务 +// 必须手动调用合约来处理时间相关的调度;也可以创建外部代码来定期的ping, +// 或为其他人提供激励(以太) + +// E. 观察者模式 +//观察者模式允许您注册为订阅者,然后注册一个由oracle调用的函数 +//(注意,oracle 需要付费来运行此操作)。与 Pub / sub 中的订阅有些相似之处 + +// 这是一个抽象合约,包括客户端和服务器端的类的导入,客户端应该要实现 +contract SomeOracleCallback { + function oracleCallback(int _value, uint _time, bytes32 info) external; +} + +contract SomeOracle { + SomeOracleCallback[] callbacks; // 所有订阅者的数组 + + // 注册订阅者 + function addSubscriber(SomeOracleCallback a) { + callbacks.push(a); + } + + function notify(value, time, info) private { + for(uint i = 0;i < callbacks.length; i++) { + // 所有调用的订阅者必须实现 oracleCallback + callbacks[i].oracleCallback(value, time, info); + } + } + + function doSomething() public { + // 实现的代码 + + // 通知所有的订阅者 + notify(_value, _time, _info); + } +} + +// 现在你的客户端合约可以通过 importing SomeOracleCallback 和注册某些 Oracle 来 +// addSubscriber 添加订阅者 + +// F. 状态机 +// 参见如下的例子,枚举类型的 State 和 修饰器 inState + + +// *** 例子: 众筹的例子(与 Kickstarter 大致相似)*** +// ** 开始例子 ** + +// CrowdFunder.sol +pragma solidity ^0.4.19; + +/// @title CrowdFunder +/// @author nemild +/// @translator bobjiang +contract CrowdFunder { + // 由创建者创建的变量 + address public creator; + address public fundRecipient; // 创建者可能和收件人不同 + uint public minimumToRaise; // 需要提示,否则每个人都会得到退款 + string campaignUrl; + byte constant version = 1; + + // 数据结构 + enum State { + Fundraising, + ExpiredRefund, + Successful + } + struct Contribution { + uint amount; + address contributor; + } + + // 状态变量State variables + State public state = State.Fundraising; // 创建时实例化 + uint public totalRaised; + uint public raiseBy; + uint public completeAt; + Contribution[] contributions; + + event LogFundingReceived(address addr, uint amount, uint currentTotal); + event LogWinnerPaid(address winnerAddress); + + modifier inState(State _state) { + require(state == _state); + _; + } + + modifier isCreator() { + require(msg.sender == creator); + _; + } + + // 允许合约销毁之前,最终合约状态后要等待24周 + modifier atEndOfLifecycle() { + require(((state == State.ExpiredRefund || state == State.Successful) && + completeAt + 24 weeks < now)); + _; + } + + function CrowdFunder( + uint timeInHoursForFundraising, + string _campaignUrl, + address _fundRecipient, + uint _minimumToRaise) + public + { + creator = msg.sender; + fundRecipient = _fundRecipient; + campaignUrl = _campaignUrl; + minimumToRaise = _minimumToRaise; + raiseBy = now + (timeInHoursForFundraising * 1 hours); + } + + function contribute() + public + payable + inState(State.Fundraising) + returns(uint256 id) + { + contributions.push( + Contribution({ + amount: msg.value, + contributor: msg.sender + }) // 采用数组,因此可以遍历 + ); + totalRaised += msg.value; + + LogFundingReceived(msg.sender, msg.value, totalRaised); + + checkIfFundingCompleteOrExpired(); + return contributions.length - 1; // 返回 id + } + + function checkIfFundingCompleteOrExpired() + public + { + if (totalRaised > minimumToRaise) { + state = State.Successful; + payOut(); + + // 可以激励在这里发起状态改变的人 + } else if ( now > raiseBy ) { + state = State.ExpiredRefund; // 支持者可以通过调用 getRefund(id) 收取退款 + } + completeAt = now; + } + + function payOut() + public + inState(State.Successful) + { + fundRecipient.transfer(this.balance); + LogWinnerPaid(fundRecipient); + } + + function getRefund(uint256 id) + inState(State.ExpiredRefund) + public + returns(bool) + { + require(contributions.length > id && id >= 0 && contributions[id].amount != 0 ); + + uint256 amountToRefund = contributions[id].amount; + contributions[id].amount = 0; + + contributions[id].contributor.transfer(amountToRefund); + + return true; + } + + function removeContract() + public + isCreator() + atEndOfLifecycle() + { + selfdestruct(msg.sender); + // 创建者获得所有未被声明的钱 + } +} +// ** 结束例子 ** + +// 10. 其他原生的函数 + +// 货币单位 +// 货币使用 wei 来定义,以太币的最小单位 = 1 wei; +uint minAmount = 1 wei; +uint a = 1 finney; // 1 ether == 1000 finney +// 其他单位,请参阅: http://ether.fund/tool/converter + +// 时间单位 +1 == 1 second +1 minutes == 60 seconds + +// 可以乘以带时间单位的变量,因为单位不会存储在变量中 +uint x = 5; +(x * 1 days); // 5 天 + +// 小心闰秒闰年与平等声明的时间 +// (相反,首选大于或小于) + +// 加密算法 +// 传递的所有字符串在哈希操作之前需要连接在一起 +sha3("ab", "cd"); +ripemd160("abc"); +sha256("def"); + +// 11. 安全 + +// 以太坊的合约中,错误可能是灾难性的 - 即使在 solidity 中是流行的模式,也可能发现是反模式的 + +// 参见文档底部的安全链接 + +// 12. 较低层次的函数 +// call - 较低层次,不会经常使用,不提供类型安全性 +successBoolean = someContractAddress.call('function_name', 'arg1', 'arg2'); + +// callcode - 在调用合约的*上下文*中执行的目标地址上的代码 +// 提供库功能 +someContractAddress.callcode('function_name'); + + +// 13. 注意风格 +// 基于 Python 的 PEP8 风格指南 +// 全部风格指南: http://solidity.readthedocs.io/en/develop/style-guide.html + +// 快速总结: +// 4个空格缩进 +// 两行隔开合约声明(和其他高级别的声明) +// 避免括号内留出多余的空格 +// 可以省略一行语句的花括号 (if, for, 等) +// else 应该单独一行 + + +// 14. NATSPEC 注释 +// 用于文档、注释和外部UI + +// 合约的 natspec - 总是在合约定义的上面 +/// @title 合约标题 +/// @author 作者名字 + +// 函数的 natspec +/// @notice 函数做什么的相关信息;展示什么时候执行该函数、 +/// @dev 开发者使用的函数文档 + +// 函数参数、返回值的 natspec +/// @param 有关参数用途的描述 +/// @return 返回值的描述 +``` + +## 更多资源 +- [Solidity Docs](https://solidity.readthedocs.org/en/latest/) +- [Smart Contract Best Practices](https://github.com/ConsenSys/smart-contract-best-practices) +- [EthFiddle - The JsFiddle for Solidity](https://ethfiddle.com/) +- [Browser-based Solidity Editor](https://remix.ethereum.org/) +- [Gitter Solidity Chat room](https://gitter.im/ethereum/solidity) +- [Modular design strategies for Ethereum Contracts](https://docs.erisindustries.com/tutorials/solidity/) + +## 重要的库文件 +- [Zeppelin](https://github.com/OpenZeppelin/zeppelin-solidity/): Libraries that provide common contract patterns (crowdfuding, safemath, etc) + +## 示例合约 +- [Dapp Bin](https://github.com/ethereum/dapp-bin) +- [Solidity Baby Step Contracts](https://github.com/fivedogit/solidity-baby-steps/tree/master/contracts) +- [ConsenSys Contracts](https://github.com/ConsenSys/dapp-store-contracts) +- [State of Dapps](http://dapps.ethercasts.com/) + +## 安全 +- [Thinking About Smart Contract Security](https://blog.ethereum.org/2016/06/19/thinking-smart-contract-security/) +- [Smart Contract Security](https://blog.ethereum.org/2016/06/10/smart-contract-security/) +- [Hacking Distributed Blog](http://hackingdistributed.com/) + +## 风格 +- [Solidity Style Guide](http://solidity.readthedocs.io/en/latest/style-guide.html): Ethereum's style guide is heavily derived from Python's [PEP 8](https://www.python.org/dev/peps/pep-0008/) style guide. + +## 编辑器 +- [Emacs Solidity Mode](https://github.com/ethereum/emacs-solidity) +- [Vim Solidity](https://github.com/tomlion/vim-solidity) +- Editor Snippets ([Ultisnips format](https://gist.github.com/nemild/98343ce6b16b747788bc)) + +## Future to Dos +- 新关键字: protected, inheritable +- 常见设计模式列表 (throttling, RNG, version upgrade) +- 常见的安全反模式 + +请随意发送 pull request 或者发邮件给作者 nemild -/at-/ gmail + +或者发邮件给译者 jiangxb -/at-/ gmail.com diff --git a/zh-tw/python-tw.html.markdown b/zh-tw/python-tw.html.markdown index 553181d8..cd7481d7 100644 --- a/zh-tw/python-tw.html.markdown +++ b/zh-tw/python-tw.html.markdown @@ -627,7 +627,7 @@ i.age # => raises an AttributeError # 你可以引入模組來做使用 import math -print math.sqrt(16) # => 4 +print math.sqrt(16) # => 4.0 # math.sqrt()為取根號 # 你可以只從模組取出特定幾個函式 |