Skip to content

Commit 306dfe2

Browse files
committed
And yet more edits to this exercise and concept.
1 parent a308ebb commit 306dfe2

File tree

5 files changed

+197
-477
lines changed

5 files changed

+197
-477
lines changed

concepts/basics/about.md

Lines changed: 67 additions & 123 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,10 @@
22

33
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-
Imperative, declarative (e.g., functional), and object-oriented programming _styles_ are all supported, but internally [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]**.
66

77
Python puts a strong emphasis on code readability and (_similar to Haskell_) uses [significant indentation][significant indentation] to denote function, method, and class definitions.
88

9-
10-
The [zen of Python (PEP 20)][the zen of python] and [What is Pythonic?][what is pythonic] lay out additional philosophies
11-
129
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].
1310

1411

@@ -21,59 +18,77 @@ Complete documentation for the current release can be found at [docs.python.org]
2118
- [Python FAQs][python faqs]
2219
- [Python Glossary of Terms][python glossary of terms]
2320

21+
2422
This concept introduces 4 major Python language features: Name Assignment (_variables and constants_), Functions (_and the return keyword_), Comments, and Docstrings.
2523

2624

2725
~~~~exercism/note
2826
2927
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.
3028
31-
~~~~
29+
The [zen of Python (PEP 20)][the zen of python] and [What is Pythonic?][what is pythonic] lay out additional philosophies.
30+
31+
On the Python track, [variables][variables] are always written in [`snake_case`][snake case], and constants in `SCREAMING_SNAKE_CASE`
3232
3333
34-
## Name Assignment and Re-assignment
34+
[snake case]: https://en.wikipedia.org/wiki/Snake_case
35+
[variables]: https://realpython.com/python-variables/
36+
[what is pythonic]: https://blog.startifact.com/posts/older/what-is-pythonic.html
37+
[the zen of python]: https://www.python.org/dev/peps/pep-0020/
38+
~~~~
3539

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`.
3940

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.
41+
## Name Assignment (Variables & Constants)
42+
43+
In Python, there are no keywords used in creating variables or constants.
44+
Instead, programmer defined [_names_][facts-and-myths-about-python-names] (also called _variables__) can be bound to any type of object using the assignment `=` operator: `<name> = <value>`.
45+
A name can be reassigned (or re-bound) to different values (different object types) over its lifetime.
4246

4347
For example, `my_first_variable` can be re-assigned many times using `=`, and can refer to different object types with each re-assignment:
4448

49+
4550
```python
46-
# Assigning my_first_variable to a numeric value.
47-
>>> my_first_variable = 1
51+
>>> my_first_variable = 1 # Name bound to an integer object of value one.
52+
>>> my_first_variable = 2 # Name re-assigned to integer value 2.
53+
4854
>>> print(type(my_first_variable))
4955
<class 'int'>
5056

5157
>>> print(my_first_variable)
52-
1
58+
2
5359

54-
# Reassigning my_first_variable to a new string value.
55-
>>> my_first_variable = "Now, I'm a string."
60+
>>> my_first_variable = "Now, I'm a string." # You may re-bind a name to a different object type and value.
5661
>>> print(type(my_first_variable))
5762
<class 'str'>
5863

5964
>>> print(my_first_variable)
60-
"Now, I'm a string."
65+
"Now, I'm a string." # Strings can be declared using single or double quote marks.
66+
67+
import collections
68+
>>> my_first_variable = collections.Counter([1,1,2,3,3,3,4,5,6,7])
69+
>>> print(type(my_first_variable))
70+
<class 'collections.Counter'>
71+
72+
>>> print(my_first_variable)
73+
>>> Counter({3: 3, 1: 2, 2: 1, 4: 1, 5: 1, 6: 1, 7: 1})
6174
```
6275

6376

6477
### Constants
6578

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.
79+
Constants are names meant to be assigned only once in a program.
80+
They should be defined at a [module][module] (file) level, and are typically visible to all functions and classes in the program.
81+
Using `SCREAMING_SNAKE_CASE` signals that the name should not be re-assigned, or its value mutated.
82+
6983

7084
```python
7185
# All caps signal that this is intended as a constant.
7286
MY_FIRST_CONSTANT = 16
7387

7488
# Re-assignment will be allowed by the compiler & interpreter,
7589
# but this is VERY strongly discouraged.
76-
# Please don't: MY_FIRST_CONSTANT = "Some other value"
90+
# Please don't do this, it could create problems in your program!
91+
MY_FIRST_CONSTANT = "Some other value"
7792
```
7893

7994

@@ -85,49 +100,45 @@ Functions can be executed by themselves, passed as arguments to other functions,
85100
When functions are bound to a [class][classes] name, they're referred to as [methods][method objects].
86101
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.
87102

88-
The keyword `def` begins a [function definition][function definition].
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+
The `def` keyword begins a [function definition][function definition].
104+
Each function can have zero or more formal [parameters][parameters] in `()` parenthesis, followed by a `:` colon.
105+
Statements for the _body_ of the function begin on the line following `def` and must be _indented in a block_.
103106

104107

105108
```python
106-
# Function definition on first line.
109+
# The body of this function is indented by 2 spaces, & prints the sum of the numbers
107110
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.
111+
total = number_one + number_two
112+
print(total)
109113

110114
>>> add_two_numbers(3, 4)
111115
7
112-
```
113116

114117

118+
# Inconsistent indentation in your code blocks will raise an error.
119+
>>> def add_three_numbers_misformatted(number_one, number_two, number_three):
120+
... result = number_one + number_two + number_three # This was indented by 4 spaces.
121+
... print(result) #this was only indented by 3 spaces
122+
...
123+
...
124+
File "<stdin>", line 3
125+
print(result)
126+
^
127+
IndentationError: unindent does not match any outer indentation level
128+
```
129+
115130
Functions explicitly return a value or object via the [`return`][return] keyword.
131+
Functions that do not have an explicit `return` expression will _implicitly_ return [`None`][none].
116132

117133
```python
118134
# Function definition on first line.
119135
def add_two_numbers(number_one, number_two):
120-
return number_one + number_two # Returns the sum of the numbers.
136+
result = number_one + number_two
137+
return result # Returns the sum of the numbers.
121138

122139
>>> add_two_numbers(3, 4)
123140
7
124-
```
125-
126-
127-
128-
Functions that do not have an explicit `return` expression will return [`None`][none].
129141

130-
```python
131142
# This function will return None.
132143
def add_two_numbers(number_one, number_two):
133144
result = number_one + number_two
@@ -136,98 +147,39 @@ def add_two_numbers(number_one, number_two):
136147
None
137148
```
138149

139-
While you may choose any indentation depth, _inconsistent_ indentation in your code blocks will raise an error:
140-
141-
```python
142-
# The return statement line does not match the first line indent.
143-
>>> def add_three_numbers_misformatted(number_one, number_two, number_three):
144-
... result = number_one + number_two + number_three # Indented by 4 spaces.
145-
... return result #this was only indented by 3 spaces
146-
...
147-
...
148-
File "<stdin>", line 3
149-
return result
150-
^
151-
IndentationError: unindent does not match any outer indentation level
152-
```
153-
154150

155151
### Calling Functions
156152

157-
Functions are [_called_][calls] using their name followed by `()`.
158-
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.
153+
Functions are [_called_][calls] or invoked using their name followed by `()`.
154+
Dot (`.`) notation is used for calling functions defined inside a class or module.
159155

160156
```python
161157
>>> def number_to_the_power_of(number_one, number_two):
162158
return number_one ** number_two
163159
...
164160

165-
>>> number_to_the_power_of(3,3)
161+
>>> number_to_the_power_of(3,3) # Invoking the function with the arguments 3 and 3.
166162
27
167-
```
168-
169163

170-
A mis-match between the number of parameters and the number of arguments will raise an error:
171164

172-
```python
165+
# A mis-match between the number of parameters and the number of arguments will raise an error.
173166
>>> number_to_the_power_of(4,)
174167
...
175168
Traceback (most recent call last):
176169
File "<stdin>", line 1, in <module>
177170
TypeError: number_to_the_power_of() missing 1 required positional argument: 'number_two'
178171

179-
```
180-
181172

182-
Adding a [default value][default arguments] for a parameter can defend against such errors:
183-
184-
```python
185-
# Note the default value of 2 assigned below.
186-
def number_to_the_power_of_default(number_one, number_two=2):
187-
"""Raise a number to an arbitrary power.
188-
189-
:param number_one: int the base number.
190-
:param number_two: int the power to raise the base number to.
191-
:return: int - number raised to power of second number
192-
193-
Takes number_one and raises it to the power of number_two, returning the result.
194-
"""
195-
196-
return number_one ** number_two
197-
198-
# Because there was a default value, this call with only one argument does not throw an error.
199-
>>> number_to_the_power_of_default(4)
200-
16
201-
```
202-
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.:
205-
206-
```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.
173+
# Calling methods or functions in classes and modules.
209174
>>> 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)
175+
>>> str.upper(start_text) # Calling the upper() method for the built-in str class.
213176
"MY SILLY SENTENCE FOR EXAMPLES."
214177

178+
# Importing the math module
179+
import math
215180

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."]
224-
225-
import string
226-
227-
# This is a constant provided by the *string* module.
228-
>>> alphabet = string.ascii_lowercase
229-
>>> print(alphabet)
230-
"abcdefghijklmnopqrstuvwxyz"
181+
>>> math.pow(2,4) # Calling the pow() function from the math module
182+
>>> 16.0
231183
```
232184

233185

@@ -323,11 +275,9 @@ errors defaults to 'strict'.
323275
```
324276

325277
[PEP257]: https://www.python.org/dev/peps/pep-0257/
326-
[assignment statements]: https://docs.python.org/3/reference/simple_stmts.html#assignment-statements
327278
[calls]: https://docs.python.org/3/reference/expressions.html#calls
328279
[classes]: https://docs.python.org/3/reference/datamodel.html#classes
329280
[comments]: https://realpython.com/python-comments-guide/#python-commenting-basics
330-
[default arguments]: https://docs.python.org/3/tutorial/controlflow.html#default-argument-values
331281
[docstring]: https://docs.python.org/3/tutorial/controlflow.html#tut-docstrings
332282
[doctests]: https://docs.python.org/3/library/doctest.html
333283
[duck typing]: https://en.wikipedia.org/wiki/Duck_typing
@@ -337,10 +287,8 @@ errors defaults to 'strict'.
337287
[function definition]: https://docs.python.org/3/tutorial/controlflow.html#defining-functions
338288
[functions]: https://docs.python.org/3/reference/compound_stmts.html#function
339289
[gradual typing]: https://en.wikipedia.org/wiki/Gradual_typing
340-
[indentation]: https://docs.python.org/3/reference/lexical_analysis.html#indentation
341290
[method objects]: https://docs.python.org/3/c-api/method.html#method-objects
342291
[module]: https://docs.python.org/3/tutorial/modules.html
343-
[more on functions]: https://docs.python.org/3/tutorial/controlflow.html#more-on-defining-functions
344292
[none]: https://docs.python.org/3/library/constants.html
345293
[object oriented programming]: https://en.wikipedia.org/wiki/Object-oriented_programming
346294
[objects]: https://docs.python.org/3/reference/datamodel.html#the-standard-type-hierarchy
@@ -357,9 +305,5 @@ errors defaults to 'strict'.
357305
[python tutorial]: https://docs.python.org/3/tutorial/index.html
358306
[return]: https://docs.python.org/3/reference/simple_stmts.html#return
359307
[significant indentation]: https://docs.python.org/3/reference/lexical_analysis.html#indentation
360-
[snake case]: https://en.wikipedia.org/wiki/Snake_case
361-
[the zen of python]: https://www.python.org/dev/peps/pep-0020/
362308
[turtles all the way down]: https://en.wikipedia.org/wiki/Turtles_all_the_way_down
363309
[type hints]: https://docs.python.org/3/library/typing.html
364-
[variables]: https://realpython.com/python-variables/
365-
[what is pythonic]: https://blog.startifact.com/posts/older/what-is-pythonic.html

0 commit comments

Comments
 (0)