Exercicis: Programació orientada a objectes
Llicència: CC BY-NC-SA 4.0
(Reconeixement - NoComercial - CompartirIgual) 🅭
Objectius
En aquests exercicis treballarem:
Definició de classes en Python.
Atributs d'instància i d'atribut de classe.
Mètodes d'instància i especials.
Encapsulament bàsic i validació de dades.
Els exercicis marcats amb ✅ seran corregits a classe.
Estructura del projecte
Tots els exercicis han de complir amb la següent estructura:
Cada exercici ha d'anar dins del directori corresponent.
El nom del fitxer ha de coincidir amb el títol de l'exercici.
El format de l'eixida del programa ha de ser consistent amb el format demanat.
La lògica d'aplicació ha d'estar organitzada en classes i mètodes; és recomanable afegir docstrings.
Exercicis
ud4/exercises
✅ person.py
Crea una classe Person amb els atributs name i age.
Afegiu els mètodes següents:
greet() : Mostra per pantalla el text amb el format:
Hola, sóc {name} i tinc {age} anys.
is_adult() : Retorna True si age >= 18, sinó False.
__str__() : Retorna una cadena amb una representació amb el format:
Person(name={name}, age={age})
L'execució principal del programa ha de crear una instància de Persona
a partir de dades llegides per entrada estàndard i cridar els mètodes definits.
Exemple d'ús
Entrada
Introdueix el nom: Marta
Introdueix l'edat: 20
Eixida
Hola, sóc Marta i tinc 20 anys.
És major d'edat: True
Representació: Persona(nom=Marta, edat=20)
✅ rectangle.py
Crea una classe Rectangle amb els següents atributs:
x : Posició en l'eix X del vèrtex inferior esquerre.
y : Posició en l'eix Y del vèrtex inferior esquerre.
width : Ample del rectangle.
height : Alt del rectangle.
Implementa mètodes:
Rectangle(width, height, x=0, y=0) : Constructor que inicialitza els atributs.
area() : Retorna l'àrea del rectangle.
perimeter() : Retorna el perímetre del rectangle.
is_square() : Retorna True si el rectangle és un quadrat.
set_position(x, y) : Estableix la posició del rectangle a (x, y).
move(dx, dy) : Desplaça el rectangle en dx i dy.
contains(px, py) : Retorna True si el punt (px, py) està dins del rectangle.
__str__() : Retorna una cadena amb la representació del rectangle.
Exemple d'ús
r = Rectangle ( 3 , 4 , x = 1 , y = 1 )
print ( "Area:" , r . area ())
print ( "Perimeter:" , r . perimeter ())
print ( "Is square:" , r . is_square ())
print ( "Contains (2, 2):" , r . contains ( 2 , 2 ))
Area: 12
Perimeter: 14
Is square: False
Contains (2, 2): True
circle.py
Crea una classe Circle amb els següents atributs:
x : Posició en l'eix X (centre).
y : Posició en l'eix Y (centre).
radius : Radi del cercle.
Implementa mètodes:
__init__(radius, x=0, y=0) : Constructor que inicialitza el radi i la posició. Ha de validar que el radi siga positiu .
area() : Retorna l'àrea del cercle.
circumference() : Retorna la circumferència del cercle.
set_radius(new_radius) : Permet canviar el radi, aplicant la mateixa validació .
contains(px, py) : Retorna True si el punt (px, py) es troba dins o a la vora del cercle.
__str__() : Retorna una cadena amb la representació del cercle amb el format:
Circle(radius={radius}, center=({x}, {y}))
Pots utilitzar math.PI per accedir a la constant \(\pi\)
Exemple d'ús
c = Circle ( radius = 5 , x = 1 , y = 1 )
print ( c )
print ( f "Àrea: { c . area () : .2f } " )
print ( f "Circumferència: { c . circumference () : .2f } " )
print ( "Conté el punt (3, 3):" , c . contains ( 3 , 3 ))
print ( "Conté el punt (7, 7):" , c . contains ( 7 , 7 ))
Eixida
Circle(radius=5, center=(1, 1))
Àrea: 78.54
Circumferència: 31.42
Conté el punt (3, 3): True
Conté el punt (7, 7): False
✅ library.py
Crea la classe Library que permetrà emmagatzemar instàncies de la classe Book,
els quals tenen els atributs isbn, title, year.
La classe Library ha de tindre els següents mètodes:
books() : Retorna una llista amb els llibres.
find(isbn) : Retorna el llibre amb el ISBN indicat. Si no existeix, retorna None.
contains(isbn) : Retorna True si existeix un llibre amb el ISBN indicat.
add(book) : Afegeix un llibre a la biblioteca.
remove(isbn) : Elimina i retorna el llibre amb el ISBN indicat. Si no s'ha trobat, retorna None.
size() : Retorna el nombre de llibres.
print_books() : Mostra per pantalla la llista dels llibres amb el format:
- {isbn}: {title} ({year})
El programa ha de mostrar un menú a l'usuari que li permeta realitzar les següents accions:
Afegir un nou llibre.
Eliminar un llibre existent per ISBN.
Informarà del llibre que s'ha eliminat.
Mostrara un missatge d'error si no s'ha trobat.
Mostrar els llibres existents.
Indicarà si encara no hi ha cap llibre a la biblioteca.
✅ robot.py
Implementa i prova la classe Robot que representa un robot que es pot moure en un pla bidimensional (2D).
classDiagram
class Robot {
- x
- y
- speed
+ Robot(x, y, speed)
+ accelerate()
+ decelerate()
+ up()
+ down()
+ left()
+ right()
+ \_\_str\_\_()
}
Atributs
x, y: coordenades del robot.
speed: velocitat del robot.
Constructors
Robot(x, y, speed): crea un robot a les coordenades i velocitat especificada.
Per defecte, el valor de tots els atributs és 0.
La velocitat ha d'estar entre 0 i 10.
Si s'especifica per baix de 0, la velocitat serà 0.
Si s'especifica per dalt de 10, la velocitat serà 10.
Mètodes
timer.py
Crea la classe Timer que funcione com un temporitzador simple.
Timer(seconds): Crea un temporitzador amb els segons indicats.
tick(): Decrementa el temps en 1 segon.
reset(): Reinicia el temporitzador al temps inicial.
add(seconds): Afegeix els segons especificats al temporitzador.
__str__() retorna una representació en format hh:mm:ss.
Ampliació
Timer.from_str(str): construeix un temporitzador a partir d'un str en el format hh:mm:ss.
user-account.py
Crea la classe UserAccount que representa un compte d'usuari d'un sistema Linux.
Atributs:
username : Nom d'usuari.
uid : Identificador d'usuari. Ha de ser un enter positiu.
gid : Identificador de grup. Ha de ser un enter positiu.
home : Directori d'inici.
shell : Intèrpret de comandes per defecte.
Mètodes:
__str__() : Retorna una cadena amb la representació del compte d'usuari amb el format:
UserAccount(username={username}, uid={uid}, gid={gid}, home={home}, shell={shell})
format_passwd() : Retorna una cadena amb el format del fitxer /etc/passwd:
{username}:{uid}:{gid}:{home}:{shell}
is_system_user() : Retorna True si el uid és menor que 1000, sinó False.
L'entrada principal del programa ha de crear instàncies de UserAccount
i guardar-les en una llista a partir de línies llegides des de l'entrada estàndard
en el format del fitxer /etc/passwd.
Exemple d'ús
Entrada
root:x:0:0:/root:/bin/bash
alice:x:1001:1001:/home/alice:/bin/zsh
bob:x:1002:1002:/home/bob:/bin/bash
Eixida
UserAccount(username=root, uid=0, gid=0, home=/root, shell=/bin/bash)
És usuari del sistema: True
Format /etc/passwd: root:0:0:/root:/bin/bash
UserAccount(username=alice, uid=1001, gid=1001, home=/home/alice, shell=/bin/zsh)
És usuari del sistema: False
Format /etc/passwd: alice:1001:1001:/home/alice:/bin/zsh
UserAccount(username=bob, uid=1002, gid=1002, home=/home/bob, shell=/bin/bash)
És usuari del sistema: False
Format /etc/passwd: bob:1002:1002:/home/bob:/bin/bash
✅ permissions.py
Crea una classe Permissions que representa els permisos d’un usuari sobre un recurs.
Atributs
read (bool)
write (bool)
execute (bool)
Mètodes
__str__(): retorna una representació en format rwx, on cada lletra apareix si el permís està activat, o - si no.
Exemple: r-x (read i execute, sense write)
enable(permission): activa un permís ('r', 'w' o 'x').
disable(permission): desactiva un permís.
toggle(permission): canvia l’estat d’un permís.
has(permission): retorna True si el permís està activat.
__eq__(other): compara si dos conjunts de permisos són iguals.
__or__(other): retorna un nou objecte Permissions amb la unió dels permisos.
__and__(other): retorna un nou objecte Permissions amb la intersecció dels permisos.
Exemple d'ús
p1 = Permissions ( read = True , write = False , execute = True )
p2 = Permissions ( read = True , write = True , execute = False )
print ( p1 ) # r-x
print ( p2 ) # rw-
print ( p1 & p2 ) # r--
print ( p1 | p2 ) # rwx
print ( p1 == p2 ) # False
p1 . enable ( 'w' )
print ( p1 ) # rwx
ip-address.py
Crea la classe IpAddress que representa una adreça IP.
La creació d'una IP vindrà donada a partir d'un str amb el format: X.X.X.X\N,
on X és cadascun dels bytes i N són els bits de la màscara de subxarxa.
El programa ha de validar que els valors són correctes:
X ha d'estar entre 0 i 255.
N ha d'estar entre 1 i 30.
Ha de proporcionar els següents mètodes:
__str()__ : Retorna la representació de la IP en el format X.X.X.X\N.
ip_address() : Retorna la IP com a cadena X.X.X.X.
subnet_mask() : Retorna la màscara de subxarxa en format X.X.X.X.
net_address() : Retorna la IP de la xarxa.
broadcast() : Retorna la IP de broadcast de la xarxa.
is_net_address() : Retorna True si és una adreça de xarxa.
is_broadcast() : Retorna True si és una adreça de broadcast.
is_host_address() : Retorna True si és una adreça d'host vàlida.
is_on_subnet(ip) : Retorna True si la IP indicada està dins de la mateixa subxarxa.
__eq__() , __lt__() , __le__() , __gt__() , __ge__() per comparar adreces IP.
📌 Aquest document pot quedar desactualitzat després d’imprimir-lo. Pots consultar la versió més recent
a la pàgina web .
🌿 Abans d’imprimir aquest document, considera si és realment necessari. Redueix el consum de paper i ajuda a protegir el nostre entorn.