Skip to content

Commit d5ec7c5

Browse files
committed
Updated README.md, shortened the Py2 vs. Py3 section
1 parent 4ff6be7 commit d5ec7c5

4 files changed

+27
-28
lines changed

Python_for_Data_Science_all.html

+3-6
Original file line numberDiff line numberDiff line change
@@ -2037,18 +2037,15 @@ <h3 id="A-note-on-Python-2-vs.-Python-3">A note on Python 2 vs. Python 3<a class
20372037
<div class="inner_cell">
20382038
<div class="text_cell_render border-box-sizing rendered_html">
20392039
<p>There are 2 major versions of Python in widespread use: <a href="https://docs.python.org/2/">Python 2</a> and <a href="https://docs.python.org/3/">Python 3</a>. Python 3 has some features that are not backward compatible with Python 2, and some Python 2 libraries have not been updated to work with Python 3. I have been using Python 2, primarily because I use some of those Python 2[-only] libraries, but an increasing proportion of them are migrating to Python 3, and I anticipate shifting to Python 3 in the near future.</p>
2040-
<p>For more on the topic, I recommend a very well documented IPython Notebook, which includes numerous helpful examples and links, by <a href="http://sebastianraschka.com/">Sebastian Raschka</a>, <a href="http://nbviewer.ipython.org/github/rasbt/python_reference/blob/master/tutorials/key_differences_between_python_2_and_3.ipynb">Key differences between Python 2.7.x and Python 3.x</a> ... or <a href="https://www.google.com/q=python%202%20vs%203">googling Python 2 vs 3</a>.</p>
2041-
<p>I received an email request from a Python 3 programmer who suggested that a relatively minor change in this notebook would enable it to run with Python 2 or Python 3: importing the <code>print_function</code> from <a href="https://docs.python.org/2/library/__future__.html"><code>__future__</code></a>, and changing my <a href="https://docs.python.org/2/reference/simple_stmts.html#print"><code>print</code> statements (Python 2)</a> to <a href="https://docs.python.org/3/library/functions.html#print"><code>print</code> function calls (Python 3)</a>. Although a relatively minor conceptual change, it necessitates the changing of many cells to reflect the Python 3 <code>print</code> syntax.</p>
2042-
<p>I find the arguments for <a href="https://www.python.org/dev/peps/pep-3105/">making <code>print</code> a function rather than statement</a> compelling - especially as it is more consistent with printing functionality in many other programming langugages - and so while I do not want to convert this notebook to a Python 3 notebook, I have implemented this change so that it can be used in either Python 2 or Python 3. However, while I have verified that it still works in Python 2, I have not tested it in Python 3.</p>
2043-
<p>I also find the arguments for <a href="https://www.python.org/dev/peps/pep-0238/">changing the division operator</a> compelling, so will import that as well. Without this import in Python 2, <code>1 / 2</code> returns <code>0</code> (the integer portion of the quotient); with this import, <code>1 / 2</code> returns <code>0.5</code>, and if you want only the integer portion of the quotient (<em>floor division</em>), you can use <code>1 // 2</code> (which works the same way in Python 2 and Python 3).</p>
2044-
<p>Note that if you don't understand some/any of the above discussion about Python 2 and Python 3, it should not affect your ability to understand the rest of this notebook.</p>
2040+
<p>For more on the topic, I recommend a very well documented IPython Notebook, which includes numerous helpful examples and links, by <a href="http://sebastianraschka.com/">Sebastian Raschka</a>, <a href="http://nbviewer.ipython.org/github/rasbt/python_reference/blob/master/tutorials/key_differences_between_python_2_and_3.ipynb">Key differences between Python 2.7.x and Python 3.x</a>, the <a href="http://python-future.org/compatible_idioms.html">Cheat Sheet: Writing Python 2-3 compatible code</a> by Ed Schofield ... or <a href="https://www.google.com/q=python%202%20vs%203">googling Python 2 vs 3</a>.</p>
2041+
<p><a href="https://twitter.com/ncoghlan_dev">Nick Coghlan</a>, a CPython core developer, sent me an email suggesting that relatively minor changes in this notebook would enable it to run with Python 2 <em>or</em> Python 3: importing the <code>print_function</code> from the <a href="https://docs.python.org/2/library/__future__.html"><strong><code>__future__</code></strong></a> module, and changing my <a href="https://docs.python.org/2/reference/simple_stmts.html#print"><code>print</code> <em>statements</em> (Python 2)</a> to <a href="https://docs.python.org/3/library/functions.html#print"><code>print</code> <em>function calls</em> (Python 3)</a>. Although a relatively minor conceptual change, it necessitated the changing of many individual cells to reflect the Python 3 <code>print</code> syntax. I also needed to replace a few functions that are no longer available in Python 3 with related functions that are available in both versions; I've added notes in nearby cells where the incompatible functions were removed explaining why they are related ... and no longer available.</p>
20452042
</div>
20462043
</div>
20472044
</div>
20482045
<div class="cell border-box-sizing code_cell rendered">
20492046
<div class="input">
20502047
<div class="prompt input_prompt">
2051-
In&nbsp;[2]:
2048+
In&nbsp;[1]:
20522049
</div>
20532050
<div class="inner_cell">
20542051
<div class="input_area">

Python_for_Data_Science_all.ipynb

+4-10
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"metadata": {
33
"name": "",
4-
"signature": "sha256:bcca0950b7dac5cf922034044015c39bca27062f58925c71f26294b7f0bfd371"
4+
"signature": "sha256:f066be0cc350e6372bbdb872eb18175b0f4453d758f4206d4d337a6a9f7e6fde"
55
},
66
"nbformat": 3,
77
"nbformat_minor": 0,
@@ -350,15 +350,9 @@
350350
"source": [
351351
"There are 2 major versions of Python in widespread use: [Python 2](https://docs.python.org/2/) and [Python 3](https://docs.python.org/3/). Python 3 has some features that are not backward compatible with Python 2, and some Python 2 libraries have not been updated to work with Python 3. I have been using Python 2, primarily because I use some of those Python 2[-only] libraries, but an increasing proportion of them are migrating to Python 3, and I anticipate shifting to Python 3 in the near future.\n",
352352
"\n",
353-
"For more on the topic, I recommend a very well documented IPython Notebook, which includes numerous helpful examples and links, by [Sebastian Raschka](http://sebastianraschka.com/), [Key differences between Python 2.7.x and Python 3.x](http://nbviewer.ipython.org/github/rasbt/python_reference/blob/master/tutorials/key_differences_between_python_2_and_3.ipynb) ... or [googling Python 2 vs 3](https://www.google.com/q=python%202%20vs%203).\n",
353+
"For more on the topic, I recommend a very well documented IPython Notebook, which includes numerous helpful examples and links, by [Sebastian Raschka](http://sebastianraschka.com/), [Key differences between Python 2.7.x and Python 3.x](http://nbviewer.ipython.org/github/rasbt/python_reference/blob/master/tutorials/key_differences_between_python_2_and_3.ipynb), the [Cheat Sheet: Writing Python 2-3 compatible code](http://python-future.org/compatible_idioms.html) by Ed Schofield ... or [googling Python 2 vs 3](https://www.google.com/q=python%202%20vs%203).\n",
354354
"\n",
355-
"I received an email request from a Python 3 programmer who suggested that a relatively minor change in this notebook would enable it to run with Python 2 or Python 3: importing the `print_function` from [`__future__`](https://docs.python.org/2/library/__future__.html), and changing my [`print` statements (Python 2)](https://docs.python.org/2/reference/simple_stmts.html#print) to [`print` function calls (Python 3)](https://docs.python.org/3/library/functions.html#print). Although a relatively minor conceptual change, it necessitates the changing of many cells to reflect the Python 3 `print` syntax.\n",
356-
"\n",
357-
"I find the arguments for [making `print` a function rather than statement](https://www.python.org/dev/peps/pep-3105/) compelling - especially as it is more consistent with printing functionality in many other programming langugages - and so while I do not want to convert this notebook to a Python 3 notebook, I have implemented this change so that it can be used in either Python 2 or Python 3. However, while I have verified that it still works in Python 2, I have not tested it in Python 3.\n",
358-
"\n",
359-
"I also find the arguments for [changing the division operator](https://www.python.org/dev/peps/pep-0238/) compelling, so will import that as well. Without this import in Python 2, `1 / 2` returns `0` (the integer portion of the quotient); with this import, `1 / 2` returns `0.5`, and if you want only the integer portion of the quotient (*floor division*), you can use `1 // 2` (which works the same way in Python 2 and Python 3).\n",
360-
"\n",
361-
"Note that if you don't understand some/any of the above discussion about Python 2 and Python 3, it should not affect your ability to understand the rest of this notebook."
355+
"[Nick Coghlan](https://twitter.com/ncoghlan_dev), a CPython core developer, sent me an email suggesting that relatively minor changes in this notebook would enable it to run with Python 2 *or* Python 3: importing the `print_function` from the [**`__future__`**](https://docs.python.org/2/library/__future__.html) module, and changing my [`print` *statements* (Python 2)](https://docs.python.org/2/reference/simple_stmts.html#print) to [`print` *function calls* (Python 3)](https://docs.python.org/3/library/functions.html#print). Although a relatively minor conceptual change, it necessitated the changing of many individual cells to reflect the Python 3 `print` syntax. I also needed to replace a few functions that are no longer available in Python 3 with related functions that are available in both versions; I've added notes in nearby cells where the incompatible functions were removed explaining why they are related ... and no longer available."
362356
]
363357
},
364358
{
@@ -370,7 +364,7 @@
370364
"language": "python",
371365
"metadata": {},
372366
"outputs": [],
373-
"prompt_number": 2
367+
"prompt_number": 1
374368
},
375369
{
376370
"cell_type": "heading",

README.md

+10-4
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@ This short primer on [Python](http://www.python.org/) is designed to provide a r
44

55
The primer is spread across a collection of [IPython Notebooks](http://ipython.org/notebook.html), and the easiest way to use the primer is to [install IPython Notebook](http://ipython.org/install.html) on your computer. You can also [install Python](https://www.python.org/downloads/), and manually copy and paste the pieces of sample code into the Python interpreter, as the primer only makes use of the Python standard libraries.
66

7-
There are three versions of the primer. Two versions contain the entire primer in a single notebook:
7+
There are three versions of the primer. Two versions are compatible with Python 2 or Python 3), and contain the entire primer in a single notebook:
88

99
* Single IPython Notebook: [Python_for_Data_Science_all.ipynb](Python_for_Data_Science_all.ipynb)
1010
* Single web page (HTML): [Python_for_Data_Science_all.html](Python_for_Data_Science_all.html)
1111

12-
The other version divides the primer into 5 separate notebooks:
12+
The other version divides the primer into 5 separate notebooks (Python 2 only):
1313

1414
* [Introduction](1_Introduction.ipynb)
1515
* [Data Science: Basic Concepts](2_Data_Science_Basic_Concepts.ipynb)
@@ -29,11 +29,17 @@ There are also 2 data files, based on the [mushroom dataset](https://archive.ics
2929

3030
## Change Log
3131

32+
2015-02-23
33+
34+
* Added attribution for suggested changes to accommodate Python 3 to [Nick Coghlan](https://twitter.com/ncoghlan_dev)
35+
3236
2015-02-22
3337

3438
* Added `from __future__ import print_function, division` for Python 3 compatibility
35-
* Updated `simple_ml.py` to also use Python 3 `print_function` and `division`
36-
* Changed "call by reference" to "call by sharing"
39+
* Updated `simple_ml.py` and `SimpleDecisionTree.py` to also use Python 3 `print_function` and `division`
40+
* Replaced `xrange()` (Python 2 only) with `range()` (Python 2 or 3)
41+
* Replaced `dict.iteritems()` (Python 2 only) with `dict.items()` (Python 2 or 3)
42+
* Changed ["call by reference"](https://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_reference) to ["call by sharing"](https://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_sharing)
3743
* Added `isinstance()` (and reference to duck typing) to section on `type()`
3844
* Added variable for `delimiter` rather than hard-coding `'|'` character
3945
* Cleaned up various cells

SimpleDecisionTree.py

+10-8
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from __future__ import print_function, division
2+
13
''' A class to implement a simple decision tree (based on ID3)
24
'''
35

@@ -38,22 +40,22 @@ def _create(self, instances, candidate_attribute_indexes, target_attribute_index
3840
# If the dataset is empty or the candidate attributes list is empty, return the default value.
3941
if not instances or not candidate_attribute_indexes:
4042
if trace:
41-
print '{}Using default class {}'.format('< ' * trace, default_class)
43+
print('{}Using default class {}'.format('< ' * trace, default_class))
4244
return default_class
4345

4446
# If all the instances have the same class label, return that class label
4547
elif len(class_labels_and_counts) == 1:
4648
class_label = class_labels_and_counts.most_common(1)[0][0]
4749
if trace:
48-
print '{}All {} instances have label {}'.format('< ' * trace, len(instances), class_label)
50+
print('{}All {} instances have label {}'.format('< ' * trace, len(instances), class_label))
4951
return class_label
5052
else:
5153
default_class = simple_ml.majority_value(instances, target_attribute_index)
5254

5355
# Choose the next best attribute index to best classify the instances
5456
best_index = simple_ml.choose_best_attribute_index(instances, candidate_attribute_indexes, target_attribute_index)
5557
if trace:
56-
print '{}Creating tree node for attribute index {}'.format('> ' * trace, best_index)
58+
print('{}Creating tree node for attribute index {}'.format('> ' * trace, best_index))
5759

5860
# Create a new decision tree node with the best attribute index and an empty dictionary object (for now)
5961
tree = {best_index:{}}
@@ -66,13 +68,13 @@ def _create(self, instances, candidate_attribute_indexes, target_attribute_index
6668

6769
for attribute_value in partitions:
6870
if trace:
69-
print '{}Creating subtree for value {} ({}, {}, {}, {})'.format(
71+
print('{}Creating subtree for value {} ({}, {}, {}, {})'.format(
7072
'> ' * trace,
7173
attribute_value,
7274
len(partitions[attribute_value]),
7375
len(remaining_candidate_attribute_indexes),
7476
target_attribute_index,
75-
default_class)
77+
default_class))
7678

7779
# Create a subtree for each value of the the best attribute
7880
subtree = self._create(
@@ -99,8 +101,8 @@ def _classify(self, tree, instance, default_class=None):
99101
return default_class
100102
if not isinstance(tree, dict):
101103
return tree
102-
attribute_index = tree.keys()[0]
103-
attribute_values = tree.values()[0]
104+
attribute_index = list(tree.keys())[0]
105+
attribute_values = list(tree.values())[0]
104106
instance_attribute_value = instance[attribute_index]
105107
if instance_attribute_value not in attribute_values:
106108
return default_class
@@ -115,7 +117,7 @@ def evaluate_accuracy(self, instances, default_class=None):
115117
predicted_labels = self.classify_list(instances, default_class)
116118
actual_labels = [x[0] for x in instances]
117119
counts = Counter([x == y for x, y in zip(predicted_labels, actual_labels)])
118-
return counts[True], counts[False], float(counts[True]) / len(instances)
120+
return counts[True], counts[False], counts[True] / len(instances)
119121

120122

121123
def pprint(self):

0 commit comments

Comments
 (0)