En que vídeo se escribió esta linea de código?
@click.argument('client_uid')
Básicos del Lenguaje
Guía de instalación y conceptos básicos
Archivos y slides del curso práctico de Python
IMPORTANTE: Instalando Ubuntu Bash en Windows para facilitarte el seguimiento del curso desde Windows.
¿Qué es la programación?
¿Por qué programar con Python?
Operadores matemáticos
Variables y expresiones
Presentación del proyecto
Funciones
Usando funciones en nuestro proyecto
Operadores lógicos
Estructuras condicionales
Uso de strings y ciclos
Strings en Python
Operaciones con Strings en Python
Operaciones con strings y el comando Update
Operaciones con strings y el comando Delete
Operaciones con strings: Slices en python
For loops
While loops
Iterators and generators
Estructuras de Datos
Uso de listas
Operaciones con listas
Agregando listas a nuestro proyecto
Diccionarios
Agregando diccionarios a nuestro proyecto
Tuplas y conjuntos
Tuplas y conjuntos en código
Introducción al módulo collections
Python comprehensions
Búsquedas binarias
Continuando con las Búsquedas Binarias
Manipulación de archivos en Python 3
Uso de objetos y módulos
Decoradores
Decoradores en Python
¿Qué es la programación orientada a objetos?
Programación orientada a objetos en Python
Scopes and namespaces
Introducción a Click
Definición a la API pública
Clients
Servicios: Lógica de negocio de nuestra aplicación
Interface de create: Comunicación entre servicios y el cliente
Actualización de cliente
Interface de actualización
Manejo de errores y jerarquía de errores en Python
Context managers
Python en el mundo real
Aplicaciones de Python en el mundo real
Conclusiones finales
Python 2 vs 3 (Conclusiones)
Clases bonus
Entorno Virtual en Python y su importancia: Python en el mundo real
No tienes acceso a esta clase
¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera
David Aroesti
Aportes 100
Preguntas 18
En que vídeo se escribió esta linea de código?
@click.argument('client_uid')
El **feedback ** es bueno para la plataforma, hasta ahora he visto pocas quejas de estas últimas clases, y las pocas quejas solo reciben un “disculpa, para la próxima lo arreglamos”, creo que seria mejor que los moderadores o personal de apoyo pusiera una nota al pie del video explicando los errores de la clase ( claro que no son atribuibles al profe, que dicho sea de paso es excelente). en fin es mi humilde opinión.
Mal, a partir del video 39 esto se fue para abajo, parese que estan correteando a David
Mi solución al reto
@clients.command()
@click.argument('client_uid', type=str)
@click.pass_context
def delete(ctx, client_uid):
""" Delete a client """
client_service = ClientService(ctx.obj['clients_table'])
client_list = client_service.list_clients()
client = [client for client in client_list if client['uid'] == client_uid]
if client:
client_service.delete_client(client)
click.echo('Cliente deleted')
else:
click.echo('Client not found')
def delete_client(self, client_to_be_deleted):
clients_list = self.list_clients()
clients_list.remove(client_to_be_deleted[0])
self._save_to_disk(clients_list)
😄
Me aparecía este error, lo solucioné poniendo “self” a la función “_save_to_disk()” y añadiendo " mode=‘w’ " en el “with open” de la misma función
Para los que les pueda interesar les dejo todo mi código en el siguiente repositorio:
https://github.com/crissebasbol/Ex_platzi_sales
Jajajajajaja se mancharon, cómo carajos vamos a poder resolver el reto de la función eliminar si no nos han explicado nada acerca de la librería click?? Aunque hayamos realizado los cursos anteriores de la ruta, a esta altura del curso no sabemos qué estamos escribiendo, solo hacemos que funcione
No me gusta decir estas cosas, pero casualmente los cursos que menos me han gustado son los de el profesor David Aroesti, siempre quedo con demasiadas dudas en sus cursos!!
Esta es mi solución de delete:
La función delete en commands.py es casi igual a update y no utilice nada en services.py
@clients.command()
@click.pass_context
def delete(ctx):
"""Deletes a client"""
client_uid = click.prompt('Client UID to delet', type=str)
client_service = ClientService(ctx.obj['clients_table'])
clients_list = client_service.list_clients()
client = [client for client in clients_list if client['uid'] != client_uid]
client_service._save_to_disk(client)```
commands
@clients.command()
@click.argument('client_uid',
type=str)
@click.pass_context
defdelete(ctx, client_uid):
"""delete a client"""
client_service = ClientService(ctx.obj['clients_table'])
clients_list = client_service.list_clients()
client = [client for client in clients_list if client['uid'] != client_uid]
if client:
client_service. _save_to_disk(client)
click.echo('Client removed')
else:
click.echo('Client not found')
En el de services no modifique nada, solo reutilize la funcion _save_to_disk, en el de commands, modifique en el comprehension la condicion (==) y la remplaze por (!=), la logica usada fue: agregar a la lista todos los clientes simpre y cundo no sea el uid sea indistinto al uid del cliente ingresado.
de esta manera guarda todos menos el que deseamos eliminar, esa es una alternativa
Definitivamente estas ultimas clases han estado de busca el error de edición 😕
El código del instructor no me funcionó. Recibía este error:
_TypeError: save_to_disk() takes 1 positional argument but 2 were given
Se resuelve muy fácil agregado al método _ save_to_disk _ su “seft”.
Resulto esto, recibía este error:
FileNotFoundError: [Errno 2] No such file or directory: ‘.clients.csv.tmp’
También se resolvía muy sencillo agregando _ _save_to_disk _ en open el argumento mode=“w”.
Con esto funcionó perfecto. Lo que no entiendo es por qué le funcionó al instructor. Pienso que es un error de edición en el video. Un novato se pude frustrar muy fácilmente con un error como este. Todo lo deben solucionar.
El reto:
En service.py
def delete_client(seft, delete_client):
clients = seft.list_clients()
for client in clients:
if client["uid"] == delete_client.uid:
clients.remove(delete_client.to_dict())
seft._save_to_disk(clients)
En command.py:
def delete(ctx, client_uid):
"""Borra un cliente"""
client_service = ClientService(ctx.obj["clients_table"])
client_list = client_service.list_clients()
client = [client for client in client_list if client["uid"] == client_uid]
if client:
client = Clients(**client[0])
client_service.delete_client(client)
click.echo("Client deleted")
else:
click.echo("Client not found")
Hola! Les dejo el código de mi implementación para lo que vimos en el curso, lo hice en español y agregué un sistema de inventario en el que se pueden crear, actualizar, borrar, leer y vender productos. Todos los PR o forks son bienvenidos. Saludos, compañeros:)
El link del repo es: https://github.com/thebdsw320/cli-sistema-inventario
En la clase anterior a David se le olvido colocar el modo en el que abria el archivo, deben corrergirlo.
funcion _save_to_disk de services.py
en vez de:
with open(tmp_table_name) as f:
Escriban lo siguiente:
with open(tmp_table_name, mode = 'w') as f:
¿Qué significa el doble * en la siguiente linea?
client = _update_client_flow(Client(**client[0]))
Yo tambien tuve algunos problemas a la hora de correr el programa, pero asi es como se aprende mejor buscando las soluciones, leer un poco la documentacion de click te ayuda a orientarte con los ejemplos que tiene, si te dan el programa ya hecho no es lo mismo, claro que un feedback al final estaria bien hay algunos que somos noob de cero, pero hasta con un error de dedo un error logico, me tarde 2 dias en encontrar que habia puesto click.command y no clients.command
ahhaah Exito si nos frustramos con ese tipo de detalles, en el trabajo que te espera que te den codigos ya hechos y sin errores xD
entre otros errores, falta agregar el parametro self, asi como el modo mode='w'
cuando se edita el archivo en la función def _save_to_disk(self, clients):
…
✅ Les paso el repositorio de GitHub que creé con los archivos del curso, por si quieren echarle un ojo.👀
Mi solución en el services, los commands la función de delete es igual a la del update
import csv
import os
from clients.model import Client
class ClientService:
def __init__(self, table_name):
self.table_name = table_name
def create_client(self, client):
with open(self.table_name, mode='a') as f:
writer = csv.DictWriter(f, fieldnames=Client.schema())
writer.writerow(client.to_dict())
def list_clients(self):
with open(self.table_name, mode='r') as f:
reader = csv.DictReader(f, fieldnames=Client.schema())
return list(reader)
def update_client(self, updated_client):
clients = self.list_clients()
updated_clients = []
for client in clients:
if client['uid'] == updated_client.uid:
updated_clients.append(updated_client.to_dict())
else:
updated_clients.append(client)
self._save_to_disk(updated_clients)
def delete_client(self, client_to_delete):
clients = self.list_clients()
for i, client in enumerate(clients) :
if client['uid'] == client_to_delete:
clients.remove(clients[i])
else:
continue
self._save_to_disk(clients)
def _save_to_disk(self, clients):
temp_table_name = self.table_name + '.tmp'
with open(temp_table_name, mode='w') as f:
writer = csv.DictWriter(f, fieldnames=Client.schema())
writer.writerows(clients)
os.remove(self.table_name)
os.rename(temp_table_name, self.table_name)```
Mi solución a este reto:
def delete_client(self, client_to_be_deleted):
clients = self.list_clients()
for client in clients:
if client['uid'] == client_to_be_deleted.uid:
clients.remove(client)
break
self._save_to_disk(clients)
@clients.command()
@click.argument('client_uid')
@click.pass_context
def delete(ctx, client_uid):
"""Deletes a client"""
client_service = ClientService(ctx.obj['clients_table'])
client_list = client_service.list_clients()
client = [client for client in client_list if client['uid'] == client_uid]
if client:
client_to_delete = _delete_client_flow(Client(**client[0]))
if client_to_delete:
client_service.delete_client(client_to_delete)
click.echo('Client deleted successfully')
else:
click.echo('Aborted')
def _delete_client_flow(client):
click.echo('Client with UID: {uid} was found.'.format(uid=client.uid))
delete_confirmation = click.prompt(
'Delete? [y]/N', type=str, default='Y')
if delete_confirmation.upper() == 'Y':
return client
return None```
Deben decorar la funcion update con el siguiente decorador:
@click.argument('client_uid',
type=str)
Lo haran para que el programa reciba el “uid” por la consola.
Coloquenlo de la siguiente manera:
@clients.command()
@click.argument('client_uid',
type=str) #Nos pasara el uid desde la consola
@click.pass_context
def update(ctx, client_uid):
...codigo de la funcion
Si no lo hacen el programa les dará un error
Mi solución al reto:
***** commands.py *******
@clients.command()
@click.argument('client_uid',
type=str)
@click.pass_context
def delete(ctx, client_uid):
"""Deletes a client"""
client_service = ClientService(ctx.obj['clients_table'])
client_list = client_service.list_clients()
client = [client for client in client_list if client['uid'] == client_uid]
if client:
client_service.delete_client(client[0])
click.echo('Client deleted')
else:
click.echo('Client not found')
**** services.py ****
def delete_client(self, deleted_client):
clients = self.list_clients()
for client in clients:
if client == deleted_client:
clients.remove(deleted_client)
self._save_to_disk(clients)```
Acá mi solución al reto:
def delete_client(self, client_id):
clients = self.list_clients()
for client in clients:
if client['uid'] == client_id.uid:
clients.remove(client)
self._save_to_disk(clients)
@clients.command()
@click.argument('client_uid', type=str)
@click.pass_context
def delete(ctx, client_uid):
"""Delete a cient"""
client_services = ClientServices(ctx.obj['clients_table'])
client_list = client_services.list_clients()
client = [client for client in client_list if client['uid'] == client_uid]
if client:
client_services.delete_client(Client(**client[0]))
click.echo('Client deleted')
else:
click.echo('Client not found')
El reto lo resolví de la siguiente manera:
def delete_client(self, client_uid):
tmp_clients = [client for client in self.list_clients() if client['uid'] != client_uid]
self._save_to_disk(tmp_clients)
@clients.command()
@click.argument('client_uid',
type=str)
@click.pass_context
def delete(ctx, client_uid):
"Deletes a client"
client_service = ClientService(ctx.obj['clients_table'])
client = [client for client in client_service.list_clients() if client['uid'] == client_uid]
if client:
client_service.delete_client(client_uid)
click.echo('Client deleted')
else:
click.echo('Client not found')
El archivo en los enlace de proyecto no está completo.
Para que el codigo funcione se debe agregar como parametro de entrada en _save_data_to_disk rows y schema, así _save_data_to_disk(rows, schema). Esto porque el codigo nesecita separa las filas a actualizar de la base de datos schema, sino crea los dos en una sola entidad y entra a error de sintaxis.
tambien es nesesario hacer este cambio en los parametros de entrada de update así:
update(self, row, schema).
El codigo al final funciona así. de lo contrario van a sufrir mucho con este error.
Mi Solución al Reto:
@clients.command()
@click.argument('client_uid',
type=str)
@click.pass_context
def delete(ctx, client_uid):
"""Deletes a client"""
client_service = ClientService(ctx.obj["clients_table"])
if click.confirm("Are you sure you want to delete the client with uid: {}".format(client_uid)):
client_service.delete_client(client_uid)
click.echo("Client Deleted")
else:
click.echo("Client not found")
def delete_client(self, client_uid):
clients = self.list_clients()
not_deleted_clients = [client for client in clients if client["uid"] != client_uid]
self._save_to_disk(not_deleted_clients)
Tuve errores ya mi cabeza no daba para el reto pero aqui lo importante delete_clients = [client for client in clients if client['uid'] != client_uid]
se le dice que si es diferente al enviando lo guarde en el codigo, no se que tan eficiente sea a la larga pero es buena idea.
.
y en command pues el del profe click.confirm
para y/N esta genial.
Mi solucion a eliminar cliente
services
import csv
import os
from clients.models import Client
class ClientService:
def __init__(self, table_name):
self.table_name = table_name
def create_client(self, client):
with open(self.table_name, mode='a') as f:
writer = csv.DictWriter(f, fieldnames=Client.schema())
writer.writerow(client.to_dict())
def list_clients(self):
with open(self.table_name, mode='r') as f:
reader = csv.DictReader(f, fieldnames=Client.schema())
return list(reader)
def update_client(self, updated_client):
clients = self.list_clients()
updated_clients = []
for client in clients:
if client['uid'] == updated_client.uid:
updated_clients.append(updated_client.to_dict())
else:
updated_clients.append(client)
self._save_to_disk(updated_clients)
def delete_client(self, deleted_client):
clients = self.list_clients()
clients_to_save = []
for client in clients:
if client['uid'] != deleted_client.uid:
clients_to_save.append(client)
self._save_to_disk(clients_to_save)
def _save_to_disk(self, clients):
tmp_table_name = self.table_name + '.tmp'
with open(tmp_table_name, 'w') as f:
writer = csv.DictWriter(f, fieldnames=Client.schema())
writer.writerows(clients)
os.remove(self.table_name)
os.rename(tmp_table_name, self.table_name)
commands
import click
from clients.services import ClientService
from clients.models import Client
from prettytable import PrettyTable
@click.group()
def clients():
"""Manages the clients lifecycle"""
pass
@clients.command()
@click.option('-n', '--name',
type=str,
prompt=True,
help='The client name')
@click.option('-c', '--company',
type=str,
prompt=True,
help='The client company')
@click.option('-e', '--email',
type=str,
prompt=True,
help='The client email')
@click.option('-p', '--position',
type=str,
prompt=True,
help='The client position')
@click.pass_context
def create(ctx, name, company, email, position):
"""Creates a new client"""
client = Client(name, company, email, position)
service = ClientService(ctx.obj['clients_table'])
service.create_client(client)
@clients.command()
@click.pass_context
def list(ctx):
"""List all clients"""
service = ClientService(ctx.obj['clients_table'])
clients = service.list_clients()
table = PrettyTable()
table.field_names = [field.upper() for field in Client.schema()]
for client in clients:
table.add_row([
client['uid'],
client['name'],
client['company'],
client['email'],
client['position']
])
click.echo(table)
@clients.command()
@click.argument('client_uid',
type=str)
@click.pass_context
def update(ctx, client_uid):
"""Updates a client"""
service = ClientService(ctx.obj['clients_table'])
clients_list = service.list_clients()
client = [client for client in clients_list if client['uid'] == client_uid]
if client:
client = _update_client_flow(Client(**client[0]))
service.update_client(client)
click.echo('Client updated')
else:
click.echo('Client not found')
@clients.command()
@click.argument('client_uid',
type=str)
@click.pass_context
def delete(ctx, client_uid):
"""Deletes a clients"""
service = ClientService(ctx.obj['clients_table'])
clients_list = service.list_clients()
client = [client for client in clients_list if client['uid'] == client_uid]
if client:
service.delete_client(Client(**client[0]))
click.echo('Client deleted')
else:
click.echo('Client not found')
def _update_client_flow(client):
click.echo('Leave empty if you dont want to modify the value')
client.name = click.prompt('New name', type=str, default=client.name)
client.company = click.prompt(
'New company', type=str, default=client.company)
client.email = click.prompt('New email', type=str, default=client.email)
client.position = click.prompt(
'New position', type=str, default=client.position)
return client
all = clients
Dejo el reto resuelto con los metodos creados en services y en command:
En service:
En commands:
Espero les sirva! Pese a algunos saltos temporales que podrían complicar a los mas novatos, el curso está muy bueno!
Mi solucion consiste en agregar una funcion en el archivo commands y otra en la de services
#Esta es la que es encesaria agregar en el commands de donde se llama al metodo dentro de la clase ClientService
@clients.command()
@click.argument('client_uid',
type=str)
@click.pass_context
def delete(ctx, client_uid):
"""Delete a single client in te list"""
client_service = ClientService(ctx.obj['clients_table'])
client_list = client_service.list_clients()
client = [client for client in client_service.list_clients() if client['uid'] == client_uid]
_tmp_dic = client[0]
if client:
client_service.delete_client(client)
click.echo('\n\t Client {} was deleted successfully! \n'.format(_tmp_dic['name']))
else:
click.echo('\n\t Client not found... \n')
def delete_client(self, client_to_delete):
clients = self.list_clients()
num = int(len(clients))
_pivot = client_to_delete[0]
for _flag in _pivot.values():
_cnt = _flag
updated_clients = []
for client in clients:
if client['uid'] == _cnt:
pass
else:
updated_clients.append(client)
self._save_to_disk(updated_clients)
Hola les dejo el reto,
en el command .py —> esto :
@clients.command()
@click.argument('client_uid',type=str)
@click.pass_context
def delete(ctx, client_uid):
"""Delete client"""
client_service = ClientService(ctx.obj['clients_table'])
clients_list = client_service.list_clients()
client = [client for client in clients_list if client['uid'] == client_uid]
if client == []:
return click.echo('No client with this ID')
else:
client_service.delete_client(Client(**client[0]))
click.echo('Client was deleted')
y en el services .py —> esto :
def delete_client(self, deleted_client):
clients = self.list_clients()
new_list_clients = []
for client in clients:
if client['uid'] == deleted_client.uid:
continue #Jump the user wants to delete.
else:
new_list_clients.append(client)
self._save_to_disk(new_list_clients)
Espero que a alguien le sirva
< @clients.command()
@click.option("-u", “uid”, type=str, prompt=True, help = “The client uid”)
@click.pass_context
def delete(ctx, uid:str):
""“Delete a client”""
client_service = ClientsService(ctx.obj["clients_table"])
client_list = client_service.list_clients()
client = [client for client in client_list if client["uid"] == uid]
if client:
client = Client(**client[0])
client = client_service.delete_client(client)
click.echo("Client deleted!! ")
else:
click.echo("Client not found!! ")>
<def delete_client(self, client_to_del):
clients_list = self.list_clients()
for client in clients_list:
if client["uid"] == client_to_del.uid:
clients_list.remove(client)
self._save_to_disk(clients_list)>
@clients.command()
@click.argument('client_uid', type=str)
@click.pass_context
def delete(ctx, client_uid):
"""Delete a client"""
client_service = ClientService(ctx.obj['clients_table'])
client_list = client_service.list_clients()
client = [client for client in client_list if client['uid'] == client_uid]
if client:
client_service.delete_client(client[0])
click.echo('Client deleted')
else:
click.echo('Client not found')
def delete_client(self, client_to_delete):
clients = self.list_clients()
updated_clients = []
for client in clients:
if client['uid'] == client_to_delete['uid']:
pass
else:
updated_clients.append(client)
self._save_to_disk(updated_clients)
Hice el reto de Delete, y fue bastante parecido al de Update, quién lo diría, pero para variar agrege una function que nos manda un prompt para confirmar la eliminación del cliente.
def _confirm_action (label:str) -> bool:
confirmation = click.prompt(label, default="n", confirmation_prompt=True)
if confirmation.lower()[0] == "y":
return True
return False
Hola, estoy teniendo el siguiente error, espero puedan ayudarme:
my codigo es el siguiente:
Services.py
def update_client(self,updated_client):
clients=self.list_clients()
updated_clients=[]
for index, client in enumerate(clients):
if client['uid'] == updated_client.uid:
updated_clients.append(updated_client.to_dict())
else:
updated_clients.append(client)
self._save_to_disk(updated_clients)
@clients.command()
@click.argument('client_uid',
type=str)
@click.pass_context
def update(ctx,client_uid):
"""Updates a client"""
client_service=ClientService(ctx.obj['clients_table'])
client_list = client_service.list_clients()
client= [client for client in client_list if client['uid']== client_uid]
if client:
client = _update_client_flow(Client(**client[0]))
client_service.update_client(client)
click.echo('Client Updated')
else:
click.echo('Client not found')
def _update_client_flow(client):
click.echo('Leave empty if you dont want to modify the value')
client.name=click.prompt('New name', type=str,default=client.name)
client.company=click.prompt('New company', type=str,default=client.company)
client.email=click.prompt('New email', type=str,default=client.email)
client.position=click.prompt('New position', type=str,default=client.position)
return client
Solución al Reto
Modificaciones implementadas en el archivo commands
@clients.command()
@click.argument('client_uid', type=str)
@click.pass_context
def delete(ctx, client_uid):
"""Delete a client"""
client_service = ClientService(ctx.obj['clients_table'])
client_list = client_service.list_clients()
client = [client for client in client_list if client['uid'] == client_uid]
if client:
deleted_client = _delete_client_flow(Client(**client[0]))
if deleted_client:
client_service.delete_client(deleted_client)
click.echo('Client deleted')
else:
click.echo('Client not found')
def _delete_client_flow(client):
click.echo(f'Client with UID {client.uid} is to be deleted!')
return client
Modificaciones implementadas en el archivo services
def delete_client(self, deleted_client):
clients = self.list_clients()
for client in clients:
if client['uid'] == deleted_client.uid:
clients.remove(client)
break
self._save_to_disk(clients)
Va mi solución al reto:
@clients.command()
@click.argument('client_uid')
@click.pass_context
def delete(ctx, client_uid):
"""Deletes a client"""
client_service = ClientService(ctx.obj['clients_table'])
clients_list = client_service.list_clients()
client = [client for client in clients_list if client['uid'] == client_uid]
if client:
client_service.delete_client(Client(**client[0]))
click.echo('Client deleted')
else:
click.echo('Client not found')
def delete_client(self, client_to_delete):
clients = self.list_clients()
updated_clients = [
client for client in clients if client['uid'] != client_to_delete.uid]
self._save_to_disk(updated_clients)
def delete_client(self, deleted_client_uid):
clients = self.list_clients()
current_clients=[]
print(deleted_client_uid)
for client in clients:
print(client['uid'])
if client['uid']==deleted_client_uid:
pass
else:
print('here')
current_clients.append(client)
self._save_to_disk(current_clients)
@clients.command()
@click.argument('client_uid', type=str)
@click.pass_context
def delete(ctx, client_uid):
"""Deletes a client"""
client_service=ClientService(ctx.obj['clients_table'])
client_list=client_service.list_clients()
for client in client_list:
if client['uid']==client_uid:
client_to_delete=client['uid']
if client_to_delete:
client_service.delete_client(client_to_delete)
click.echo('Client deleted')
else:
click.echo('Client not found')
Este es el método delete del reto:
Para el archivo de comandos el código es:
@clients.command()
@click.argument('client_uid',type=str)
@click.pass_context
def delete(ctx, client_uid):
"""Deletes a client"""
client_service = ClientService(ctx.obj['clients_table'])
client_list = client_service.list_clients()
client = [client for client in client_list if client['uid'] == client_uid]
if client:
client_service.delete_client(Client(**client[0]))
click.echo('Client deleted')
else:
click.echo('Client not found')
Para el archivo de servicios el código es:
def delete_client(self,deleted_client):
clients = self.list_clients()
active_clients = []
for client in clients:
if client['uid'] != deleted_client.uid:
active_clients.append(client)
self._save_to_disk(active_clients)
Les comparto mi solución del desafío.
@clients.command()
@click.option('-u', '--uid', type=str, prompt=True, help='The client UID.')
@click.pass_context
def delete(ctx: click.Context, uid: str):
"""Deletes a client.
Time Complexity: O(n)
"""
client_service = ClientService(ctx.obj['clients_table'])
clients = client_service.list_clients()
found: bool = False
c: dict
for c in clients:
if c['uid'] == uid:
found = True
break
if not found:
click.echo('Client not found')
return
client_service.delete_client(uid, clients)
def delete_client(self, client_uid: str, clients: List[dict] = None):
"""Deletes a client.
Time Complexity: O(n)
Args:
client_uid (str): The client's UID.
"""
if clients is None:
clients = self.list_clients()
updated_clients: List[dict] = []
client: dict
for client in clients:
if client['uid'] != client_uid:
updated_clients.append(client)
self._save_to_disk(updated_clients)
Me costó un poco pero acá está una solución rápida y un poco inspirada en lo que comentaron mis compañeros pero con menos código
En commands_py:
Es un poco parecido al update pero en services_py solo hay que poner el nuevo diccionario con la misma fucion save to disk
Fue una odisea, sobre todo porque hay algunas cosas que no han quedado del todo claras en las clases. Además, como se ha visto hay algunos errores en el código que aparece en pantalla. En fin.
.
La verdad me costó un huevo y la mitad del otro, pero la lógica es la siguiente:
.
1.- Tener en cuenta que para eliminar un cliente necesitamos identificarlo por su id.
2.- Luego nos vamos a clients/services. Vamos a seguir el ejemplo de update_client, es decir, vamos a pasar al cliente que queremos elimianr 'deleted_client’
2.1.- Nos traemos la lista completa de clientes y lo guaradamos en una variable.
2.2.- Generamos una lista de clientes con la condición que el ID sea diferente al del cliente que queremos eliminar.
2.3.- Nota, tendríamos una lista con todos los clientes y otra excluyento al cliente que queremos eliminar.
2.4.- Lo guardamos a disco. Como esa función ya está implementada no necesitamos pensar más.
def delete_client(self, deleted_client):
clients = self.list_clients()
new_client = [client for client in clients if client['uid'] != deleted_client ]
self._save_to_disk(new_client)
3.- Nos vamos clients/commands
4.- Agregamos el argumento client_uid, porque lo vamos a necesitar.
5.- Recuperamos nuestra tabla con los clientes, 'clients_table’
6.- También recuperamos la lista con los clientes y lo guardamos en una variable, 'client_list’
7.- Creamos una lista donde excluimos al cliente que queremos eliminar.
8.- Luego hacemos una condición en la que eliminamos al cliente y enviamos un mensaje indicando que la operación se realizó
@clients.command()
@click.argument('client_uid',
type=str)
@click.pass_context
def delete(ctx, client_uid):
"""Delete a client"""
client_service = ClientService(ctx.obj['clients_table'])
client_list = client_service.list_clients()
client = [ client for client in client_list if client['uid'] != client_uid ]
if client:
client_service.delete_client(client_uid)
click.echo('Client deleted')
else:
click.echo('Client not found')
Asi quedaría el archivo services
import csv
import os
from clients.models import Client
class ClientService:
def __init__(self, table_name):
self.table_name = table_name
def create_client(self, client):
with open(self.table_name, mode='a') as f:
writer = csv.DictWriter(f, fieldnames=Client.schema())
writer.writerow(client.to_dict())
def list_clients(self):
with open(self.table_name, mode='r') as f:
reader = csv.DictReader(f, fieldnames=Client.schema())
return list(reader)
def update_client(self, updated_client):
clients = self.list_clients()
updated_clients = []
for client in clients:
if client['uid'] == updated_client.uid:
updated_clients.append(updated_client.to_dict())
else:
updated_clients.append(client)
self._save_to_disk(updated_clients)
def _save_to_disk(self, clients):
tmp_table_name = self.table_name + '.tmp'
with open(tmp_table_name, mode='w') as f:
writer = csv.DictWriter(f, fieldnames=Client.schema())
writer.writerows(clients)
os.remove(self.table_name)
os.rename(tmp_table_name, self.table_name)
Y asi quedaría el archivo command
import click
from clients.services import ClientService
from clients.models import Client
@click.group()
def clients():
"""Manages the clients lifecycle"""
pass
@clients.command()
@click.option('-n','--name',
type=str,
prompt=True,
help='The client name')
@click.option('-c','--company',
type=str,
prompt=True,
help='The client company')
@click.option('-e','--email',
type=str,
prompt=True,
help='The client email')
@click.option('-p','--position',
type=str,
prompt=True,
help='The client position')
@click.pass_context
def create(ctx, name, company, email, position):
"""Create a new clients"""
client = Client(name, company, email, position)
client_service = ClientService(ctx.obj['clients_table'])
client_service.create_client(client)
@clients.command()
@click.pass_context
def list(ctx):
"""List all clients"""
client_service = ClientService(ctx.obj['clients_table'])
clients_list = client_service.list_clients()
click.echo(' ID | NAME | COMPANY | EMAIL | POSITION')
click.echo('*'*50)
for client in clients_list:
print('{uid} | {name} | {company} | {email} | {position}'.format(
uid = client['uid'],
name = client['name'],
company = client['company'],
email = client['email'],
position = client['position']
))
@clients.command()
@click.argument('client_uid',
type=str)
@click.pass_context
def update(ctx, client_uid):
"""Update a client"""
client_service = ClientService(ctx.obj['clients_table'])
client_list = client_service.list_clients()
client = [client for client in client_list if client['uid'] == client_uid]
if client:
client = _update_client_flow(Client(**client[0]))
client_service.update_client(client)
click.echo('Client updated')
else:
click.echo('Client not found')
def _update_client_flow(client):
click.echo('Leave empty if you dont want to modify the value')
client.name = click.prompt('New name ', type=str, default=client.name)
client.company = click.prompt('New company ', type=str, default=client.company)
client.email = click.prompt('New email ', type=str, default=client.email)
client.position = click.prompt('New position ', type=str, default=client.position)
return client
@clients.command()
@click.pass_context
def delete(ctx, client_uid):
"""Delete a client"""
pass
all = clients
Truchas con los typos, si les surge un error, chequen cada clase, cada línea para que vean si la tienen igual, por una letra, una coma o un punto les puede estar fallando todo el programa.
A eso añadanle que hay unas líneas de código que escribe mal el profe, o que no aparece en la clase cuándo la escribieron. Lo bueno es que tenemos los comentarios y alguien siempre ya ha visto ese error.
Si tienen Visual studio code pueden poner el cursor sobre una variable y si esta está repetida, al presionar ctrl + d les permitirá modificar las demás variables repetidas 👌
Para eliminar clientes:
# clients/services.py
class ClientService:
# ...
def delete_client(self, deleted_client):
clients = self.read_clients()
clients = [client for client in clients if client['uid'] != deleted_client.uid]
self._save_to_disk(clients)
# ...
# clients/commands.py
@clients.command()
@click.argument('client_uid', type=str)
@click.pass_context
def delete(ctx, client_uid):
"Deletes a client"
client_service = ClientService(ctx.obj['clients_table'])
client_list = client_service.read_clients()
client = [client for client in client_list if client['uid'] == client_uid]
if len(client) > 0:
client_service.delete_client(Client(**client[0]))
click.echo('Client deleted')
else:
click.echo('Client not found')
Mi solución…
commands :
@clients.command()
@click.argument('client_uid',type=str)
@click.pass_context
def delete(ctx, client_uid):
"""Deletes a client"""
client_service = ClientService(ctx.obj['table'])
client_list = client_service.list_clients()
client = [client for client in client_list if client['uid'] == client_uid]
if client:
client_service.delete_client(client)
else:
click.echo('Client not found')
services :
def delete_client(self,old_client):
clients = self.list_clients()
new_clients= [client for client in clients if client['uid'] != old_client[0]['uid'] ]
self._save_to_disk(new_clients)
Mi solución, commands:
@clients.command()
@click.argument('client_uid',type=str)
@click.pass_context
def delete(ctx,client_uid):
"""Deletes a client"""
client_service = ClientService(ctx.obj['clients_table'])
client_list = client_service.list_clients()
client = [client for client in client_list if client['uid'] == client_uid]
if client:
client_service.delete_client(client_uid)
click.echo('Client deleted')
else:
click.echo('Client not found')
services:
def delete_client(self,client_uid):
clients = self.list_clients()
updated_clients = []
for client in clients:
if client['uid'] != client_uid:
updated_clients.append(client)
self._save_to_disk(updated_clients)
Mi solucion al metodo eliminar
#En services.py
def delete_client(self, deleted_client):
clients = self.list_clients()
updated_clients = []
for client in clients:
if client['uid'] == deleted_client.uid:
continue #Simplemente no se agrega el usuario a eliminar al tmp_clients_table
else:
updated_clients.append(client)
self._save_to_disk(updated_clients)
#En commands.py
@clients.command()
@click.argument('client_uid')
@click.pass_context
def delete(ctx, client_uid):
""" Deletes a client based on his uid """
client_service = ClientService(ctx.obj['clients_table'])
clients = client_service.list_clients()
client = [ client for client in clients if client['uid']==client_uid]
if client:
client_service.delete_client(Client(**client[0]))
click.echo('Client deleted')
else:
click.echo('Client not found')
Hola chavos!
A manera de reto por ser nuevo en python, realice el proyecto utilizando JSON en lugar de CSV, les dejo el link del repositorio por si gustan pasar a verlo o utlizarlo de inspiración.
A continuacion mi codigo en services
import csv
import os
from clients.models import Client
class ClientService:
def __init__(self, table_name):
self.table_name = table_name
def create_client(self, client):
with open(self.table_name, mode='a') as f:
writer = csv.DictWriter(f, fieldnames=Client.schema())
writer.writerow(client.to_dict())
def list_clients(self):
with open(self.table_name, mode='r') as f:
reader = csv.DictReader(f, fieldnames=Client.schema())
return list(reader)
def update_client(self, updated_client):
clients = self.list_clients()
updated_clients = []
for client in clients:
if client['uid'] == updated_client.uid:
updated_clients.append(updated_client.to_dict())
else:
updated_clients.append(client)
self._save_to_disk(updated_clients)
def _save_to_disk(self, clients):
tmp_table_name = self.table_name + '.tmp'
with open(tmp_table_name, mode='w') as f:
writer = csv.DictWriter(f, fieldnames=Client.schema())
writer.writerows(clients)
os.remove(self.table_name)
os.rename(tmp_table_name, self.table_name)
def delete(self, row_uid, schema):
rows = self.list_clients()
updated_rows = [row for row in rows if row['uid'] != row_uid]
self._save_to_disk(updated_rows)
def delete_client(self, client_uid):
self.delete(client_uid, Client.schema())
Les recomiendo usar la @click.option tanto para el update como delete en lugar de @click.argument, esto porque con argument no me reconocía el client_uid como argumento. Cuando lo cambie funciono todo super bien.
Podrían subir el código a github?
Mi Services
def delete_client(self, client_uid):
clients = self.list_client()
clients_no_deleted = []
for client in clients:
if client['uid'] == client_uid:
continue
else:
clients_no_deleted.append(client)
self._save_to_disk(clients_no_deleted)
Mi solución.
Comando:
@clients.command()
@click.argument('client_uid', type = str)
@click.pass_context
def delete(ctx, client_uid):
"""Deletes a client """
client_service = ClientService(ctx.obj['clients_table'])
if client_service.delete_client(client_uid) :
click.echo('Client deleted!')
else:
click.echo('Client not in the list!')
Servicio:
def delete_client(self, client_uid):
clients = self.list_clients()
size = len(clients)
updated_clients = [client for client in clients if client['uid'] != client_uid]
updated_size = len (updated_clients)
self._save_to_disk(updated_clients)
if size == updated_size:
return False
else:
return True
Hola, mi solución al método delete:
## Delete client
def delete_client(self,deleted_client):
clients=self.list_clients()
for indx, client in enumerate (clients):
if client['uid'] == deleted_client.uid:
clients.remove(clients[indx])
else:
continue
self._save_to_disk(clients)
@clients.command()
@click.argument('client_uid',
type=str)
@click.pass_context
def delete(ctx, client_uid):
"""Deletes a client"""
client_service=ClientService(ctx.obj['clients_table'])
client_list = client_service.list_clients()
client= [client for client in client_list if client['uid']== client_uid]
if client:
client=Client(**client[0])
client_service.delete_client(client)
click.echo('Client Deleted')
else:
click.echo('Client not found')
si tienen el siguiente error “UnsupportedOperation: not writable”. Agreguen la clausula mode=‘a’, para poder guardar en disco.
def _save_to_disk(self,clients):
tmp_table_name = self.table_name + '.tmp'
with open(tmp_table_name, mode='a') as f:
writer = csv.DictWriter(f, fieldnames = ClientModel.schema())
writer.writerows(clients)
os.remove(self.table_name)
os.rename(tmp_table_name, self.table_name)```
Mi command 😄
@clients.command()
@click.argument('client_uid', type=str)
@click.pass_context
def delete(ctx, client_uid):
"""Delete a client"""
client_services = ClientService(ctx.obj['clients_table'])
client_list = client_services.list_client()
client = [client for client in client_list if client['uid'] == client_uid]
if client:
client_services.delete_client(client_uid)
click.echo('Client deleted')
else:
click.echo('Client not found')
Me está mostrando este error cuando ejecuto la línea “pv clients update XXXXXXXX”:
TypeError: update() got an unexpected keyword argument 'cliente_uid'```
No sé a qué se debe. Gracias de antemano!
Solución al reto
@clients.command()
@click.argument('client_uid',
type=str)
@click.pass_context
def delete(ctx, client_uid):
"""Deletes a client"""
client_service = Clients_Service(ctx.obj['clients_table'])
client_list = client_service.list_clients()
client = [client for client in client_list if client['uid'] == client_uid]
if client:
client = Client(**client[0])
client_service.delete_client(client)
click.echo('Client deleted')
else:
click.echo('Client not found')
def delete_client(self, deleted_client):
clients = self.list_clients()
for index, client in enumerate(clients):
if client['uid'] == deleted_client.uid:
del clients[index]
self._self_save_to_disk(clients)
def delete_client(self, deleted_client):
clients = self.list_clients()
for index, client in enumerate(clients):
if client['uid'] == deleted_client.uid:
clients.pop(index)
self._save_to_disk(clients)
def delete(ctx, client_uid):
'''Deletes a client'''
client_service = ClientService(ctx.obj['clients_table'])
client_list = client_service.list_clients()
client = [client for client in client_list if client['uid'] == client_uid]
if client:
client = Client(**client[0])
client_service.delete_client(client)
click.echo('Client Deleted')
else:
click.echo('Client not found')
Mi solución fue esta:
En “commands.py”:
@clients.command()
@click.argument('client_uid',
type=str)
@click.pass_context
def delete(ctx, client_uid):
"""Delete a client"""
client_service = ClientService(ctx.obj['clients_table'])
client_list = client_service.list_clients()
client = [client for client in client_list if client['uid'] == client_uid]
if client:
client_service.delete_client(Client(**client[0]))
click.echo('Client delete')
else:
click.echo('Client not Found')
En “services.py”:
def delete_client(self, deleted_client):
clients = self.list_clients()
deleted_clients = []
for client in clients:
if client['uid'] == deleted_client.uid:
pass
else:
deleted_clients.append(client)
self._save_to_disk(deleted_clients)
Mi recomendación es que si en alguna parte de perdiste y no entendiste que hizo David, no pierdas la calma y sobre todo no te frustres. Sé que es muy molesto los errores, pero es parte de programar.
Los errores de escritura que más cometi fue con Client, client, Clients y clients; fíjate mucho en eso. También en saber si lo que manejas es un objeto o una función, que se diferencian con los paréntesis [Igual si te queda duda usa type()]
Lo que puedes hacer es hacer un proceso de debug con algunos print(). Utiliza type() para saber que es lo que estás manejando y dir() para entender que propiedades tienes.
Como consejo si no sabes que como resolverlo, es que Delete es muy parecido a Update. Así que puedes intentar entender que hace update e implementalo con el reto.
Siéntate, prepárate algo de tomar y date a la idea de que veras una pila de errores que podrás ir resolviendo uno por uno, únicamente leyendo lo que te dice la consola, te adelanto que si bien puedes buscar el error en StackOverflow, en la mayoría de casos no te será de utilidad.
Suerte
Bueno, mi aporte:
def delete_client(self, client_to_delete):
clients = self.list_clients()
clients_after_deleting = []
for client in clients:
if client['uid'] == client_to_delete.uid:
continue;
else:
clients_after_deleting.append(client)
self._save_to_disk(clients_after_deleting)
Y:
@clients.command()
@click.argument('client_uid',
type=str)
@click.pass_context
def delete(ctx, client_uid):
"""Deletes a client"""
client_service = ClientService(ctx.obj['clients_table'])
client_list = client_service.list_clients()
client = [client for client in client_list if client['uid'] == client_uid]
if client:
client = Client(**client[0])
client_service.delete_client(client)
click.echo('Client has been Deleted!')
else:
click.echo('Client has not been found!!!')
Mi aporte
####################################################################
services.py
def delete_client(self, deleted_client):
clients = self.list_clients()
updated_clients = []
for client in clients:
if client['uid'] == deleted_client.uid:
pass
else:
updated_clients.append(client)
self._save_to_disk(updated_clients)
####################################################################
commands.py
@clients.command()
@click.argument('client_uid',
type=str)
@click.pass_context
def delete(context, client_uid):
""" Deletes a client """
client_service = ClientService(context.obj['clients_table'])
client_list = client_service.list_clients()
client = [client for client in client_list if client['uid'] == client_uid]
if client:
client = Client(**client[0])
client_service.delete_client(client)
click.echo('Client deleted')
else:
click.echo('Client not found')
(venv) joel@joel-Inspiron-5575:~/Documents/apuntes-programacion/python/platzi-ventas$ pv clients update 0abd1db5-67d4-44f7-b93b-4b0ed637bea7
Usage: pv clients update [OPTIONS]
Try "pv clients update --help" for help.
Error: Got unexpected extra argument (0abd1db5-67d4-44f7-b93b-4b0ed637bea7)
(venv) joel@joel-Inspiron-5575:~/Documents/apuntes-programacion/python/platzi-ventas$
me sale este error pero he revisado una y otra vez el codigo. esta igual que el de david, no entiendo porque no acepta el argumento.
porque si no le pongo el uid me dice que falta el argumento
def delete_client(self, deleted_client):
self._save_to_disk([
client
for client in self.list_clients()
if client['uid'] != deleted_client.uid
])
@clients.command()
@click.argument('client_uid', type=str)
@click.pass_context
def delete_client(context, client_uid):
""" Eliminación de cliente """
client_service = ClientService(context.obj['clients_table'])
client = [
client
for client in client_service.list_clients()
if client['uid'] == client_uid
]
msg = 'Cliente eliminado' if client else 'Cliente no encontrado'
if client:
client_service.delete_client(Client(**client[0]))
click.echo(msg)
Este sería el comando:
@clients.command()
@click.argument('client_uid',type=str)
@click.pass_context
def delete(ctx, client_uid):
"""Deletes a client"""
client_service = ClientService(ctx.obj['clients_table'])
clients_list = client_service.list_clients()
client = [client for client in clients_list if client['uid'] == client_uid]
if client:
client_service.delete_client(Client(**client[0]))
click.echo('Client deleted')
else:
click.echo('Client not found')
y este el servicio:
def delete_client(self,client_delete):
clients = self.list_clients()
for index,value in enumerate(clients):
if value['uid'] == client_delete.uid:
clients.pop(index)
break
self._save_to_disk(clients)
Aquí comparto mi código para delete en services.py:
def delete_client(self, deleted_client):
clients = self.list_clients()
for client in clients:
if client['uid'] == deleted_client[0]['uid']:
clients.remove(deleted_client[0])
self._save_to_disk(clients)
def _save_to_disk(self, clients):
tmp_table_name = self.table_name + '.tmp'
with open(tmp_table_name, mode='w') as f:
writer = csv.DictWriter(f, fieldnames=ClientModel.schema())
writer.writerows(clients)
os.remove(self.table_name)
os.rename(tmp_table_name, self.table_name)
En commands.py:
@clients.command()
@click.argument('client_uid', type=str)
@click.pass_context
def delete(ctx, client_uid):
"""Deletes a client"""
client_service = ClientService(ctx.obj['clients_table'])
client_list = client_service.list_clients()
client = [client for client in client_list if client['uid'] == client_uid]
if client:
click.echo(client)
client_service.delete_client(client)
click.echo('Client deleted')
else:
click.echo('Client not found')
He adaptado el código de update_cliente para que también sirva en la eliminación.
En services.py
def delete_client(self, client_to_delete):
clients = self.list_clients()
updated_clients = []
for client in clients:
if client['uid'] == client_to_delete.uid:
continue
else:
updated_clients.append(client)
self._save_to_disk(updated_clients)
Y en commands.py
@clients.command()
@click.argument('client_uid',
type=str)
@click.pass_context
def delete(ctx, client_uid):
"""Deletes a client"""
client_service = ClientService(ctx.obj['clients_table'])
client_list = client_service.list_clients()
client = [client for client in client_list if client['uid'] == client_uid]
if client:
client_service.delete_client(Client(**client[0]))
click.echo('Client deleted')
else:
click.echo('Client not found')
Que buena clase! Lejos, el mejor profe de Python
@clients.command()
@click.argument('client_uid',
type=str)
@click.pass_context
def delete(ctx, client_uid):
'''Delete a client'''
client_service = ClientService(ctx.obj['client_table'])
clients_list = client_service.list_clients()
client = [client for client in clients_list if client['uid'] == client_uid]
if client:
client_service.delete_client(Client(**client[0]))
click.echo('Client deleted')
else:
click.echo('Client not found')
def delete_client(self, client_to_delete):
clients = self.list_clients()
for idx, client in enumerate(clients):
if client['uid'] == client_to_delete.uid:
del clients[idx]
break
Funciona el código que esta en archivo?, yo trato de ver services y commands y no me funciona el proyecto.
Hola amigos, al intentar ejecutar el
pv clients update
me da el siguiente error:
Typeerror: update() missing 1 required positional argument: ‘client_uid’
Veo en muchos comentarios que los que ya han desarrollado la función delete(), metieron el decorador
@click.argument(‘client_uid’, type=str)
antes de su definición en commands.py
Dado el error que tengo en update () intenté hacer lo mismo , pero de esta vez me da otro error que es el siguiente:
Missing argument ‘CLIENT_UID’
Alguien me podría ayudar?
Muchas gracias.
Un saludo.
Aquí mi solución al reto:
def delete_client(self, client_uid):
clients = self.list_clients()
updated_clients = [client for client in clients if client['uid'] != client_uid] #Creacion list comprehension de todos los usuarios diferentes al usuario a eliminar
self._save_to_disk(updated_clients)
@clients.command()
@click.pass_context
def delete(ctx):
"""Deletes a client"""
client_uid = click.prompt('Write the id of the client to delete: ', type=str)
client_service = ClientService(ctx.obj['clients_table'])
if click.confirm('Are you sure to delete the client? '):
client_service.delete_client(client_uid)
click.echo('The client has been deleted')
@clients.command()
@click.option('-uid', '--client_uid',
type=str,
prompt=True,
help='The client uid')
@click.pass_context
def delete(context, client_uid):
"""Delete a client"""
client_service = ClientService(context.obj['clients_table'])
client_list = client_service.list_clients()
client = [client for client in client_list if client['uid'] == client_uid]
if client:
client_service.delete_client(ClientModel(**client[0]))
click.echo('Client deleted')
else:
click.echo('Client not found')
def delete_client(self, delete_client):
clients = self.list_clients()
for client in clients:
if client['uid'] == delete_client.uid:
clients.remove(client)
break
self._save_to_disk(clients)
Por qué inicializamos en cada comando un nuevo ClientService ? Por qué no inicializarlo de forma global y utilizarlo en cada comando?
Saludos
Me parece que los nombres que pone el profesor a las variables son muy confusas en cierto punto. Muchas veces, por lo menos yo, no entiendo el porque del nombre de algunas variables.
cuando ejecuto los comandos pv clients --help o pv clients create no hace nada, ya instale la aplicación ye tengo el ambiente virtual bien instalado
que podría tener mal si al ejecutar los comandos desde el entorno virtual no hacen nada :
(platzi-ventas) C:\platzi-ventas>pv clients --help
(platzi-ventas) C:\platzi-ventas>pv clients create
(platzi-ventas) C:\platzi-ventas>
DEF UPDATE
ULTRA SENCILLO Y FACIL DE ENTENDER
@clients.command()
@click.argument('client_name',
type=str)
@click.pass_context
def update(ctx,client_name):
"""Update a client"""
client_service= ClientService(ctx.obj['client_table'])
client_service.update_client(client_name)
SERVICE.PY**
FUNCION UPDATE
def update_client(self, client_name):
clients=self.list_clients("u")
search=self.search(client_name)#BUSCAMOS SI EL CLIENTE EXISTE
if search==True:
click.echo("FOUNDED")
else:
click.echo("NOT FOUNDED")
return
updated_client=self._values()
clientes_actualizados= []
for client in clients:
if client['name']==client_name:
clientes_actualizados.append(updated_client.to_dict())
else:
clientes_actualizados.append(client)
self._save_to_disk(clientes_actualizados)
def _save_to_disk(self,clients):
tmp_table=self.table_name+'.tmp'
with open(tmp_table, mode='w') as f:
writer=csv.DictWriter(f,fieldnames=Client.schema())
writer.writerows(clients)
os.remove(self.table_name)
os.rename(tmp_table,self.table_name)
import click
from clients.services import ClientServices
from clients.models import Client
@click.group()
def clients():
""" Manages the clients lifecycle"""
pass
@clients.command()
@click.option('-n', '--name',
type=str,
prompt=True,
help='The client name')
@click.option('-c', '--company',
type=str,
prompt=True,
help='The client Company')
@click.option('-e', '--email',
type=str,
prompt=True,
help='The client email')
@click.option('-p', '--position',
type=str,
prompt=True,
help='The client position')
@click.pass_context
def create(ctx, name, company, email, position):
"""Create a new client """
client = Client(name, company, email, position)
client_service = ClientServices(ctx.obj['clients_table'])
client_service.create_client(client)
@clients.command()
@click.pass_context
def list_clients(ctx):
"""List all clients"""
client_services = ClientServices(ctx.obj['clients_table'])
client_list = client_services.list_clients()
click.echo(' ID | NAME | COMPANY | EMAIL | POSITION')
click.echo('*'*50)
for client in client_list:
print('{uid} | {name} | {company} | {email} | {position}'.format(
uid = client['uid'],
name = client['name'],
company = client['company'],
email = client['email'],
position = client['position']
))
@clients.command()
@click.argument('client_uid', type=str)
@click.pass_context
def update(ctx, client_uid):
"""Update a client """
client_service = ClientServices(ctx.obj['clients_table'])
client_list = client_service.list_clients()
client = [client for client in client_list if client['uid'] == client_uid]
if client:
client = _update_client_flow(Client(**client[0]))
client_service.update_client(client)
click.echo('Client Updated')
else:
click.echo('Client not found')
def _update_client_flow(client):
click.echo('Leave empty if you do not want to modify the value')
client.name = click.prompt('New Name', type=str, default=client.name)
client.company = click.prompt('New Company', type=str, default=client.company)
client.email = click.prompt('New Email', type=str, default=client.email)
client.position = click.prompt('New Position', type=str, default=client.position)
return client
@clients.command()
@click.argument('client_uid', type=str)
@click.pass_context
def delete(ctx, client_uid):
"""Delete a client"""
client_service = ClientServices(ctx.obj['clients_table'])
client_list = client_service.list_clients()
client = [client for client in client_list if client['uid'] == client_uid]
if client:
client_service._delete_client(Client(**client[0]))
click.echo('Remove it')
else:
click.echo('Client not found')
@clients.command()
@click.argument('client_uid', type=str)
@click.pass_context
def search(ctx, client_uid):
"""Search a client """
client_service = ClientServices(ctx.obj['clients_table'])
client_found = client_service.search_client(client_uid)
click.echo(' ID | NAME | COMPANY | EMAIL | POSITION')
click.echo('*'*50)
for client in client_found:
print('{uid} | {name} | {company} | {email} | {position}'.format(
uid = client['uid'],
name = client['name'],
company = client['company'],
email = client['email'],
position = client['position']
))
all = clients
import click
from clients.services import ClientServices
from clients.models import Client
@click.group()
def clients():
""" Manages the clients lifecycle"""
pass
@clients.command()
@click.option('-n', '--name',
type=str,
prompt=True,
help='The client name')
@click.option('-c', '--company',
type=str,
prompt=True,
help='The client Company')
@click.option('-e', '--email',
type=str,
prompt=True,
help='The client email')
@click.option('-p', '--position',
type=str,
prompt=True,
help='The client position')
@click.pass_context
def create(ctx, name, company, email, position):
"""Create a new client """
client = Client(name, company, email, position)
client_service = ClientServices(ctx.obj['clients_table'])
client_service.create_client(client)
@clients.command()
@click.pass_context
def list_clients(ctx):
"""List all clients"""
client_services = ClientServices(ctx.obj['clients_table'])
client_list = client_services.list_clients()
click.echo(' ID | NAME | COMPANY | EMAIL | POSITION')
click.echo('*'*50)
for client in client_list:
print('{uid} | {name} | {company} | {email} | {position}'.format(
uid = client['uid'],
name = client['name'],
company = client['company'],
email = client['email'],
position = client['position']
))
@clients.command()
@click.argument('client_uid', type=str)
@click.pass_context
def update(ctx, client_uid):
"""Update a client """
client_service = ClientServices(ctx.obj['clients_table'])
client_list = client_service.list_clients()
client = [client for client in client_list if client['uid'] == client_uid]
if client:
client = _update_client_flow(Client(**client[0]))
client_service.update_client(client)
click.echo('Client Updated')
else:
click.echo('Client not found')
def _update_client_flow(client):
click.echo('Leave empty if you do not want to modify the value')
client.name = click.prompt('New Name', type=str, default=client.name)
client.company = click.prompt('New Company', type=str, default=client.company)
client.email = click.prompt('New Email', type=str, default=client.email)
client.position = click.prompt('New Position', type=str, default=client.position)
return client
@clients.command()
@click.argument('client_uid', type=str)
@click.pass_context
def delete(ctx, client_uid):
"""Delete a client"""
client_service = ClientServices(ctx.obj['clients_table'])
client_list = client_service.list_clients()
client = [client for client in client_list if client['uid'] == client_uid]
if client:
client_service._delete_client(Client(**client[0]))
click.echo('Remove it')
else:
click.echo('Client not found')
@clients.command()
@click.argument('client_uid', type=str)
@click.pass_context
def search(ctx, client_uid):
"""Search a client """
client_service = ClientServices(ctx.obj['clients_table'])
client_found = client_service.search_client(client_uid)
click.echo(' ID | NAME | COMPANY | EMAIL | POSITION')
click.echo('*'*50)
for client in client_found:
print('{uid} | {name} | {company} | {email} | {position}'.format(
uid = client['uid'],
name = client['name'],
company = client['company'],
email = client['email'],
position = client['position']
))
all = clients
retos cumplidos
Ahora si, despues de muchos intentos, funconando.
mi codigo del reto:
def delete_client(self, uid):
clients = self.list_clients()
updated_clients = list()
for cli in clients:
if cli['uid'] == uid:
pass
else:
updated_clients.append(cli)
self._save_to_disk(updated_clients)```
commands.py:
@clients.command()
@click.argument(‘client_uid’,
type=str)
@click.pass_context
def delete(ctx, client_uid):
""“delete a client”""
client_service = ClientService(ctx.obj[‘clients_table’])
client_list = client_service.list_clients()
deleted_client = [client for client in client_list if client['uid'] == client_uid]
if deleted_client:
client_service.delete_client(client_uid)
click.echo('client successfully deleted')
else:
click.echo('client not found')```
Mi solución al reto. Funciona similar a Update con $pv clients update <uid>
Mis métodos de list se lama read y read_clients por si ven la diferencia:
**
services.py**
def delete_client(self, deleted_client):
clients = self.read_clients()
updated_clients = []
for client in clients:
if client['uid'] != deleted_client.uid:
updated_clients.append(client)
self._save_to_disk(updated_clients)
@clients.command()
@click.argument('client_uid',
type=str)
@click.pass_context
def delete(ctx, client_uid):
"""Deletes a client"""
client_service = ClientService(ctx.obj['clients_table'])
clients_list = client_service.read_clients()
client = [client for client in clients_list if client['uid'] == client_uid]
if client:
client = Client(**client[0])
client_service.delete_client(client)
click.echo('Client deleted')
else:
click.echo('Client not found')
¡Mi solucion al reto!
en el archivo services.py
def delete_client(self,deleted_client_uid):
clients=self.list_client()
not_deleted_clients=[]
for client in clients:
if client['uid'] != deleted_client_uid:
not_deleted_clients.append(client)
self._save_to_disk(not_deleted_clients)
y en el archivo commands.py
@clients.command()
@click.pass_context
@click.argument('client_uid',type=str)
def delete(ctx,client_uid):
"""Delete a client"""
client_service=ClientService(ctx.obj['clients_table'])
client_list = client_service.list_client()
client = [client for client in client_list if client['uid']==client_uid]
if client:
client_service.delete_client(client_uid)
click.echo('Client deleted')
else:
click.echo('Client not found')```
Hay algo que si tengo que decir de este ejercicio con el api, uno usualmente sigue el código, que esta ejecutando el profesor, y sale un error, entonces vas a descargar los archivos y el diferente el código 😕 realmente un tema importante a nivel de explicacion del codigo implementado no se esta haciendo acá 😦
Aquí les comparto una solución al reto: Método delete:
archivo “services.py”: Creamos el metodo delete_client(), el cual usa un dictionary comprehension para detectar el cliente que queremos borrar (sólo usamos 3 lineas de código). Los demás clientes los guarda en la lista “final_clients” y la guarda en disco.
def delete_client(self, del_client):
clients = self.list_clients()
final_clients = [client for client in clients if not (client['uid'] == del_client.uid)]
self._save_to_disk(final_clients)
archivo “commands.py”: Creamos el comando delete(), que es muy similar al código del comando update(). El comando delete() llama al método delete_client() que creamos en el archivo anterior.
@clients.command()
@click.argument('client_uid', type=str)
@click.pass_context
def delete(ctx, client_uid):
"""Deletes a client"""
client_service = ClientService(ctx.obj['clients_table'])
client_list = client_service.list_clients()
client = [client for client in client_list if client['uid'] == client_uid]
if client:
client_service.delete_client(Client(**client[0]))
click.echo('Client deleted')
else:
click.echo('Client not found')
Me encanto esta práctica, gracias profesor David Aroesti!
Esta fue mi solución
[commands.py]
@clients.command()
@click.argument('client_email',
type=str)
@click.pass_context
def delete(ctx, client_email):
"""Delete a client"""
clients_service = ClientService(ctx.obj['clients_table'])
clients_list = clients_service.list_clients()
client_to_delete = [client for client in clients_list
if client['email'] == client_email]
if client_to_delete:
# print('cliente no descomprimido:::')
# print(client_to_delete)
# print('cliente descomprimido:::')
# print(**client_to_delete)
client_to_delete = Client(**client_to_delete[0])
clients_service.delete_client(client_to_delete)
click.echo('Client {} deleted'.format(client_email))
else:
click.echo('Client {} not found'.format(client_email))
def delete_client(self, client_to_delete):
clients = self.list_clients()
updated_clients = []
for client in clients:
if client['email'] == client_to_delete.email:
pass
else:
updated_clients.append(client)
self._save_to_disk(updated_clients)
Les comparto la documentacion de Click esta super genial para entender esta clase si te sientes un poco perdido.
Hasta ahorita he notado bastante hate sobre el curso, estamos en un curso para aprender a desarrollar y siendo una comunidad tan grande me decepciona la actitud de algunos compañeros.
Prefiero 100% pagar los cursos de platzi y aprender lo que yo quiero en un año y generar ingresos, y no pagar durante 5 años una universidad que quizá aprenda el 80 o 90% de lo que estudie ahí.
bueno algo confuso de errores, pero viendo comentarios solucionamos el error
A continuación mi código en command
import click
from clients.services import ClientService
from clients.models import Client
@click.group()
def clients():
"""Manages the clients lifeclycle"""
pass
@clients.command()
@click.option('-n', '--name',
type=str,
prompt=True,
help='The client name')
@click.option('-c', '--company',
type=str,
prompt=True,
help='The client company')
@click.option('-e', '--email',
type=str,
prompt=True,
help='The client email')
@click.option('-p', '--position',
type=str,
prompt=True,
help='The client position')
@click.pass_context
def create(ctx, name, company, email, position):
"""Creates a new cliente"""
client_service = ClientService(ctx.obj['clients_table'])
client = Client(name, company, email, position)
client_service.create_client(client)
@clients.command()
@click.pass_context
def list(ctx):
"""List all clientes"""
client_service = ClientService(ctx.obj['clients_table'])
client_list = client_service.list_clients()
click.echo(' ID | NAME | COMPANY | EMAIL | POSITION')
click.echo('*' * 100)
for client in client_list:
click.echo('{uid} | {name} | {company} | {email} | {position}'.format(
uid=client['uid'],
name=client['name'],
company=client['company'],
email=client['email'],
position=client['position']
))
@clients.command()
@click.argument('client_uid', type=str)
@click.pass_context
def update(ctx, client_uid):
"""Updates a clients"""
client_service = ClientService(ctx.obj['clients_table'])
client_list = client_service.list_clients()
client = [client for client in client_list if client['uid'] == client_uid]
if client:
client = _update_client_flow(Client(**client[0]))
client_service.update_client(client)
click.echo('Client update')
else:
click.echo('Client not found')
def _update_client_flow(client):
click.echo('Leave empty if you dont want to modify the value')
client.name = click.prompt('New name', type=str, default=client.name)
client.company = click.prompt('New company', type=str, default=client.company)
client.email = click.prompt('New email', type=str, default=client.email)
client.position = click.prompt('New position', type=str, default=client.position)
return client
@clients.command()
@click.argument('client_uid', type=str)
@click.pass_context
def delete(ctx, client_uid):
"""Delete a client"""
client_service = ClientService(ctx.obj['clients_table'])
if click.confirm('Are you sure want to delete the client with uid: {}'.format(client_uid)):
client_service.delete_client(client_uid)
all = clients
Hola, la verdad no he podido entender, es muy rápido y aunque uno repita los videos no logro entender que está haciendo, estoy así desde que empezó los diferentes archivos…
Aquí hay información de como utilizar la instrucción:
@click.pass_context
https://click.palletsprojects.com/en/7.x/complex/
(yo tuve dudas de lo que hacia y cuando utilizarlo)
No he podido correr mi código, no logro conectar los métodos de comands con pv. Este es el error que me aparace
D:\Vacaciones\Python\pv> pv clients create
Usage: pv clients [OPTIONS] COMMAND [ARGS]…
Try “pv clients --help” for help.
Error: No such command “create”.
<import click
from clientes.servicios import ClientService
from clientes.modelos import Client
@click.group()
def clients():
# Maneja el ciclo de los clientes
pass
@click.command()
@click.option('-n', '--name',
type = str,
prompt = True,
help = 'The client name')
@click.option('-c', '--company',
type = str,
prompt = True,
help = 'The client company')
@click.option('-e', '--email',
type = str,
prompt = True,
help = 'The client email')
@click.option('-p', '--position',
type = str,
prompt = True,
help = 'The client position')
@click.pass_context
def create(ctx, name, company, email, position):
#Crea un nuevo cliente
client = Client(name, company, email, position)
client_service = ClientService(ctx.obj['clients_table'])
client_service.create_client(client)
@click.command()
@click.pass_context
def list(ctx):
#List all clients
client_service = ClientService(ctx.obj['clients_table'])
clients_list = client_service.list()
click.echo(' ID | Name | Company | Email | Position ')
click.echo ('*'*50)
for client in clients_list:
click.echo ( ' {uid} | {name} | {company} | {email} | {position}'.format(
uid = client['uid'],
name = client['name'],
company = client['company'],
email = client['email'],
position = client['position'],))
@click.command()
@click.pass_context
def update(ctx, cliente_id):
#Updates a client
pass
@click.command()
@click.pass_context
def delete(ctx, cliente_id):
# Deletes a client
pass
all = clients>
<import click
from clientes import comandos as comandos_clientes
CLIENTS_TABLE = '.clients.csv'
@click.group()
@click.pass_context
def cli(ctx):
ctx.obj = {}
ctx.obj['clients_table'] = CLIENTS_TABLE
cli.add_command(comandos_clientes.all)>
¿Quieres ver más aportes, preguntas y respuestas de la comunidad?