Hey, Polyglots! Ready for another programming language?
By the end of this, students should be able to:
- Contrast Python REPL with Ruby REPL.
- Contrast basic language features and types from Python with basic language features and types from Ruby.
- Write a simple script in Python.
- Fork and clone this repository.
brew install pyenv
- Open
~/.bashrc
and add the following between Rbenv and Git configs:
# Pyenv
export PYENV_ROOT=/usr/local/var/pyenv
eval "$(pyenv init -)"
-
pyenv install 3.5.1
-
pyenv global 3.5.1
-
Python doesn't ship with the most up to date version of package manager pip, so upgrade pip :
pip install -upgrade pip
-
brew install pyenv-virtualenv
-
Add the following to
~/.bashrc
under your additions from step 2:eval "$(pyenv virtualenv-init -)"
curl -L https://raw.githubusercontent.com/yyuu/pyenv-installer/master/bin/pyenv-installer | bash
- Python doesn't ship with the most up to date version of package manager
pip, so upgrade pip :
pip install -upgrade pip
- Open
~/.bashrc
and add the following between Rbenv and Git configs:
# Pyenv
export PATH="/root/.pyenv/bin:$PATH"
eval "$(pyenv init -)"
eval "$(pyenv virtualenv-init -)"
We'll be using linter-pylint.
apm install linter-pylint
We'll be using Python's built-in REPL to practice what we learn today.
Typing python
onto the command line will bring you into this REPL, similar to
using pry
or node
.
To run Python scripts, simply run
python <filename.rb>
from the command line.
Hint: to print to the console in Python, we use print <string to print>
Let's practice this. Take a minute to look at lib/fizzbuzz.rb,
then run the fizzbuzz
script from the command line using
python lib/fizzbuzz.rb
.
Snake case lives on! Aka, keep_your_variables_defined_this_way
.
Parens ()
in Python are required around parameters as opposed to optional
in Ruby.
Similar to Ruby, there is a lack of semicolons in Python. Line breaks in your code are enough to denote the end of an expression.
However, as you may have noticed from our fizzbuzz
script, we are introduced
to colons :
throughout our code. Colons always come directly after the
first line of the block statement. Colons are also immediately followed by a
new, indented line (this indentation is purposeful whitespace).
Python's colons/whitespace combo act similarly to Ruby's end
for method
declarations and loops.
While whitespace in Ruby is essentially ignored, in Python, it is critical to
ensuring working code. Otherwise, you'll run into an IndentationError
.
Variable declaration in Python is extremely similar to Ruby's. Variables can be defined without being previously declared. Variable reassignment is also as flexible as Ruby's.
>>> x = 2 # assigns x to numerical value 2
>>> x = "WDI is top tier" # reassigns x to string value
Also similar to Ruby, variables in Python cannot be called or stated without being defined.
>>> z
NameError: name 'z' is not defined
In Python, true and false are represented by True
and False
(yes, case
matters).
The falsy values of Python are:
False
None
0
0.0
''
[]
{}
None
is equivalent to Ruby's nil
.
Ruby | Python | |
---|---|---|
logical operators | && , || , ! |
and , or , not |
relational operators | == != > < >= <= |
== != > < >= <= |
arithmetic operators | + , - , * , / // , % |
+ , - , * , / , % |
If you remember from Ruby, integer division will always return a whole integer. For best results, division with Floats returns most accurate results.
In Python, this whole integer division behavior can be mirrored with the //
operator.
>>> 14.5 / 3 # => 4.833333
>>> 14.5 // 3 # => 4.0
Note that operations on floats will still return floats no matter the operator.
To convert between floats and integers, use:
>>> int(14.5) # => 14
>>> float(14) # => 14.0
Let's get used to these operators.
In your Python REPL from the command line, take some time to practice each logical, relational and artithmetic operator listed for you above.
In Python, there is no difference between using " "
or ' '
.
Escape Characters
are evaluated in both.
>>> print "This is a \n new line."
# => This is a
# => new line.
>>> print 'This is a \n new line.'
# => This is a
# => new line.
Like Ruby, there are many options for string interpolation in Python. For our
purposes, we'll be using .format()
, as it is preferred for Python 3.5.
.format()
is appended to a string and takes a parameters the strings to be
concatenated. If the string contains empty {}
s, the parameters fill the {}
s
in the order passed in. If they contain a number (beginning with 0), they will
be mapped to the parameter passed to .format()
at said index.
>>> awkward_nerd = "Lauren"
>>> awesome_nerd = "Jason"
>>> occupation = "consultant"
>>> "{} is a pretty cool {}.".format(awkward_nerd, occupation)
# => "Lauren is a pretty cool consultant."
>>> "{0} is a {1}. {2} is a {1} as well.".format(awkward_nerd, occupation, awesome_nerd)
# => "Lauren is a consultant. Jason is a consultant as well."
Again, colons and whitespace are critical to working Python code. Aside from
that and the use of elif
vs. elsif
, these should feel very similar to Ruby
conditional statements.
if x < 0:
print 'Negative'
elif x == 0:
print 'Zero'
else:
print 'Positive'
Also like Ruby, Python employs while
and for
loops.
Python also allows for an optional else
statement with each of these. With
while
loops, the else
statement is executed once the while
condition is
no longer true. With for
loops, else
is executed upon the loop's
completion.
count = 0
while count < 5:
print count, " is less than 5"
count = count + 1
else:
print count, " is not less than 5"
count = 15
for i in range(1,count):
print i
else:
print "done"
Again, this else
is optional and different in nature from a conditional else.
It functions more as a completion handler.
Functions in Python are similar to Ruby methods (Python also has methods, but we only refer to them as such when they are functions of a Class).
Aside from syntactical differences, the main difference to note is the need for an explicit return. Think JavaScript!
Basic function structure:
def function_example(param_one, param_two):
"""Example function returning string interpolation of parameters."""
concat = "What a splendid function! I've got my {0} and {1}.".format(param_one, param_two)
return concat
You may have noticed something like
"""This function..."""
within each of our example functions. These are called docstrings
and are
conventionally used in Python to provide documentation throughout a codebase.
Code will run fine without them, but that would stray from Python's conventions
as well as throw you into linter message hell. Try them out!
In lib/calculator.py, create a calculator function that
takes two parameters. The first should be the operation to be completed
(addition
, subtraction
, multiplication
, division
). The second should be
a list with the appropriate number of numbers to operate on. The function
mapped to the appropriate operation should take the expected numbers by index
from the list passed in and return back to you the result of the operation.
We haven't discussed lists yet, but they are very similar to Ruby arrays. The syntax required for this is very similar to how you would approach this in Ruby. Lean on the knowledge you gained from the Python vs Ruby study!
Remember, to run a Python script from the command line:
python <filename.py>
Python lists are comparable to Ruby arrays. They store comma separated values
of varying data types between square brackets []
.
Lists are ordered, thus, indices can be leveraged to get or set their elements.
wdi_base_langs = ["JavaScript", "Ruby", "SQL"]
wdi_base_langs[2] # => "SQL"
wdi_base_langs[0] = "JS" # => ["JS", "Ruby", "SQL"]
len()
is used to get the length of a list in Python.
len(wdi_base_langs) # => 3
We can merge lists together using the +
operator:
wdi_new_langs = ["Python"]
all_wdi_langs = wdi_new_langs + wdi_base_langs # => ["JS", "Ruby", "SQL", "Python"]
We could have gone about adding "Python" to the end of the wdi_base_langs
list by using .append()
.
wdi_base_langs.append("Python") # => ["JS", "Ruby", "SQL", "Python"]
Like Ruby, .pop()
removes the last element from a Python list. .append()
will add to the end of a list.
We do not have built-in operators for removing or adding to the beginning of a list. As hackers, we've got some hacks, though.
.remove()
allows us to remove an element at any index. Thus, list.remove(0)
would remove the first element from a list.
We could implement our array merging to add to the beginning of a list. Look at the following:
a = "first"
b = ["second", "third"]
[a] + b # => ["first", "second", "third"]
for
loops with lists don't stray far from the loops we saw earlier.
all_wdi_langs = ["JS", "Ruby", "SQL", "Python"]
for lang in all_wdi_langs:
print lang
Python dictionaries are very similar to other key-value objects we've seen.
Dictionary keys must be unique. Creating a key-value pair for a key that already exists will simply reassign the value of the existing key.
Keys can be either strings or numbers.
There are two ways of instantiating a Python dictionary:
new_dict = dict() # => {}
# or
new_dict = {} # => {}
example_dict = {
"key_one": "val one",
"key_two": "val two",
"key_three": "val three"
}
To add or retrieve a key-value pair, we implement square bracket notation:
new_dict["fun_key"] = "fresh"
new_dict["fun_key"] # => "fresh"
.get()
is another option for retrieving a key's value.
new_dict.get("fun_key") # => "fresh"
Dictionary defaults are a little different from Ruby. If it is unknown that a
key you are retrieving exists, you can call .get()
with a default value
should it not exist.
new_dict.get("no_key", "not there") # => "not there"
In lib/list_and_dict_buzz.rb, build a more robust
FizzBuzz from scratch. Create a dictionary containing keys fizz
, buzz
,
fizzbuzz
, and other
, each with lists as values. As you iterate through all
the numbers from 1 to max_num, add each number to one of the lists mentioned
above; numbers divisible by 3 only should go into the fizz
list, numbers
divisible by 5 only should go into the buzz
list, numbers divisible by both
should go into the fizzbuzz
list, and numbers divisible by neither should go
into the "other" list. Finally, once you're done, print the resulting
dictionary to check that your code works properly.
Source code distributed under the MIT license. Text and other assets copyright General Assembly, Inc., all rights reserved.