Skip to content

Commit c9d96f4

Browse files
committed
Rewrites of about, introduction, and links.
1 parent a552877 commit c9d96f4

File tree

3 files changed

+311
-162
lines changed

3 files changed

+311
-162
lines changed

concepts/basics/about.md

Lines changed: 160 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
# basics
22

3-
[Python][python docs] is a [dynamic and strongly][dynamic typing in python] typed [object-oriented][object oriented programming] programming language.
3+
Python is a [dynamic and strongly][dynamic typing in python] typed [object-oriented][object oriented programming] programming language.
44
It employs both [duck typing][duck typing] and [gradual typing][gradual typing], via [type hints][type hints].
5-
It supports multiple programming paradigms including both imperative (_object-oriented, procedural_) and declarative (_functional, concurrent_) flavors.
6-
But do not be fooled: while programming across paradigms is fully _supported_, [everything in Python is an object][everythings an object].
5+
Imperative, declarative (e.g., functional), and object-oriented programming _styles_ are all supported, but internally [everything in Python is an object][everythings an object].
6+
7+
Python puts a strong emphasis on code readability and (_similar to Haskell_) uses [significant indentation][significant indentation] to denote function, method, and class definitions.
8+
9+
10+
The [zen of Python (PEP 20)][the zen of python] and [What is Pythonic?][what is pythonic] lay out additional philosophies
711

812
Python was created by Guido van Rossum and first released in 1991. The [Python Software Foundation][psf] manages and directs resources for Python and CPython development and receives proposals for changes to the language from [members][psf membership] of the community via [Python Enhancement Proposals or PEPs][peps].
913

10-
Python puts a strong emphasis on code readability and (_similar to Haskell_) uses [significant indentation][significant indentation] to denote function, method, and class definitions.
11-
The [zen of Python (PEP 20)][the zen of python] and [What is Pythonic?][what is pythonic] lay out additional philosophies.
1214

1315
Complete documentation for the current release can be found at [docs.python.org][python docs].
1416

@@ -19,59 +21,110 @@ Complete documentation for the current release can be found at [docs.python.org]
1921
- [Python FAQs][python faqs]
2022
- [Python Glossary of Terms][python glossary of terms]
2123

24+
This concept introduces 4 major Python language features: Name Assignment (_variables and constants_), Functions (_and the return keyword_), Comments, and Docstrings.
25+
26+
27+
~~~~exercism/note
2228
23-
## Getting Started
29+
In general, content, tests, and analyzer tooling for the Python track follow the style conventions outlined in [PEP 8](https://www.python.org/dev/peps/pep-0008/) and [PEP 257](https://www.python.org/dev/peps/pep-0257/) for Python code style, with the additional (strong) suggestion that there be no single letter variable names.
2430
25-
Objects are [assigned][assignment statements] to [names][naming and binding] in Python via the `=` or _assignment operator_. [Variables][variables] are written in [`snake_case`][snake case], and constants usually in `SCREAMING_SNAKE_CASE`.
31+
~~~~
2632

27-
A `name` (_variable or constant_) is not itself typed, and can be attached or re-attached to different objects or values over its lifetime.
28-
For extended naming conventions and formatting advice, see [PEP 8][pep8].
33+
34+
## Name Assignment and Re-assignment
35+
36+
In Python, there are no keywords to define variables or constants.
37+
Both are [_names_][facts-and-myths-about-python-names] that help programmers reference values (_objects_) in a program and are written differently only by convention.
38+
On Exercism, [variables][variables] are always written in [`snake_case`][snake case], and _constants_ in `SCREAMING_SNAKE_CASE`.
39+
40+
Names are assigned to values using `=`, or the [_assignment operator_][assignment statements] (`<name> = <value>`).
41+
A name (_variable or constant_) can be re-assigned over its lifetime to different values/object types.
42+
43+
For example, `my_first_variable` can be re-assigned many times using `=`, and can refer to different object types with each re-assignment:
2944

3045
```python
46+
# Assigning my_first_variable to a numeric value.
3147
>>> my_first_variable = 1
32-
>>> my_first_variable = "Last one, I promise"
48+
>>> print(type(my_first_variable))
49+
<class 'int'>
50+
3351
>>> print(my_first_variable)
52+
1
53+
54+
# Reassigning my_first_variable to a new string value.
55+
>>> my_first_variable = "Now, I'm a string."
56+
>>> print(type(my_first_variable))
57+
<class 'str'>
3458

35-
"Last one, I promise"
59+
>>> print(my_first_variable)
60+
"Now, I'm a string."
3661
```
3762

38-
Constants are usually defined on a [module][module] or `global` level, and although they _can_ be changed, they are _intended_ to be assigned only once.
3963

40-
Their `SCREAMING_SNAKE_CASE` is a message to other developers that the assignment should not be altered.
64+
### Constants
65+
66+
Constants are typically defined at a [module][module] level, being values that are accessible outside function or class scope.
67+
Constant names **_can be reassigned to new values_**, but they are _intended_ to be named only once.
68+
Using `SCREAMING_SNAKE_CASE` warns other programmers that these names should not be mutated or reassigned.
4169

4270
```python
43-
# All caps signal that this is intended as a constant
71+
# All caps signal that this is intended as a constant.
4472
MY_FIRST_CONSTANT = 16
4573

4674
# Re-assignment will be allowed by the compiler & interpreter,
47-
# but is VERY strongly discouraged.
48-
# Please don't do: MY_FIRST_CONSTANT = "Some other value"
75+
# but this is VERY strongly discouraged.
76+
# Please don't: MY_FIRST_CONSTANT = "Some other value"
4977
```
5078

79+
80+
## Functions
81+
5182
In Python, units of functionality are encapsulated in [_functions._][functions], which are themselves [objects][objects] (_it's [turtles all the way down][turtles all the way down]_).
5283

5384
Functions can be executed by themselves, passed as arguments to other functions, nested, or bound to a class.
5485
When functions are bound to a [class][classes] name, they're referred to as [methods][method objects].
5586
Related functions and classes (_with their methods_) can be grouped together in the same file or module, and imported in part or in whole for use in other programs.
5687

5788
The keyword `def` begins a [function definition][function definition].
58-
`def` must be followed by the function name and a parenthesized list of zero or more formal [parameters][parameters].
59-
Parameters can be of several different varieties, and can even [vary][more on functions] in length.
60-
The `def` line is terminated with a colon (`:`).
89+
It must be followed by the function name and a parenthesized list of zero or more formal [parameters][parameters].
90+
Parameters can be of several different varieties, and can even [vary][more on functions] in length.
91+
92+
The `def` line is terminated with a colon (`:`):
93+
94+
```python
95+
# Function definition.
96+
def my_function_name(parameter, second_parameter):
97+
<function body>
98+
99+
```
100+
101+
Statements for the `function body` begin on the line following `def` and must be _indented in a block_.
102+
There is no strict indentation amount (_either space **OR** [tab] characters are acceptable_), but [indentation][indentation] must be _consistent_ for all indented statements.
103+
104+
105+
```python
106+
# Function definition on first line.
107+
def add_two_numbers(number_one, number_two):
108+
print(number_one + number_two) # Prints the sum of the numbers, and is indented by 2 spaces.
109+
110+
>>> add_two_numbers(3, 4)
111+
7
112+
```
113+
61114

62-
Statements for the `function body` begin on the line following `def`, and must be _indented in a block_.
63-
There is no strict indentation amount (_either space **OR** [tab] characters are acceptable_), but [indentation][indentation] must be _consistent for all indented statements_.
64115
Functions explicitly return a value or object via the [`return`][return] keyword.
65116

66117
```python
67118
# Function definition on first line.
68-
>>> def add_two_numbers(number_one, number_two):
69-
... return number_one + number_two # Returns the sum of the numbers, and is indented by 2 spaces.
119+
def add_two_numbers(number_one, number_two):
120+
return number_one + number_two # Returns the sum of the numbers.
70121

71122
>>> add_two_numbers(3, 4)
72123
7
73124
```
74125

126+
127+
75128
Functions that do not have an explicit `return` expression will return [`None`][none].
76129

77130
```python
@@ -83,53 +136,53 @@ def add_two_numbers(number_one, number_two):
83136
None
84137
```
85138

86-
Inconsistent indentation will raise an error:
139+
While you may choose any indentation depth, _inconsistent_ indentation in your code blocks will raise an error:
87140

88141
```python
89142
# The return statement line does not match the first line indent.
90143
>>> def add_three_numbers_misformatted(number_one, number_two, number_three):
91144
... result = number_one + number_two + number_three # Indented by 4 spaces.
92145
... return result #this was only indented by 3 spaces
146+
...
147+
...
93148
File "<stdin>", line 3
94149
return result
95150
^
96151
IndentationError: unindent does not match any outer indentation level
97152
```
98153

154+
155+
### Calling Functions
156+
99157
Functions are [_called_][calls] using their name followed by `()`.
100158
The number of arguments passed in the parentheses must match the number of parameters in the original function definition unless [default arguments][default arguments] have been used.
101159

102160
```python
103161
>>> def number_to_the_power_of(number_one, number_two):
104-
"""Raise a number to an arbitrary power.
105-
106-
:param number_one: int the base number.
107-
:param number_two: int the power to raise the base number to.
108-
:return: int - number raised to power of second number
109-
110-
Takes number_one and raises it to the power of number_two, returning the result.
111-
"""
112-
113-
... return number_one ** number_two
114-
162+
return number_one ** number_two
163+
...
115164

116165
>>> number_to_the_power_of(3,3)
117166
27
118167
```
119168

120-
A mis-match between parameters and arguments will raise an error:
169+
170+
A mis-match between the number of parameters and the number of arguments will raise an error:
121171

122172
```python
123173
>>> number_to_the_power_of(4,)
174+
...
124175
Traceback (most recent call last):
125176
File "<stdin>", line 1, in <module>
126177
TypeError: number_to_the_power_of() missing 1 required positional argument: 'number_two'
127178

128179
```
129180

181+
130182
Adding a [default value][default arguments] for a parameter can defend against such errors:
131183

132184
```python
185+
# Note the default value of 2 assigned below.
133186
def number_to_the_power_of_default(number_one, number_two=2):
134187
"""Raise a number to an arbitrary power.
135188
@@ -142,35 +195,51 @@ def number_to_the_power_of_default(number_one, number_two=2):
142195

143196
return number_one ** number_two
144197

198+
# Because there was a default value, this call with only one argument does not throw an error.
145199
>>> number_to_the_power_of_default(4)
146200
16
147201
```
148202

149-
Methods bound to class names are invoked via dot notation (`<class_name>.<method_name>()`), as are functions, constants, or global names imported as part of a module.:
203+
204+
Methods bound to class names are invoked via dot notation (`<class name>.<method name>(<parameters>))`, as are functions (`<module name>.<function name>(<parameters>)`), constants (`<module name>.<constant name>`), or any other global names imported as part of a module.:
150205

151206
```python
207+
# This is an example of a method call of the built in str class.
208+
# Define a variable and assign it to a string.
209+
>>> start_text = "my silly sentence for examples."
210+
211+
# Uppercase the string by calling the upper method from the str class.
212+
>>> str.upper(start_text)
213+
"MY SILLY SENTENCE FOR EXAMPLES."
214+
215+
216+
# Below is an example of a method call of the built in list class.
217+
# Define an empty list
218+
>>> my_list = []
219+
220+
# Add an element to the list by calling the append method from the list class.
221+
>>> my_list.append(start_text)
222+
>>> print(my_list)
223+
["my silly sentence for examples."]
152224

153225
import string
154226

155227
# This is a constant provided by the *string* module.
156-
>>> print(string.ascii_lowercase)
228+
>>> alphabet = string.ascii_lowercase
229+
>>> print(alphabet)
157230
"abcdefghijklmnopqrstuvwxyz"
231+
```
158232

159-
# This is a method call of the str *class*.
160-
>>> start_text = "my silly sentence for examples."
161-
>>> str.upper(start_text)
162-
"MY SILLY SENTENCE FOR EXAMPLES."
163233

164-
# This is a method call of an *instance* of the str *class*.
165-
>>> start_text.upper()
166-
"MY SILLY SENTENCE FOR EXAMPLES."
167-
```
234+
## Comments
168235

169236
[Comments][comments] in Python start with a `#` that is not part of a string, and end at line termination.
170-
Unlike many other programming languages, Python does not support multi-line comment marks.
237+
Unlike many other programming languages, Python **does not support** multi-line comment marks.
171238
Each line of a comment block must start with the `#` character.
239+
172240
Comments are ignored by the interpreter:
173241

242+
174243
```python
175244
# This is a single line comment.
176245

@@ -181,25 +250,53 @@ x = "foo" # This is an in-line comment.
181250
# these should be used sparingly.
182251
```
183252

253+
254+
## Docstrings
255+
184256
The first statement of a function body can optionally be a [_docstring_][docstring], which concisely summarizes the function or object's purpose.
185-
Docstrings are read by automated documentation tools and are returned by calling `.__doc__` on the function, method, or class name.
186-
They are recommended for programs of any size where documentation is needed, and their conventions are laid out in [PEP257][PEP257]:
257+
Docstrings are declared using triple double quotes (""") indented at the same level as the code block:
187258

188259

189260
```python
190-
# An example on a user-defined function.
191-
def number_to_the_power_of(number_one, number_two):
192-
"""Raise a number to an arbitrary power.
193-
194-
:param number_one: int the base number.
195-
:param number_two: int the power to raise the base number to.
196-
:return: int - number raised to power of second number
197-
198-
Takes number_one and raises it to the power of number_two, returning the result.
261+
262+
# An example from PEP257 of a multi-line docstring.
263+
def complex(real=0.0, imag=0.0):
264+
"""Form a complex number.
265+
266+
Keyword arguments:
267+
real -- the real part (default 0.0)
268+
imag -- the imaginary part (default 0.0)
199269
"""
200270

201-
return number_one ** number_two
271+
if imag == 0.0 and real == 0.0:
272+
return complex_zero
273+
274+
```
275+
276+
277+
Docstrings are read by automated documentation tools and are returned by calling the special attribute `.__doc__` on the function, method, or class name.
278+
They are recommended for programs of any size where documentation is needed, and their conventions are laid out in [PEP257][pep257].
279+
280+
Docstrings can also function as [lightweight unit tests][doctests], which can be read and run by PyTest, or by importing the `doctest` module.
281+
Testing and `doctest` will be covered in a later concept.
282+
283+
284+
```python
285+
# An example on a user-defined function.
286+
>>> def number_to_the_power_of(number_one, number_two):
287+
"""Raise a number to an arbitrary power.
288+
289+
:param number_one: int the base number.
290+
:param number_two: int the power to raise the base number to.
291+
:return: int - number raised to power of second number
292+
293+
Takes number_one and raises it to the power of number_two, returning the result.
294+
"""
295+
296+
return number_one ** number_two
297+
...
202298

299+
# Calling the .__doc__ attribute of the function and printing the result.
203300
>>> print(number_to_the_power_of.__doc__)
204301
Raise a number to an arbitrary power.
205302

@@ -209,7 +306,9 @@ Raise a number to an arbitrary power.
209306

210307
Takes number_one and raises it to the power of number_two, returning the result.
211308

212-
# __doc__() for the built-in type: str.
309+
310+
311+
# Printing the __doc__ attribute for the built-in type: str.
213312
>>> print(str.__doc__)
214313
str(object='') -> str
215314
str(bytes_or_buffer[, encoding[, errors]]) -> str
@@ -223,9 +322,6 @@ encoding defaults to sys.getdefaultencoding().
223322
errors defaults to 'strict'.
224323
```
225324

226-
Docstrings can also include [doctests][doctests], which are interactive examples of how a method or function should work.
227-
Doctests can be read and run by PyTest, or by importing the `doctest` module.
228-
229325
[PEP257]: https://www.python.org/dev/peps/pep-0257/
230326
[assignment statements]: https://docs.python.org/3/reference/simple_stmts.html#assignment-statements
231327
[calls]: https://docs.python.org/3/reference/expressions.html#calls
@@ -237,6 +333,7 @@ Doctests can be read and run by PyTest, or by importing the `doctest` module.
237333
[duck typing]: https://en.wikipedia.org/wiki/Duck_typing
238334
[dynamic typing in python]: https://stackoverflow.com/questions/11328920/is-python-strongly-typed
239335
[everythings an object]: https://docs.python.org/3/reference/datamodel.html
336+
[facts-and-myths-about-python-names]: https://nedbatchelder.com/text/names.html
240337
[function definition]: https://docs.python.org/3/tutorial/controlflow.html#defining-functions
241338
[functions]: https://docs.python.org/3/reference/compound_stmts.html#function
242339
[gradual typing]: https://en.wikipedia.org/wiki/Gradual_typing

0 commit comments

Comments
 (0)