Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPhilip Withnall <philip@tecnocode.co.uk>2013-08-23 03:56:40 (GMT)
committer Philip Withnall <philip@tecnocode.co.uk>2013-08-23 03:56:40 (GMT)
commite4d030ee6eedde4eb0322469d542437e539cdb39 (patch)
treefeb77fd5ab0de7242d6ef4ab6005a9489213fc18
parent77f06d4b7c4c069482cbab607ab15fa03796e789 (diff)
Write ‘Python functions and classes’ part
This section is complete in English, but is yet to be translated to Spanish. Mañana.
-rw-r--r--python-functions-and-classes.tex275
1 files changed, 245 insertions, 30 deletions
diff --git a/python-functions-and-classes.tex b/python-functions-and-classes.tex
index 483810e..77ee771 100644
--- a/python-functions-and-classes.tex
+++ b/python-functions-and-classes.tex
@@ -64,6 +64,36 @@ print('El numero mas pequeno es %i' % minimo)
\end{lstlisting}
\end{frame}
+\subsection{\en{Recursion}\es{Recursividad}}
+
+\en{Functions allow for a new type of control flow: they allow for
+\emph{recursion}. Recursion is where a function calls itself and uses the return
+value from the call in its calculation. A typical example of this is in
+computing mathematical factorials. It's possible to implement this calculation
+using a loop, but it's more natural to implement using recursion, as this
+mirrors the mathematical definition of factorials.}
+\es{TODO}
+
+\en{As with \texttt{while} loops, ensure your recursion always terminates, or
+you will get an infinite recursion, like an infinite loop.}
+\es{TODO}
+
+\begin{frame}[fragile]
+\frametitle{\en{Recursion}\es{Recursividad}}
+\begin{lstlisting}[language=Python]
+def factorial(n):
+ if n == 0:
+ return 1
+ else:
+ return n * factorial(n - 1)
+
+# factorial(n) == n * factorial(n - 1)
+# == n * (n-1) * factorial(n - 2)
+# ...
+# == n * (n-1) * ... * 1
+\end{lstlisting}
+\end{frame}
+
\section{\en{Imports}\es{Importaciónes}}
@@ -121,7 +151,12 @@ its variables are separate from those of other instances of the same class.}
\en{Why collect functions and variables together? It makes maintaining a large
program a lot easier by separating code and data out into different components
-which don't interfere with each other.}
+which don't interfere with each other. You can think of a class as describing
+a single real-world object, such as a vehicle or a table. All the state
+(variables) associated with that object is in the class, and all the actions
+which can be performed on that object are declared as methods (functions) of the
+class. Classes don't \emph{always} correspond to real-world objects, but the
+principle stands.}
\es{TODO}
\en{To define a class in Python, use the \texttt{class} statement, followed by
@@ -142,30 +177,38 @@ for the class. It is called when an instance of the class is created, as shown
next.}
\es{TODO}
+\en{Every method in a class must have \texttt{self} as its first
+parameter --- this is what makes it a \emph{method}, rather than a
+\emph{function}. \texttt{self} is a reference to the object the method is being
+called on, and permits access to the object's variables and other methods. To
+refer to a variable or method in an instance of a class, use \texttt{self} and
+a dot followed by the variable or method name.}
+\es{TODO}
+
\begin{frame}[fragile]
\frametitle{\en{Defining classes}\es{Definición de clases}}
\begin{lstlisting}[language=Python]
class Vehiculo(object):
- def __init__(self, matricula, numero_de_ruedas):
+ def __init__(self, matricula, ruedas):
self._matricula = matricula
- self._numero_de_ruedas = numero_de_ruedas
+ self._ruedas = ruedas
- # Asumir vehiculos estan gravados por el numero de ruedas
+ # Asumir vehiculos estan gravados por
+ # el numero de ruedas.
def calcular_impuesto(self):
- return 100 * self._numero_de_ruedas
+ return 100 * self._ruedas
def dar_matricula(self):
return self._matricula
\end{lstlisting}
- % TODO: syntax; constructors as special methods; inheritance; properties (definition)
- % TODO: class as bundle of functions and variables; instantiating a class; getting/setting a property; calling a method from outside and inside a class instance
\end{frame}
\en{Instantiating a class is similar to calling a function; you're effectively
calling the \texttt{\_\_init\_\_} function, and can pass it parameters as
-normal. Once you've instantiated a class, you can call its methods using a
-dot --- just like calling \texttt{append()} on a list. All lists are actually
-instances of a \texttt{list} class.}
+normal. It returns an instance of the class (an object). Once you've
+instantiated a class, you can call its methods using a dot --- just like calling
+\texttt{append()} on a list. All lists are actually instances of a \texttt{list}
+class.}
\es{TODO}
\begin{frame}[fragile]
@@ -175,7 +218,7 @@ mi_coche = Vehiculo('AB99BA', 4)
mi_moto = Vehiculo('CB21TA', 2)
print(mi_coche.calcular_impuesto()) # da 400
-print(mi_coche.dar_matricula()) # da 'AB99BA'
+print(mi_coche.dar_matricula()) # da 'AB99BA'
print(mi_moto.calcular_impuesto()) # da 200
\end{lstlisting}
\end{frame}
@@ -196,32 +239,39 @@ can call the old code in the parent class by using \texttt{super()}.}
\begin{frame}[fragile]
\frametitle{\en{Defining classes}\es{Definición de clases}}
+% Note: I've taken the liberty of using 2-space indents here to get everything
+% to fit on the slide. I'm sorry.
\begin{lstlisting}[language=Python]
class Coche(Vehiculo):
- def __init__(self, matricula, peso):
- # Todos los coches tienen 4 ruedas
- super(Coche, self).__init__(matricula, 4)
- self._peso = peso
+ def __init__(self, matricula, peso):
+ # Todos los coches tienen 4 ruedas.
+ super(Coche, self).__init__(matricula, 4)
+ self._peso = peso
- def calcular_presion(self):
- return self._peso / 4
+ def calcular_presion(self):
+ return self._peso / 4
class Moto(Vehiculo):
- def __init__(self, matricula):
- # Todos los motos tienen 2 ruedas
- super(Moto, self).__init__(matricula, 2)
+ def __init__(self, matricula):
+ # Todos los motos tienen 2 ruedas.
+ super(Moto, self).__init__(matricula, 2)
+\end{lstlisting}
+\end{frame}
+\begin{frame}[fragile]
+\frametitle{\en{Defining classes}\es{Definición de clases}}
+\begin{lstlisting}[language=Python]
mi_coche = Coche('AB99BA', 1500)
mi_moto = Moto('CB21TA')
print(mi_coche.calcular_impuesto()) # da 400
-print(mi_coche.dar_matricula()) # da 'AB99BA'
+print(mi_coche.dar_matricula()) # da 'AB99BA'
print(mi_moto.calcular_impuesto()) # da 200
\end{lstlisting}
\end{frame}
-\subsection{\en{Private methods}\es{TODO}}
+\subsection{\en{Private methods}\es{Métodos privados}}
\en{What if you want to define a method in your class but don't want it to be
callable from outside the class? For example, a method which performs part of a
@@ -231,11 +281,89 @@ then called a \emph{private method}. The same is true for variables, although
a single-underscore is commonly used for them.}
\es{TODO}
+\en{In this example, \texttt{\_\_add\_fuel()} is a private method, and
+\texttt{\_remaining\_fuel} and \texttt{\_odometer} are private variables.
+\texttt{refuel()} is a \emph{public} method which calls
+\texttt{\_\_add\_fuel()}. Why not put the code in \texttt{\_\_add\_fuel()} into
+\texttt{refuel()}? Because there may be other methods in the class which cause
+fuel to be added to the car, and we want to re-use the code to do so.}
+\es{TODO}
+
\begin{frame}[fragile]
-\frametitle{\en{Private methods}\es{TODO}}
+\frametitle{\en{Private methods}\es{Métodos privados}}
+% Again, I've taken the liberty of using 3-space indents here to make everything
+% fit.
\begin{lstlisting}[language=Python]
class Coche(Vehiculo):
- TODO
+ def __agregar_combustible(self, cantidad):
+ self._combustible += cantidad
+
+ def repostar(self, cantidad):
+ self.__agregar_combustible(cantidad)
+ self._cuentakilometros = 0
+\end{lstlisting}
+\end{frame}
+
+
+\subsection{\en{Properties}\es{Propriedades}}
+
+\en{Often, it is helpful to have a public variable on a class which can be
+read and written to by other code. However, it is also often necessary to
+execute some code in the class when the variable is written to (for example, to
+update other state in the class which depends on that variable, or checking the
+new value is acceptable). Python has \emph{properties} for this, which are a
+special way of handling variables in a class.}
+\es{TODO}
+
+\begin{frame}[fragile]
+\frametitle{\en{Properties}\es{Propriedades}}
+\begin{lstlisting}[language=Python]
+class Vehiculo(object):
+ pasajeros = 0
+
+mi_coche = Vehiculo()
+print(mi_coche.pasajeros) # imprime '0'
+mi_coche.pasajeros = 1
+\end{lstlisting}
+\end{frame}
+
+\en{Instead of defining the variable by assigning to it, as in the first
+example, assign the result of the special \texttt{property()} function to it
+instead. The \texttt{property()} function takes the name of a ``getter'' and a
+``setter'' method as its parameters: these are called when the property is
+read or written, respectively.}
+\es{TODO}
+
+\begin{frame}[fragile]
+\frametitle{\en{Properties}\es{Propriedades}}
+\begin{lstlisting}[language=Python]
+class Vehiculo(object):
+ def __init__(self, escanos):
+ self._pasajeros = 0
+ self._escanos = escanos
+
+ def get_pasajeros(self):
+ return self._pasajeros
+
+ def set_pasajeros(self, valor):
+ if valor <= self._escanos:
+ self._pasajeros = valor
+ else:
+ print('Demasiados pasajeros!')
+
+ # Propriedad
+ pasajeros = property(get_pasajeros,
+ set_pasajeros)
+\end{lstlisting}
+\end{frame}
+
+\begin{frame}[fragile]
+\frametitle{\en{Properties}\es{Propriedades}}
+\begin{lstlisting}[language=Python]
+mi_coche = Vehiculo(5) # 5 escanos
+mi_coche.pasajeros = 3
+print(mi_coche.pasajeros) # imprime '3'
+mi_coche.pasajeros = 6 # imprime 'Demasiados!'
\end{lstlisting}
\end{frame}
@@ -253,23 +381,110 @@ method being documented.}
\frametitle{\en{Documentation}\es{Documentación}}
\begin{lstlisting}[language=Python]
class Vehiculo(object):
- """TODO"""
- def my_method(self, foo):
- """TODO"""
- return 15
+ """Un vehiculo generico.
+
+ Esto puede repostar, guardar la distancia
+ recorrida por el vehiculo, y contar el
+ numero de pasajes.
+ """
+ def repostar(self, cantidad):
+ """Anadir cantidad litros de
+ combustible para el vehiculo."""
+ self._combustible += cantidad
\end{lstlisting}
\end{frame}
\en{You can access documentation from the Python interpreter by accessing the
-\texttt{\_\_doc\_\_} member variable of the class or method.
+\texttt{\_\_doc\_\_} member variable of the class or method.}
+\es{TODO}
\begin{frame}[fragile]
\frametitle{\en{Documentation}\es{Documentación}}
\begin{lstlisting}[language=Python]
print(Vehiculo.__doc__)
+print(Vehiculo.repostar.__doc__)
print(range.__doc__)
\end{lstlisting}
\end{frame}
-% TODO: git, licensing, basic GTK+ usage, code formatting/peps
+\section{\en{Code formatting}\es{Formato de código}}
+
+\en{As with documentation, consistent and clear code formatting is important in
+making code readable. Python has two tools available to help checking programs
+for formatting errors and other errors: \texttt{pylint} and \texttt{pep8}.}
+\es{TODO}
+
+\en{They should be run after making large additions to the code, or before
+releasing a program to others.}
+\es{TODO}
+
+\begin{frame}{\en{Code formatting}\es{Formato de código}}
+\en{In a terminal:}\es{En un terminal:}
+\begin{itemize}
+ \item{\texttt{pylint \en{my-file.py}\es{mi-archivo.py}}}
+ \item{\texttt{pep8 \en{my-file.py}\es{mi-archivo.py}}}
+\end{itemize}
+\end{frame}
+
+
+\section{\en{GUIs with GTK+}\es{TODO}}
+
+\en{Creating user interfaces (GUIs) will be covered in more detail in
+\autoref{part:writing-sugar-activities}, but it's useful to cover a simple
+example now as a demonstration of the use of classes.}
+\es{TODO}
+
+\en{In the GTK+ UI toolkit, every on-screen UI element (or \emph{widget}) is an
+object --- an instance of a class. For example, there's a \texttt{Button} class
+which is instantiated for every button in a program. In this example, the
+\texttt{Window} and \texttt{Button} classes are instantiated to give a window
+containing a button. The example is cut down to its bare minimum, and is not a
+useful program.}
+\es{TODO}
+
+\begin{frame}[fragile]
+\frametitle{\en{GUI example}\es{Ejemplo de GUI}}
+\begin{lstlisting}[language=Python]
+from gi.repository import Gtk
+
+ventana = Gtk.Window('Hola mundo')
+boton = Gtk.Button('Un boton')
+ventana.add(boton)
+ventana.show_all()
+
+Gtk.main()
+\end{lstlisting}
+\end{frame}
+
+
+\section{\en{Licencing}\es{Licencias}}
+
+\en{An important part of the Sugar project is that it is free software --- in
+the sense that anyone has the freedom to read and modify the source code. To
+upload an activity to \url{http://activities.sugarlabs.org/} it must use a
+free software licence. This is important, as it allows students to view and
+learn from the code running their activities, and potentially modify it to
+improve the activities.}
+\es{TODO}
+
+\en{There are several major free software licences, and you must choose one
+which matches your ideology. The most relevant three licences are: GPL, MIT and
+BSD. The Sugar project itself uses GPL.}
+\es{TODO}
+
+\begin{frame}{\en{Licencing}\es{Licencias}}
+
+\begin{block}{}
+\url{http://gnu.org/licenses/license-recommendations.html}
+\end{block}
+
+\begin{block}{}
+\begin{description}
+ \item[GPL]{\url{http://\en{en}\es{es}.wikipedia.org/wiki/GNU_General_Public_License}}
+ \item[MIT]{\url{http://\en{en}\es{es}.wikipedia.org/wiki/MIT_License}}
+ \item[BSD]{\url{\en{http://en.wikipedia.org/wiki/BSD_licenses}
+ \es{http://es.wikipedia.org/wiki/Licencia_BSD}}}
+\end{description}
+\end{block}
+\end{frame}