Para ler e copiar python

Este é o último nivel que abordamos na aprendizaxe de Python. Non o facemos de xeito práctico, senón para fomentar a lectura e reutilización (isto é, copiar no bo sentido) de código xa feito.

Se lemos programas de complexidade media en Python ou os seus comentarios, o normal é que pareza todo moi raro, con un montón de conceptos descoñecidos, ou, aínda peor, confundidos con outros: clase, atributo. instancia, obxecto...

A idea desta páxina é que volvas cando teñas confunsión cun termo, e repases os conceptos. O obxectivo é que non soe a chino o que aparece neste código:

Este código é a parte inicial do famoso xogo do Pong escrito para a biblioteca de Pygame. En concreto o código para crear a bola que se move polo escenario e interactúa coas raquetas. Nesta páxina imos intentar aclarar que significa: class, self, __init__ porque son cousas que vas atopar seguido en calquera programa de complexidade media.

Python é un tipo de linguaxe de programación chamado multiparadigma, o cal significa que está construído dende a base utilizando distintas modalidades de linguaxes de programación. Dos tipos de paradigmas que están na base de Python os máis importantes son: 

  • O paradigma da programación estruturada, empregado nos algoritmos sinxelos, os que teñen unha ou varias funcións (ou ordes secuenciadas), que collen uns datos e devolven outros datos. Por exemplo, calcular o factorial dun número. Estes algoritmos son para aprender programación é tamén para aprender a dividir un problema (programa) complexo nunha sucesión de problemas (subprogramas) sinxelos. Estes algoritmos son os que temos utilizado na parte de Scratch a Python.
  • O paradigma da programación orientada a obxectos, empregado nos algoritmos de complexidade media. Este paradigma ou metodoloxía de programación, chamado POO (ou OOP en inglés) é a base de moitos linguaxes de programación importantes, polo que unha das vantaxes de aprender isto  en Python é que facilita enormemente aprender unha segunda linguaxe de programación se tamén é orientada a obxectos. En concreto poderías aprender facilmente Javascript se saber ler un código de Python como o anterior. Se queres ler con calma de que vai isto dos obxectos, podes ler nesta páxina.

As palabras/conceptos que necesitas ter claro para poder ler Python en modalidade POO son:

obxecto - atributo - clase - método - instancia

A isto temoslle que engadir: función, parámetro, variable, tipos de datos, estrutura de datos....

Vexamos como pode afectarnos isto para ler programas de Python. A diferencia vai estar na dificultade de partida do algoritmo a escribir ou ler (e polo tanto do problema a resolver ou o comportamento a implementar)

 

Tipo de algoritmos según complexidade Palabras e conceptos que atopamos ao ler Diagrama básico
Sinxela ou media nalgúns casos Función, método, parámetro, argumento, biblioteca ou módulo, datos simples, datos estruturados lineais.

 

Media

Todos os anteriores e ademais:

clase, instancia, obxecto, atributo...

 

Programando obxectos

Para nós os obxectos son aquilo concreto que imos programar (un algoritmo que toma uns valores de entrada e devolve uns valores, ou un comportamento, de saída, pero tamén a interación cos outros obxectos). En Scratch serían os sprites ou monecos. Aquí é un pouco máis lioso, porque os obxectos poden estar compostos por outros obxectos. Pero para entendelo mellor pensar así: un obxecto e algo que programamos (entrada-saída-comportamento).

Os obxectos poden executar funcións, escritas por nós ou chamadas dende o programa, chamadas métodos, que dependen de valores de entrada, chamados parámetros, e poden ter diversas propiedades ou condicións, chamados atributos. Por exemplo un obxecto 'Serpe Pitón' pode ter unha función para moverse coas frechas do teclado e un atributo, propiedade, de 'non é velenosa' e outra de 'peso'.

 

Apunte lingüístico: a diferencia entre argumento é parámetro viría a ser que o argumento é o nome da variable xeral, e parámetro é un valor concreto do argumento. En matemáticas isto sería que en f(x) = 2·x, x sería o argumento e cando decimos f(3) = 6, 3 é o parámetro e 6 a saída da función. Ou sexa, os argumentos son variables que toman como valores aos parámetros.

Aínda hai clases

Na programación orientada a obxectos hai unha metodoloxía moi útil (pero pode que confusa ao incio). Se crea unha clase, que ven sendo como un molde ou planilla base formada por varias funcións (métodos) e parámetros (argumentos), un molde con certas propiedades, e os obxectos e as interacións entre obxectos se crean a partir das clases definidas previamente. Imos velo coa serpe de AlgoRitmia.

instancia

 

atributos

 

métodos

 

Isto representámolo dicindo que os obxectos, que forman a base do noso programa, son instancias de clase. Collemos o molde da clase e creamos un ou varios obxectos concretos. Por exemplo coa clase Serpe(), creamos unha pitón ou unha víbora. As dúas son serpes, o cal quere decir que teñen propiedades e funcións en común, como por exemplo o seu subgrupo ('Reptil') pero logo terán propiedades, atributos, distintos, como o nome ou o feito de ser velenosas ou non.

 

 

Se queres afondar máis nesta páxina  comentan con calma o concepto de clase, e nestoutra  comentan paso a paso o famoso videoxogo Pong en función dos conceptos de programación orientada a obxectos.

 

Crear unha clase: o uso de self

Imos crear serpes concretas, obxectos, que teñan propiedades concretas (nome, ser velenosa) pero partindo dun molde previo chamado clase. Crear unha clase é como crear unha función (que logo estará composta de outras funcións), pero usando a palabra class:

class Serpe():

As clases terán unhas variables que son as propiedades, que logo terán valores concretos nos obxectos.

As clases comezan todas cunha función ou método inicial,  chamada __init__ que terá como parémetros as propiedades que vaian ter os futuros obxectos (o nome da serpe é unha variable que toma valores concretos en cada serpe), e ademais o primeiro parámetro sempre será self. Isto por que?. Self é o argumento (parámetro) que lle di ao método que estamos a aplicalo sobre o noso obxecto concreto. Confuso?. O mellor é practicar.

Apunte lingüístico: a norma para poñer nomes ás clases é CamelCase.

Imos crear diferentes serpes que teñan as seguintes propiedades (atributos): o nome, subgrupo animal e se é velenosa. En función destes valores teremos saídas diferentes.

Creamos o método inicial, que contén os 3 parámetros ou argumentos que imos utilizar para caracterizar á nosa serpe, o noso obxecto, e ademais self en primeiro lugar :

class Serpe():

    def __init__(self, nome, subgrupo, veleno):
        self.nome = nome
        self.subgrupo = subgrupo
        self.veleno = veleno

A función __init__  é coñecida en moitas páxinas como constructor.

Temos creadas unhas variables que poden almacenar os valores concretos (cando os teñamos) dunha serpe concreta (obxecto). Son chamadas self.nome, self.subgrupo e self.veleno. Agora creamos unha función, quen_son(), para utilizar o valor concreto do nome e do subgrupo:

class Serpe():

    def __init__(self, nome, categoria, veleno):
        self.nome = nome
        self.subgrupo = subgrupo
        self.veleno = veleno

    def quen_son(self):
        print ('Ola, son a ', self.nome, ' e polo tanto son un ', self.categoria)

Importante: o argumento desta función é só self por que logo utilizamos self.nome para almacenar o valor concreto do nome dunha serpe concreta.

Crear un obxecto dentro dunha clase

Agora imos crear o noso obxecto facendo unha instancia,  que ten uns atributos ou propiedades concretas, partindo da clase Serpe():

serpe1 = Serpe("Víbora", "Reptil", True)

Importante: Fíxate que na clase temos 4 parámetros ou valores e no obxecto 3. O outro é o inicial, self, e non temos que indicalo.

Pois agora podemos usar serpe1 como conxunto de datos e métodos, un obxecto, ao que podemos aplicar algún método concreto usando a sintaxe:

nome_do_obxecto.método()

Por exemplo:

serpe1.quen_son() #neste caso esto viría sendo o noso programa

Resumimos na seguinte táboa o que temos feito:

Programa Serve para
class Serpe(): Dámoslle nome a unha nova clase
   def __init__(self, nome, categoria, veleno):
        self.nome = nome
        self.subgrupo = subgrupo
        self.veleno = veleno
Esta clase terá 4 parámetros, pero so teremos que especificar 3 deles, porque o cuarto é o parámetro self.
def quen_son(self):
        print ('Ola, son a ', self.nome, ' e polo tanto son un ', self.categoria)
Definimos un método: unha función que funcionará para todos os obxectos desta clase. Este método indica un comportamento da clase: é un saúdo.
serpe1 = Serpe("Víbora", "Reptil", True)

Defino un obxecto que pertence á clase Serpe, é dicir: unha instancia . Por tanto coa  función __init__ gardarase o seguinte:

  • na variable self gardaremos serpe1
  • na variable nome gardaremos "Víbora"
  • na variable subgrupo gardaremos "Reptil"
  • na variable velenogardaremos True

 

serpe1.quen_son() Chamo ao método quen_son da clase á que pertence serpe1

 

    Podes fixarte que o de usar subgrupo como variable é un pouco parvo, pois todas as serpes son Reptís. Si, pero é para indicar un exemplo de parámetro constante. Nos exercicios podes modificar a función para que non use este parámetro.

    Engadir outra función na clase

    Engadimos outra función que use o parámetro de se unha serpe é velenosa ou non:

    def velenosa(self):
            if self.veleno:
                print('Son velenosa')
            else:
                print('Tranqui, non mordo...moito')

    Como ves, o único argumento da función é self. Pero poderíamos utilizar outros parámetros.

    Crear outro obxecto
     

    serpe2 = Serpe("Pitón", 'Reptil', False)

    Crear un programa

    Agora poderemos crear un  programa chamando as funcións que desexemos das nosas serpes. Neste caso tan sinxelo non hai moito que poidamos facer:

    serpe1.quen_son()
    serpe1.velenosa()
    serpe2.quen_son()
    serpe2.velenosa()

    Exercicios:

    1. Modifica o programa para prescindir do argumento subgrupo (pero que siga dicindo cada serpe que é un reptil)
    2. Modifica o programa para que use un bucle de consulta. Tes unha proposta na parte de abaixo do código
    3. Modifica a clase para que as serpes que non son velenosas dean unha frase tipo 'Coidado, non pisar!'
    4. Crea a túa clase e os teus obxectos en base a estes.

    Non remata aquí todo o que podes aprender de Python. Tes que saber que hai outros conceptos ou características importantes de POO que sairán en moitas páxinas de Python:

    polimorfismo-herencia-abstración-encapsulamiento e outras

    Para copiar Python

    Copiar e modificar un programa xa creado é un dos métodos fundamentais para aprender a programar. Pero temos que saber como ler ese código.

    O problema principal que vas ter é non recoñecer os métodos dun programa, en especial os que veñan dun módulo ou biblioteca. Contra isto non hai solución, paciencia, ler con calma e buscar información en internet.

    Pero podes aprender sobre eses métodos vendo a estrutura do programa e identificando as partes. Se os nomes están ben empregados pode ser máis sinxelo do que parece.

    Como norma xeral nos programas de dificultade media teremos esta estrutura de programa:

    Diagrama de bloques dun programa medio Exemplo de estrutura en Python

     

    No xogo aliens que ven de exemplo en Pygame (e do que xa falamos na páxina de Pygame) teremos esta estrutura. Podes comprobalo baixando o programa.

    if __name__ == '__main__':

    Este comando, que aparece no bucle principal é, basicamente, a maneira de executar os programas cando estamos en modo POO. Se queres ler unha boa explicación podes ir a esta páxina.