Básicos del Lenguaje

1

Guía de instalación y conceptos básicos

2

Archivos y slides del curso práctico de Python

3

IMPORTANTE: Instalando Ubuntu Bash en Windows para facilitarte el seguimiento del curso desde Windows.

4

¿Qué es la programación?

5

¿Por qué programar con Python?

6

Operadores matemáticos

7

Variables y expresiones

8

Presentación del proyecto

9

Funciones

10

Usando funciones en nuestro proyecto

11

Operadores lógicos

12

Estructuras condicionales

Uso de strings y ciclos

13

Strings en Python

14

Operaciones con Strings en Python

15

Operaciones con strings y el comando Update

16

Operaciones con strings y el comando Delete

17

Operaciones con strings: Slices en python

18

For loops

19

While loops

20

Iterators and generators

Estructuras de Datos

21

Uso de listas

22

Operaciones con listas

23

Agregando listas a nuestro proyecto

24

Diccionarios

25

Agregando diccionarios a nuestro proyecto

26

Tuplas y conjuntos

27

Tuplas y conjuntos en código

28

Introducción al módulo collections

29

Python comprehensions

30

Búsquedas binarias

31

Continuando con las Búsquedas Binarias

32

Manipulación de archivos en Python 3

Uso de objetos y módulos

33

Decoradores

34

Decoradores en Python

35

¿Qué es la programación orientada a objetos?

36

Programación orientada a objetos en Python

37

Scopes and namespaces

38

Introducción a Click

39

Definición a la API pública

40

Clients

41

Servicios: Lógica de negocio de nuestra aplicación

42

Interface de create: Comunicación entre servicios y el cliente

43

Actualización de cliente

44

Interface de actualización

45

Manejo de errores y jerarquía de errores en Python

46

Context managers

Python en el mundo real

47

Aplicaciones de Python en el mundo real

Conclusiones finales

48

Python 2 vs 3 (Conclusiones)

Clases bonus

49

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

Aprende Inglés, Desarrollo Web, AI, Ciberseguridad y mucho más.

Antes: $249

Currency
$209
Comienza ahora

Termina en:

1 Días
19 Hrs
20 Min
50 Seg

Manipulación de archivos en Python 3

32/49
Recursos

Aportes 101

Preguntas 36

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

Los archivos con punto inicial, hacen referencia a un archivo oculto.

No sé cómo al profe le funcionó jejeje, pero en el método _save_clients_to_storage() tuve que sacar el rename del statement del with open… me quedó así para que me funcionará:

def _save_clients_to_storage():
	tmp_table_name = '{}.tmp'.format(CLIENT_TABLE)
	with open(tmp_table_name, mode='w') as f:
		writer = csv.DictWriter(f, fieldnames=CLIENT_SCHEMA)
		writer.writerows(clients)

		os.remove(CLIENT_TABLE)
	os.rename(tmp_table_name, CLIENT_TABLE)

En la documentación de Python se explica que, en S.O. Windows, la función remove del módulo os lanzará una excepción si se intenta eliminar un archivo abierto. De manera similar, la función rename lanzará una excepción si se intenta renombrar un archivo cuando el nombre del archivo está en uso.

En windows hay que cerrar el archivo o te saldra error de tmp

def _save_clients_to_storage():
	tmp_table_name = '{}.tmp'.format(CLIENT_TABLE)
	with open(tmp_table_name, mode='w') as f:
		writer = csv.DictWriter( f, fieldnames= CLIENT_SCHEMA )
		writer.writerows(clients)

		os.remove(CLIENT_TABLE)
		f.close() 
		os.rename( tmp_table_name, CLIENT_TABLE )


El punto es para que el archivo sea oculto 🕵️‍♂️

le hice una modificación a la función _initialize_clients_from_storage() para que cree el archivo por si el mismo si no existe.
gracias a este articulo

def _initialize_clients_from_storage():
    if not os.path.exists(CLIENT_TABLE):
        with open(CLIENT_TABLE, mode= 'w'):
            pass
    else:
        with open(CLIENT_TABLE, mode='r') as f:
            reader = csv.DictReader(f,fieldnames=CLIENT_SCHEMA)

            for row in reader:
                clients.append(row)```

A mi me daba error en el método _save_clients_to_storage() de que no se podia cambiar el nombre al archivo porque estaba siendo utilizado por otra persona. he añadido una linea a ese método y ya funciona
Este es el metodo con el cambio hecho:

def _save_clients_to_storage():
	"""Primero lo guardamos en una tabla temporal porque no se puede
	reescribir un arhivo que ya está abierto"""
	tmp_table_name = '{}.tmp'.format(CLIENT_TABLE)
	with open(tmp_table_name, mode='w') as f:
		writer = csv.DictWriter(f, fieldnames=CLIENT_SCHEMA)
		writer.writerows(clients) ## asi escribimos varias filas
		f.close()
		os.remove(CLIENT_TABLE) ## eliminamos la tabla original
		os.rename(tmp_table_name, CLIENT_TABLE) ## renombramos la tabla temporal con el mismo nombre que tenia la tabla original

DictReader
Esta crea un objeto el cuál mapea la información leída a un diccionario cuyas llaves están dadas por el parámetro fieldnames. Este parámetro es opcional, pero cuando no se especifica en el archivo, la primera fila de datos se vuelve las llaves del diccionario.

DictWriter
Esta clase es similar a la clase DictWriter y hace lo contrario, que es escribir datos a un archivo CSV. La clase es definida como csv.DictWriter(csvfile, fieldnames, restval=’’, extrasaction=‘raise’, dialect=‘excel’, *args, **kwds)

El parámetro fieldnames define la secuencia de llaves que identifican el orden en el cuál los valores en el diccionario son escritos al archivo CSV. A diferencia de DictReader, esta llave no es opcional y debe ser definida para evitar errores cuando se escribe a un CSV.
fuente: https://code.tutsplus.com/es/tutorials/how-to-read-and-write-csv-files-in-python--cms-29907

Si le da un error similar a este:

Traceback (most recent call last):
  File "main.py", line 173, in <module>
    _save_clients_to_storage()
  File "main.py", line 26, in _save_clients_to_storage
    os.rename(tmp_table_name, CLIENT_TABLE)
PermissionError: [WinError 32] El proceso no tiene acceso al archivo porque está siendo utilizado por otro proceso: 'clients.csv.tmp' -> 'clients.csv'

Es porque dentro de la función _save_clients_to_storage(), deben de indicarle al programa que cierre el archivo f para que pueda ser guardado el archivo temporal con el mismo nombre .clients.csv. Les comparto el pequeño cambio a realizar:

def _save_clients_to_storage():
    tmp_table_name = '{}.tmp'.format(CLIENT_TABLE)
    with open(tmp_table_name, mode='w') as f:
        writer = csv.DictWriter(f, fieldnames=CLIENT_SCHEMA)
        writer.writerows(clients)

        os.remove(CLIENT_TABLE)
        f.close()
        os.rename(tmp_table_name, CLIENT_TABLE)

El . inicial en el archivo se usa para hacer de el archivo algo oculto.

Es como el _ para declarar una variable privada

Buenas tardes, a mi me funcionó con el siguiente código, tuve que hacer algunas correcciones al código expuesto por el profe.

import csv
import os

CLIENT_TABLE='.clients.csv'
CLIENT_SCHEMA = ['name','company','email','position']
clients = []

def _initialize_clients_from_storage():
	with open(CLIENT_TABLE,mode='r') as f:
		reader = csv.DictReader(f,fieldnames=CLIENT_SCHEMA)

		for row in reader:
			clients.append(row)


def _save_clients_to_storage():
	tmp_table_name = '{}.tmp'.format(CLIENT_TABLE)
	with open(tmp_table_name,mode='w') as f:
		writer = csv.DictWriter(f,fieldnames=CLIENT_SCHEMA)
		writer.writerows(clients)

	os.remove(CLIENT_TABLE)
	os.rename(tmp_table_name,CLIENT_TABLE)
		#print(CLIENT_TABLE)
		


def create_client(client):
	global clients
	if client not in clients:
		clients.append(client)
	else:
		print('Client already is in the client\'s list')


def list_clients():
	for idx,client in enumerate(clients):
		print('{uid} | {name} | {company} | {email} | {position}'.format(
uid=idx,
name=client['name'],
company=client['company'],
email = client['email'],
position = client['position'])			)
		#print('{}:{}'.format(idx,client['name']))

	
def delete_client(client_name):

	global clients

	if client_name in clients:
	   clients.remove(client_name)
	else:
		print('Client is not in clients list')

def update_client(client_name,update_client_name):
	global clients
	if client_name in clients:
		index = clients.index(client_mame)
		clients[index]=updated_name
	else:
		print('Client is not in clients list')

def search_client(client_name):
	for client in clients:
		if client!=client_name:
			continue
		else:
			return True
def list_client():
	print(clients)

def _print_welcome():
	print('*'*50)
	print('WELCOME TO PLATZI VENTAS')
	print('*'*50)
	print('what would you like to do today?')
	print('[C]reate client')
	print('[L]ist client')
	print('[S]earch client')
	print('[U]pdate client')
	print('[D]elete client')

def _get_client_field(field_name):
	field = None
	while not field:
		field = input('What is the client {}?'.format(field_name))
	return field

def _get_client_name():
	return input('what is the client name?')

if __name__ == '__main__':
	_initialize_clients_from_storage()

	_print_welcome()

	command= input()
	command= command.upper()
	if command == 'C':
		client ={
			'name': _get_client_field('name'),
			'company':_get_client_field('company'),
			'email':_get_client_field('email'),
			'position':_get_client_field('position'),
		}
		#client_name= _get_client_name()
		create_client(client)
		
	elif command == 'D':
		client_name = _get_client_name()
		delete_client(client_name)
		
		pass
	elif command == 'L':
		list_clients()
	elif command == 'S':
		client_name= _get_client_name()
		found = search_client(client_name)
		if(found):
			print('The client is in the client\'s list')
		else:
			print('Then client is not in our client\'s list'.format(client_name))
		search_client(client_name)
	elif command == 'U':
		client_name= _get_client_name()
		update_client_name= input('What is the updated client name?')
		update_client(client_name,update_client_name)
		
		pass
	else:
		print('Invalid command')

_save_clients_to_storage()

La función “_save_clientes_to_storage” genera un error.

Lo resolví poniendo las líneas de os.remove y os.rename fuera del bloque with

Para los que estan en windows y les arroja este error:

FileNotFoundError: [Errno 2] No such file or directory: '.clients.csv'

Usen la ruta del archivo completa en mi caso:

CLIENT_TABLE = 'C:\\Users\\Aeonics\\Documents\\MEGAsync\\Cursos\\Python\\Proyecto\\Proyecto_Ventas_Python\\.clients.csv'

Yo como un loco pensando que el CSV tenia que devolverme los títulos y avías agregado un código sin haberlo dicho

Me puse a ver el video varias veces a ver dónde falle

print('uid |  name  | company  | email  | position ')
print('*' * 50)

También descubrí que tienes un error que nunca comentaste ya que te falto la “e” en “fieldnames”

writer = csv.DictWriter(f, fieldnames=CLIENT_SCHEMA)

Si quieren conocer más modos de lectura de archivos pueden miran en la documentación oficial de Python

https://docs.python.org/3/library/functions.html?highlight=open#open

Para que les funcione en Windows, el nombre del archivo debe tener antes un back slash

CLIENT_TABLE = '.\clients.csv'

Me parece chido que platzi libere contenidos en youtube, debe ser mucha gente la beneficiada. Pero Me parece poco amable para los suscriptores que solo tengas la opcion de reproducir ese contenido embebido en youtube. Sobre todo cuando tu metodo de estudio ya se empezo a apoyar en los “marcadores”. Yo entiendo que asi se disparan las visualizaciones en youtube, pero me siento usado y sin opcion. ¿como lo solucionarian, dando la opcion a reproducirlo en su player con marcadores o liberando el “modulo” de toma de marcadores para que puedas usarlo “manual” en clases con contenido en youtube?

Este artículo me ayudó a entender mejor el concepto: http://book.pythontips.com/en/latest/context_managers.html
Espero a alguien más le sirva

No entiendo el por que se necesita ese archivo temporal… Yo escribi sobre el mismo archivo y no tuve problema:

def save_file():
    with open(CLIENT_TABLE, mode= "w") as f:
        writer = csv.DictWriter(f, fieldnames=CLIENT_SCHEMA)
        writer.writerows(CLIENTS)```

IMPORTANTE Si tienes este error:

<os.rename(tmp_table_name, CLIENT_TABLE)
PermissionError: [WinError 32] El proceso no tiene acceso al archivo porque está siendo utilizado por otro proceso: '.clients.csv.tmp' -> '.clients.csv'> 

Esto se debe a que no tienes una correcta indentacion de tu codigo, esa funcion deberia estar de la siguiente forma:

<def _save_clients_to_storage():
    tmp_table_name = f'{CLIENT_TABLE}.tmp'
    with open(tmp_table_name, mode = 'w') as f:
        writer = csv.DictWriter(f, fieldnames = CLIENT_SCHEMA)
        writer.writerows(clients)

    os.remove(CLIENT_TABLE)
    os.rename(tmp_table_name, CLIENT_TABLE)
> 

Ahora si no vas a tener ese error de nuevo saludos😎

Holaa
Los archivos que inician con punto (".") son archivos ocultos, para mostrarlos, escribe el siguiente comando en la terminal:

ls -al

-al: listar los archivos incluidos los ocultos 😉

El código me está arrojando el siguiente error

Traceback (most recent call last):
File “main_prof.py”, line 148, in <module>
_save_clients_to_storage()
File “main_prof.py”, line 23, in _save_clients_to_storage
writer = csv.DictWriter(f, fieldnames=CLIENT_SCHEMA)
NameError: name ‘csv’ is not defined

No entiendo porque si estoy en la carpeta correspondiente al archivo .csv que creé (" .clients.csv ")

Alguién sabe por qué puede estar pasando?

no funciona este video

Buenas noches, cómo estan?
Una consulta… para que se importa el os, cuál es su función o para qué sirve?

Los archivos que empiezan con punto (.) son archivos ocultos,
Hagan la prueba tratando de listarlos con un simple ls en el directorio donde quedó creado el archivo y verán que no se muestra el archivo.
Sin embargo Podrán verlo haciendo un ls -la, que tiene mas poderes.

¿Puedo utilizar como .csv un archivo que estoy trayendo de un sitio en Internet?. Por ejemplo (soy meteoroólogo), quiero trabajar con un csv con datos climáticos a los que puedo acceder en algun servidor público como la NOAA. Gracias por adelantado por la respuesta.

Por qué en este caso no hicimos uso de “global” para poder usar la variable PASSWORD dentro de una función?

a mi demda este error

Traceback (most recent call last):
  File "c:/Users/Aeonics/Documents/MEGAsync/Cursos/Python/Proyecto/Proyecto_Ventas_Python/main.py", line 163, in <module>
    _save_clients_to_storage()
  File "c:/Users/Aeonics/Documents/MEGAsync/Cursos/Python/Proyecto/Proyecto_Ventas_Python/main.py", line 22, in _save_clients_to_storage
    writer.writerow(clients)
  File "C:\Users\Aeonics\AppData\Local\Programs\Python\Python38\lib\csv.py", line 154, in writerow
    return self.writer.writerow(self._dict_to_list(rowdict))
  File "C:\Users\Aeonics\AppData\Local\Programs\Python\Python38\lib\csv.py", line 147, in _dict_to_list
    wrong_fields = rowdict.keys() - self.fieldnames
AttributeError: 'list' object has no attribute 'keys'

Para los que usen PC windows y les aparezca el error

FileNotFoundError: [Errno 2] No such file or directory

clients = [] 
CLIENT_TABLE ='C://Users//antho//OneDrive//Documentos//CursosPLATZI//Python//APP_curso_python//.clients.csv'
CLIENT_SCHEMA = ['name','company','email', 'position']

def _initialize_clients_from_storage():
    with open(CLIENT_TABLE, mode='r') as f:
        reader = csv.DictReader(f,fieldnames=CLIENT_SCHEMA)
        for row in reader:
            clients.append(row)

def _save_clients_to_storage():
    tmp_table_name='{}.tmp'.format(CLIENT_TABLE)
    with open(tmp_table_name, mode='w') as f:
        writer = csv.DictWriter(f,fieldnames=CLIENT_SCHEMA)
        writer.writerows(clients)
        f.close

    os.remove(CLIENT_TABLE)
    os.rename(tmp_table_name,CLIENT_TABLE)

Después de una hora viendo como solucionar los errores del codigo en MI SOLUCIÓN, les dejo un aporte que me sirvio.

*Si el codigo arranca y despues empieza a tirar muchos errores como:

  • FileNotFoundError: [Errno 2] No such file or directory:

  • PermissionError: [WinError 32] El proceso no tiene acceso al archivo porque está siendo utilizado por otro proceso: ‘clients.csv.tmp’

  1. Primero que nada tienen que solucionar los problemas del codigo, en esta seccion de comentarios muchos alumnos ya dieron la respuesta al problema

  2. Renombren el archivo .clients.csv.tmp —> clients.csv, haciendo eso mi codigo con la solucion me anduvo al 100% con todas las opciones probadas

PD:dejo mi codigo por si les sirve

import sys
import csv
import os


TABLA_CLIENTES = '.clients.csv'
CLIENTS_SCHEMA = ['name', 'company' , 'email' , 'position']
clients = []


def _initialize_clients_from_storage():
    with open(TABLA_CLIENTES, mode='r') as f:
        reader = csv.DictReader(f, fieldnames=CLIENTS_SCHEMA)
        
        for row in reader:
            clients.append(row)
        



def _save_clients_to_storage():
    tmp_table_name = '{}.tmp'.format(TABLA_CLIENTES)

    with open(tmp_table_name, mode='w') as f:
        writer = csv.DictWriter(f, fieldnames=CLIENTS_SCHEMA)
        writer.writerows(clients)

    os.remove(TABLA_CLIENTES)
    os.rename(tmp_table_name, TABLA_CLIENTES)


#Crear un cliente
def create_client(client): 
    global clients

    if client not in clients:
         clients.append(client)
    else:
        print("Su cliente ya se encuentra en la lista")

#Enlista los clientes
def list_clients():
    for idx, client in enumerate(clients): #Itera el diccionario, e imprime los datos del cliente
        print('{uid} | {name} | {company} | {email} | {position}'.format(
            uid = idx,
            name = client['name'],
            company = client['company'],
            email = client['email'],
            position = client['position']))


#Actualizar clientes
def update_client(client_name, update_client_name): #Recibe por parametros 2 variables.
    global clients

    if client_name in clients:
        del clients[update_client_name]
        client_update = {
            'name': _get_client_field('name'),
            'company': _get_client_field('company'),
            'email': _get_client_field('email'),
            'position': _get_client_field('position'),
        }
        clients.append(client_update)
    else:
        _client_not_in_list() #Imprime que el cliente no esta en la lista

#Borrar cliente
def delete_client(client_name):
    global clients 

    if client_name in clients:
        del clients[int(input('Que cliente desea eliminar?'))] #Borra el cliente, el objeto dentro de la lista, lo elimina
    else:
        _client_not_in_list()

#Buscar clientes
def search_client(client_name):
    for client in clients: #Itera los clientes
        if client != client_name:  #Si el nombre del cliente no es igual que el nombre que el usuario ingreso, continua la iteracion
            continue

        elif client == 2:
            print("EL CLIENTE NO EXISTE")

        else:  #Si lo encontro, devuelve true y comienza desde el ultimo punto
            return True


#Imprime la Pantalla de bienvenida
def _print_welcome():
    print("Bienvenidos a platzi Ventas")
    print('*' * 50)
    print("Que es lo que quieres hacer hoy?")
    print("[L] Listar clientes")
    print('[C] Crear cliente')
    print('[U] Actualizar Cliente')
    print('[D] Borrar Cliente')
    print('[S] Buscar Cliente')

def _get_client_field(field_name):
    field = None

    while not field:
        field = input('Cual es el cliente {}?'.format(field_name))

    return field


#Obtener el nombre del cliente
def _get_client_name():
    global clients
    client_name = None


    while not client_name:
        client_name = clients[int(input('Ingrese el numero del cliente'))]
    
        if client_name == 'exit':
            client_name = None
            break
    
    if not client_name:
        sys.exit()

    return client_name

#Funcion para que el cliente busque en el diccionario
def _get_client_name_diccionarie():
    global clients
    client_name = None

    while not client_name:
        client_name = clients[int(input('Ingrese el numero del cliente'))]
    
        if client_name == 'exit':
            client_name = None
            break
    
    if not client_name:
        sys.exit()

    return client_name

#Imprime que el cliente no esta en lista
def _client_not_in_list():
    return input("El cliente no se encuentra en la lista")

#Empieza nuestro codigo
if __name__ == '__main__':
    _initialize_clients_from_storage()

    _print_welcome()

    command = input()
    command = command.upper() #TRANSFORMA TODAS LAS LETRAS EN MAYUSCULAS

#Crea un cliente si el usuario apreta la letra "C"
    if command == 'C':
        client = {
            'name': _get_client_field('name'),
            'company': _get_client_field('company'),
            'email': _get_client_field('email'),
            'position': _get_client_field('position'),
        }
        create_client(client)
#Enlista los clientes si el usuario apreto "L"
    elif command == 'L':
        list_clients()

#Borra los clientes si el usuario apreto "D"
    elif command == 'D':
        client_name = _get_client_name()
        delete_client(client_name)

#Actualiza los clientes si el usuario apreto "U"
    elif  command == 'U':
        client_name = _get_client_name()
        update_client_name = int(input("Que cliente quieres actualizar?"))
        update_client(client_name,update_client_name)

#Busca los clientes si el usuario apreto "S"
    elif command == 'S':
        client_name = _get_client_name()
        found = search_client(client_name)

        if found:
            print('El cliente: {} esta en la lista de clientes.'.format(client_name))
        else:
            print("El cliente: {} no esta en nuestra lista de clientes".format(client_name))
    else:
        print('Invalid Command')

_save_clients_to_storage()
import csv
import os

CLIENT_TABLE = 'C://Users//Asus//Desktop//Respaldo//Documents//Curso PYTHON .clients.csv'
CLIENT_SCHEMA = ['name', 'company', 'email', 'position']
clients =[]

def _initialize_clients_from_storage():
	with open(CLIENT_TABLE, mode ='r') as f:
		reader = csv.DictReader(f, fieldnames= CLIENT_SCHEMA)

		for row in reader: 
			clients.append(row)

def _save_clients_to_storage ():
	tmp_table_name = '{}.tmp'.format(CLIENT_TABLE)
	with open(tmp_table_name, mode='w') as f:
		writer = csv.DictWriter(f, fieldnames=CLIENT_SCHEMA)
		writer.writerows(clients)
		

		os.remove(CLIENT_TABLE)
		f.close
		os.rename(tmp_table_name, CLIENT_TABLE) 

def  create_client(client):
	global clients

	if client not in clients:
		clients.append(client)
	else: 
		print("Client is already in the client's list")


def list_clients():
	for idx, client in enumerate(clients):
		print ('{uid}| {name} | {company} | {email} | {position}'.format(
			uid = idx, 
			name = client['name'],
			company = client ['company'],
			email= client['email'],
			position=client['position']))


def update_client(client_name, updated_name):
	global clients
	exists = 'false'

	for idx, client in enumerate(clients):

		if client_name == client['name']:
			update_client=_get_client()
			clients[index].updated(update_client)
			exists = 'false'
			break
		else: 
			exists = 'true'

	if (exists =='true'):
		print("Client is not included in client's list")

def delete_client(client_name):
	global clients

	if client_name in clients:
		clients.remove(client_name)
	else:
		print('Client is not in client´s list')

def search_client(client_name):
	for client in clients:
		if client != client_name:
			continue
		else:
			return True

def _get_client_field(field_name):
	field = None

	while  not field:
		field = input('What is the client name {}?'.format(field_name))

	return field

def _print_welcome():
	print("Welcome a la plataforma de ventas")
	print('*' * 50)
	print("What would you like to do today?")
	print('[C]reate client')
	print('[L]ist client´s')
	print('[U]update client')
	print('[D]elete client')
	print('[S]earch client')

def _get_client_name():
	client_name = None

	while not client_name:
		client_name= input('What is the client name?')

		if client_name == 'exit':
			client_name = None
			break 

	if not client_name:
		sys.exit() 

	return client_name 

if __name__ == '__main__':
	_initialize_clients_from_storage()

	_print_welcome()
	
	command = input()
	command = command.upper()

	if command == 'C':
		client= {
			'name': _get_client_field('name'), 
			'company': _get_client_field ('company'),
			'email': _get_client_field('email'),
			'position': _get_client_field('position'),
		}
		create_client(client)
		list_clients()
	elif command == 'L':
		list_clients()
	elif command == 'D':
		client_name= _get_client_name()
		delete_client(client_name)
		list_clients()
	elif command == 'U':
		client_name =_get_client_name()
		updated_client_name= input ('What is the updated client name?')
		update_client(client_name,updated_client_name)
		list_clients()
	elif command == 'S':
		client_name = _get_client_name()
		found= search = search_client(client_name)

		if found: 
			print("The client is in the client´s list")
		else:
			print("The client:{} is not in our client´s list".format(client_name))
	else:
		print('Invalid command')

	_save_clients_to_storage()

print(clients) 

Al listar los productos me genera este error. He buscado mucho (Documentación,Tutoriales, etc) la razón del por qué y no la encuentro.

Les agradecería la ayuda si a alguien le sucedió y lo resolvió

<code>
Traceback (most recent call last):
  File "main2.py", line 190, in <module>
    _save_products_to_storage()
  File "main2.py", line 21, in _save_products_to_storage
    write.writerows(product)
  File "/usr/local/Cellar/python/3.7.2_2/Frameworks/Python.framework/Versions/3.7/lib/python3.7/csv.py", line 158, in writerows
    return self.writer.writerows(map(self._dict_to_list, rowdicts))
  File "/usr/local/Cellar/python/3.7.2_2/Frameworks/Python.framework/Versions/3.7/lib/python3.7/csv.py", line 148, in _dict_to_list
    wrong_fields = rowdict.keys() - self.fieldnames
AttributeError: 'str' object has no attribute 'keys'

Por qué era lo del punto antes del nombre del archivo? ".clients.csv"
Por qué esto en windows no funciona?
Cuál sería su semejante en windows?

Archivos con que comienzan con punto por defecto el sistema operativo los identifica como ocultos. 😃

Aqui esta mi codigo corriendo:

import csv
import os
from tabulate import tabulate 
# List<Dictionary<string,string>> clients
CLIENT_TABLE = "./clients.csv"
CLIENT_SCHEMA = ["name", "company", "email", "position"]
clients = []

def _initialize_clients_from_storage():
    file_exists = os.path.isfile(CLIENT_TABLE) 
    if not file_exists:
        fh = open(CLIENT_TABLE,"w")
        fh.close()
    
    with open(CLIENT_TABLE, mode="r") as f:
        reader = csv.DictReader(f, fieldnames=CLIENT_SCHEMA)
        for row in reader:
            clients.append(row)


def _save_clients_to_storage():
    tmp_table_name = "{}.tmp".format(CLIENT_TABLE)
    with open(tmp_table_name, mode="w") as f:
        writer = csv.DictWriter(f, fieldnames=CLIENT_SCHEMA)
        writer.writerows(clients)

    os.remove(CLIENT_TABLE)
    os.rename(tmp_table_name, CLIENT_TABLE)


def create_client(client):
    global clients
    if client["name"]  not in clients:
        clients.append(client)
    else:
        print("Client is already in client\'s list") 
             
    
def list_clients():   
    global clients
    if clients:
        print('Our Clients are :')
        show=[]
        for idx,name in enumerate(clients):
            show.append(
                [
                    idx+1,
                    name["name"], 
                    name["company"],
                    name["email"],
                    name["position"],
                ])
        print(tabulate(show,headers=['N°','Name', "Company", "Email", "Position"],tablefmt='fancy_grid'))
    else:
        print(' I don´t have Clients in this moment')



def getIndexByName(client_name):
    global clients  
    idx = 0
    indexFound = False

    for _dict in clients:
        if (client_name == _dict["name"]):
            indexFound = True
            break
        idx+=1

    if not indexFound:
        idx = None

    return idx

def update_client(client_name, field_name, field_value):
    global clients
    idx =  getIndexByName(client_name)
    if idx != None:
        if field_name in clients[idx].keys():
            clients[idx][field_name] = field_value
        else:
            print("The field name does not exist in the dictionary")
    else:
        print("The user does not exist in the list")


def delete_client(client_name):
    global clients
    idx = getIndexByName(client_name)
    if idx != None:
        clients.__delitem__(idx)
    else:
        _not_in_list()

def get_client(client_name):   
    global clients
    if clients:
        print('Please find the detail information from the client: ', client_name)
        show=[]
        for idx,name in enumerate(clients):
            if name["name"] == client_name:
                show.append(
                    [
                        idx+1,
                        name["name"], 
                        name["company"],
                        name["email"],
                        name["position"],
                    ])
        print(tabulate(show,headers=['N°','Name', "Company", "Email", "Position"],tablefmt='fancy_grid'))
    else:
        print(' I don´t have Clients in this moment')

def _get_client_name():
    return input('What is the client name? ')

def _get_client_field(field_name):
    field = None
    while not field:
        field = input("What is the client {} name?".format(field_name))
    return field

def _not_in_list():
    print('Client not in list')

def _print_welcome():
    print('WELCOME TO SALES')
    print('*'*50)
    print('What would like to do? ')
    
    print('[C]reate client')
    print('[L]ist clients')
    print('[U]pdate client')
    print('[D]elete client')
    print('[S]earch client')


def _exit():
    return input('Do you want to continue? [Y/N] ').upper()

if __name__ == "__main__":
    _initialize_clients_from_storage()

    bexit = False
    while not bexit:
        _print_welcome()

        command = input().upper()

        if command == 'C':
            client =  {
                "name": _get_client_field("name"),
                "company": _get_client_field("company"),
                "email": _get_client_field("email"),
                "position": _get_client_field("position"),
            }

            create_client(client)
            list_clients()
        elif command=='L':
            list_clients()
        elif command=='U':
            client_name= input('Whats the client name? ')  
            field_name = input('Whats the field name to edit? ').lower()  
            field_value = input('Whats the new field value? ')  
            update_client(client_name , field_name, field_value) 
            list_clients()
        elif command == 'D':
            delete_client(_get_client_name())
            list_clients()
        elif command == 'S':
            client_name= _get_client_name()
            get_client(client_name)
        else:
            print('Invalid command!! ')

        _save_clients_to_storage()

        if _exit() != "Y":
            bexit = True
    
    print('Program terminated')```

El punto al inicio es para hacer del csv un archivo oculto. Si no lo pones, igual funciona, pero es mas cool ;D

Los archivos con . al inicio son archivos ocultos

En Linux si se pone punto antes del nombre del archivo este archivo se vuelve un archivo oculto .archivo.csv, ademas el archivo debe vivir en la carpeta raiz del proyecto o lo marca como no existente
Estoy en VScode y empece creando el archivo clients.csv directamente desde la carpeta y me salia error: FileNotFoundError: \[Errno 2] No such file or directory: Lo que hice, fue eliminar ese archivo y crearlo directamente desde el VScode como clients.csv Despues me permite hacer CRUD sobre el archivo
![](<import random ''' def binary_search(data, target, low, high): if low \> high: return False mid = (low + high) // 2 if target == data[mid]: return True elif target \< data[mid]: return binary_search(data, target, low, mid - 1) else: return binary_search(data, target, mid + 1, high) if __name__ == '__main__': data = [random.randint(0, 100) for _ in range(100)] data.sort() print(data) target = int(input("¿Qué número te gustaría encontrar? ")) found = binary_search(data, target, 0, len(data) - 1) print(found) ''' import random def binary_search_iterative(data, target): low, high = 0, len(data) - 1 while low \<= high: mid = (low + high) // 2 if target == data[mid]: return True elif target \< data[mid]: high = mid - 1 else: low = mid + 1 return False if __name__ == '__main__': data = [random.randint(0, 100) for _ in range(100)] data.sort() print(data) target = int(input("¿Qué número te gustaría encontrar? ")) found = binary_search_iterative(data, target) print(found)>)![]()```js import random ''' def binary_search(data, target, low, high): if low > high: return False mid = (low + high) // 2 if target == data[mid]: return True elif target < data[mid]: return binary_search(data, target, low, mid - 1) else: return binary_search(data, target, mid + 1, high) if __name__ == '__main__': data = [random.randint(0, 100) for _ in range(100)] data.sort() print(data) target = int(input("¿Qué número te gustaría encontrar? ")) found = binary_search(data, target, 0, len(data) - 1) print(found) ''' import random def binary_search_iterative(data, target): low, high = 0, len(data) - 1 while low <= high: mid = (low + high) // 2 if target == data[mid]: return True elif target < data[mid]: high = mid - 1 else: low = mid + 1 return False if __name__ == '__main__': data = [random.randint(0, 100) for _ in range(100)] data.sort() print(data) target = int(input("¿Qué número te gustaría encontrar? ")) found = binary_search_iterative(data, target) print(found) ```import random ''' def binary\_search(data, target, low, high): if low > high: return False mid = (low + high) // 2 if target == data\[mid]: return True elif target < data\[mid]: return binary\_search(data, target, low, mid - 1) else: return binary\_search(data, target, mid + 1, high) if \_\_name\_\_ == '\_\_main\_\_': data = \[random.randint(0, 100) for \_ in range(100)] data.sort() print(data) target = int(input("¿Qué número te gustaría encontrar? ")) found = binary\_search(data, target, 0, len(data) - 1) print(found) ''' import random def binary\_search\_iterative(data, target): low, high = 0, len(data) - 1 while low <= high: mid = (low + high) // 2 if target == data\[mid]: return True elif target < data\[mid]: high = mid - 1 else: low = mid + 1 return False if \_\_name\_\_ == '\_\_main\_\_': data = \[random.randint(0, 100) for \_ in range(100)] data.sort() print(data) target = int(input("¿Qué número te gustaría encontrar? ")) found = binary\_search\_iterative(data, target) print(found)

Quedo funcional 🐧 pero toco entrar al repositorio del profe. Otra cosa que me di cuenta en el list_clients() no se puede con f'{}' si toca con el .format().
Ya habiamos trabajo abriendo archivo .csv pero sin editarlo. Buen introducción porque si toca estudiarlo mas a fondo.

Esta es mi version del código, agregue la funcionalidad de poder seguir interactuando con el programa hasta que el usuario decida cerrarlo

import os
import csv

CLIENT_TABLE = '.clients.csv'
CLIENTS_SCHEMA = ['name', 'Company', 'email', 'position']
clients = []

#Nuevas funciones para poder manipular los datos que seran agregados en 
#   un archivo csv
def _initialize_clients_from_storage():
    with open(CLIENT_TABLE, mode = 'r') as f:
        reader = csv.DictReader(f, fieldnames = CLIENTS_SCHEMA)
        for row in reader:
            clients.append(row)


def _save_clients_to_storage():
    tmp_table_name = '{}.tmp'.format(CLIENT_TABLE)
    with open(tmp_table_name, mode='w') as f:
        writer = csv.DictWriter(f, fieldnames = CLIENTS_SCHEMA)
        writer.writerows(clients)

        os.remove(CLIENT_TABLE)
    os.rename(tmp_table_name, CLIENT_TABLE)


#Se emplea para pedir al usuario los datos que se quieren agregar
#   dentro del diccionario
def _get_client_field(field_name):
    field = None
    while not field:
        field = input('What\'s the client\'s {}?: '.format(field_name))
    return field



#Creación de objeto dentro de la lista, es decir que se crean diccionarios de
#   a cuerdo a la necsidad que se presenta. En este programa solo existen dos
#   necesidaes de diccionario, uno para ingresar todos los datos y otro para 
#   hacer la busqueda de un nombre dentro de la lista.
def _create_obj(_option):
    if _option == 1:
        client = {
                'name': _get_client_field('name').capitalize(),
                'Company' : _get_client_field('Company').capitalize(),
                'email' : _get_client_field('email'),
                'position' : _get_client_field('position').capitalize(),
            }
    else:
        client = {
            'name': _get_client_field('name').capitalize(),
        }
    return client



#This function is used to loop through the list easily
#   Se emplea para poder hacer las busquedas solo por nombre y hacer más facil la
#   tarea de recorrer la lista a través de los indices
def _conversor_lists(client_d, aux):
    global clients
    num = int(len(clients))
    mlist = []
    pivot = []
    if client_d != None: 
        for idx in range(num):
            for content in clients[idx].values():
                mlist.append(content)
        for cont in client_d.values():
            pivot.append(cont)
        if aux == 0:
            return mlist #Full list
        else:
            return pivot # A small list with a name to search
    else:
        return None


#Funcion para agregar un nuevo elemento a la lista de clientes
def create_client(client):
    os.system("cls")
    print('\n\t --- NEW CLIENT ---\n')
    global clients
    if client not in clients:
        clients.append(client)
    else:
        print('Client already in the client\'s list')


#Funcion para eliminar un registro en la lista de clientes
def delete_client(client_d):
    os.system("cls")
    print('\n\t --- DELETE CLIENT ---\n')
    global clients
    _return = search_client(client_d, 1, None)
    if _return != None:
        clients.pop(_return)
        print('Client {} was deleted successfully!\n'.format(client_d['name']))


#Funcion para actualizar los datos de un cliente
def update_client(client_u):
    os.system("cls")
    print('\n\t --- CLIENT EDITION ---\n')
    global clients
    num = int(len(clients))
    _return = search_client(client_u, 1, None)
    _check = None
    if _return != None:
        while _check == None:
            print('Insert new information about the selected client: \n')
            client = _create_obj(1)
            _check = search_client(client,2,client_u)
        clients.insert(_return, client)
        clients.pop(_return+1)
        print('\t Update successful! \n')

    

#Funcion de busquedas, se utiliza para corroborar la existencia de un elemento en la lista
def search_client(client_d, _var, cl_up):
    os.system("cls")
    if _var == 0: 
        print('\n\t --- SEARCHING CLIENT ---\n')
    global clients
    num = int(len(clients))
    mlist = _conversor_lists(client_d, 0)
    pivot = _conversor_lists(client_d, 1)
    pibot_up = _conversor_lists(cl_up, 1)
    num2 = int(len(mlist))
    a = 0
    for i in range(num2):
        if i%4 == 0 and i !=0:
            a+=1
        if pivot[0] == mlist[i]:
            if i == 0:
                if _var == 0:
                    print('\tCliente {} is in the list.\n'.format(client_d['name']))
                    for _key, value in clients[i-(a*3)].items():
                        print(str(_key) + ': ' + str(value) )
                    return None
                elif _var == 2: #Omitimos el nombre del cliente que se quiere editar
                    if pibot_up[0] != mlist[i]:
                        print('\t Two clients cannot exist with the same name...\n')
                        return None
                else:
                    return i-(a*3)
            else:
                if _var == 0: 
                    for _key, value in clients[i-(a*3)].items():
                        print(str(_key) + ': ' + str(value) )
                    return None
                else:
                    return i-(a*3)
            break
        elif i == num2-1 and _var != 2:
                print('Client {} doesn\'t exist in the list... \n'.format(client_d['name']))
                return None


#Se muestra detalladamente el contenido de toda la lista de diccionarios
def show_list():
    os.system("cls")
    print('\n\t --- CLIENT\'S LIST ---\n')
    for idx, client in enumerate(clients):
        print('Name: {}'.format(client['name']))
        print('Company: {}'.format(client['Company']))
        print('e-mail: {}'.format(client['email']))
        print('Possition: {} \n'.format(client['position']))



#Impresion del menu con respectivas opciones y, los llamados a las respectivas
#   funciones que le dan operatividad al programa
def _print_wellcome():
    print('-' * 50)
    print('\n\t --- WELCOME TO CLIENTS MANAGEMENT ---\n')
    menu = """
    What would you do today?

    1 - Create client
    2 - Delete client
    3 - Update client
    4 - Search client
    5 - Show clients
    6 - Exit

    Choose an option: """
    while True:
        
        try: 
            option = int(input(menu))
            
            if option == 1:
                client = _create_obj(option)
                create_client(client)
                print('\n')
            elif option == 2:
                client_D = _create_obj(option)
                delete_client(client_D)
                print('\n')
            elif option == 3:
                client_u = _create_obj(option)
                update_client(client_u)
                print('\n')
            elif option == 4:
                client_S = _create_obj(option)
                search_client(client_S, 0, None)
            elif option == 5:
                show_list()
            elif option == 6:
                return 1
            else:
                print('Oops! That\'s not an option. Try again...\n')
        except ValueError:
                    print('Oops! That\'s not an option. Try again...\n')



#Funcion principal, aqui se hace un bucle que permite mantener el programa corriendo
#   hasta que el usuario decida finalizarlo
def main():
    _initialize_clients_from_storage()
    flag = 'y'
    exit_flag = 0
    while flag == 'y' or flag == 'Y':
        exit_flag = _print_wellcome()
        if exit_flag != 0:
            break
        flag = input('\tContinue? (y/n):')

    print('*' * 100)
    print('\t\t** END PROGRAM **')
    _save_clients_to_storage()
    
   

# Caracteristica de Python que indica donde tiene que iniciar la ejecucion del programa
if __name__ == '__main__':
    main()

saludos a todos,

tengo el sieguiente problema, al parecer no encuentra el archivo csv, e intentado cambiarle el nombre de distintos modos, incluso sin el . incinicial para que no este oculto y nada.

Traceback (most recent call last):
File “C:\Users\rguevara\Desktop\python\main.py”, line 185, in <module>
_save_clients_to_storage()
File “C:\Users\rguevara\Desktop\python\main.py”, line 24, in _save_clients_to_storage
os.remove(CLIENT_TABLE)
FileNotFoundError: [WinError 2] El sistema no puede encontrar el archivo especificado: ‘clients.csv’

Está clase está mejor explicada que con Facundo(quién imparte otros cursos de python en platzi).
Recomendación:
Pongan mucha atención y practiquen más, recientementee hice una prueba técnica para un trabajo y este video te ayuda bastante

ERROR WIN32 SOLUCIONADO: se debe sacar de la identacion del ultimo with, tanto remove CLIENT_TABLE, como rename CLIENT_TABLE, para que el with pueda cerrar su proceso y asi el delete y el remove puedan trabajar con el archivo.
.
.
with open(tmp_table_name, mode=‘w’) as f:
…writer = csv.DictWriter(f, fieldnames=CLIENT_SCHEMA)
…writer.writerows(clients)

os.remove(CLIENT_TABLE)
os.rename(tmp_table_name, CLIENT_TABLE)

Resuelto por:
@franciscoholguinrico
y
@orlandoramirez

Para que funcione debe quedar asi la funcion _save_client_to_storage()
Ojo:
f.close()
os. remove
os.rename
deben quedar fuera del with

def _save_clients_to_storage():
    tmp_table_name = '{}.tmp'.format(CLIENT_TABLE)
    with open(tmp_table_name, mode='w') as f:
        writer = csv.DictWriter(f,fieldnames=CLIENT_SCHEMA)
        writer.writerows(clients)

    f.close()
    os.remove(CLIENT_TABLE)
    os.rename(tmp_table_name, CLIENT_TABLE)

Va mi aporte, cómo me quedó el código en teoría funcionado bien:

import sys
import csv
import os


CLIENT_TABLE = '.clients.csv'
CLIENT_SCHEMA = ['name', 'company', 'email', 'position']
clients = []


def _initialize_clients_from_storage():
    with open(CLIENT_TABLE, mode='r') as f:
        reader = csv.DictReader(f, fieldnames=CLIENT_SCHEMA)

        for row in reader:
            clients.append(row)


def _save_clients_to_storage():
    tmp_table_name = f'{CLIENT_TABLE}.tmp'
    with open(tmp_table_name, mode='w') as f:
        writer = csv.DictWriter(f, fieldnames=CLIENT_SCHEMA)
        writer.writerows(clients)

        os.remove(CLIENT_TABLE)
        os.rename(tmp_table_name, CLIENT_TABLE)


def create_client(client):
    global clients

    if client not in clients:
        clients.append(client)
    else:
        print('Client is already in our database')


def list_clients():

    print('uid | name | company | email | position')
    print('*' * 50)

    for idx, client in enumerate(clients):
        print(
            f'{idx} | {client["name"]} | {client["company"]} | {client["email"]} | {client["position"]}')


def update_client(client_id):
    global clients
    if client_id < len(clients):
        clients[client_id] = {
            'name': _get_client_field('name'),
            'company': _get_client_field('company'),
            'email': _get_client_field('email'),
            'position': _get_client_field('position')
        }
        print(
            f'The client {client_id} was succefully updated from our database')
    else:
        print(f'The client {client_id} is not in our database')


def delete_client(client_id):
    global clients
    if client_id < len(clients):
        clients.pop(client_id)
        print(
            f'The client {client_id} was succefully deleted from our database')
    else:
        print(f'The client {client_id} is not in our database')


def search_client(client_name):
    global clients
    return next((idx for idx, client in enumerate(clients) if client["name"] == client_name), None)


def _print_welcome():
    print('WELCOME TO PLATZI VENTAS')
    print('*' * 50)
    print('What would you like to do today?')
    print('[C]reate client')
    print('[L]list clients')
    print('[U]pdate client')
    print('[D]elete client')
    print('[S]earch client')


def _get_client_field(field_name):
    field_input = None

    while not field_input:
        field_input = input(f'What is de client {field_name}? ')

        if field_input == 'exit':
            field_input = None
            break

        if field_name == 'uid':
            if not field_input.isnumeric():
                print("Not a valid id number")
                field_input = None

    if not field_input:
        sys.exit()

    return field_input


if __name__ == '__main__':
    _initialize_clients_from_storage()

    _print_welcome()

    command = input().upper()

    if command == 'C':
        client = {
            'name': _get_client_field('name'),
            'company': _get_client_field('company'),
            'email': _get_client_field('email'),
            'position': _get_client_field('position')
        }
        create_client(client)
    elif command == 'L':
        list_clients()
    elif command == 'D':
        client_id = _get_client_field('uid')
        delete_client(int(client_id))
    elif command == 'U':
        client_id = _get_client_field('uid')
        print(f'Updating client {client_id}...')
        update_client(int(client_id))
    elif command == 'S':
        client_name = _get_client_field('name')
        id_found = search_client(client_name)
        if id_found >= 0:
            client = clients[id_found]
            print('uid | name | company | email | position')
            print('*' * 50)
            print(
                f'{id_found} | {client["name"]} | {client["company"]} | {client["email"]} | {client["position"]}')
        else:
            print(f'The client {client_name} is not in our database')
    else:
        print('Invalid command')

    _save_clients_to_storage()

Un aporte referente a el uso actualizado de 'format 'en Python 3:
Es posible cambiar el segmento del codigo:

tmp_table_name = '{}.tmp'.format(CLIENT_TABLE)

Por este otro mas actualizado:

tmp_table_name =  f'{CLIENT_TABLE}.tmp'

Espero les sea de utilidad. ¡Animo a todos!

hola a todos dejo una explicacion de paso a paso lo que hace el codigo y al final un resumen en general del mismo. si me equivoque en algo por favor corríjanme y espero ayudar a los que no lograron entender del todo

  1. importamos el modulo os que es operative system y csv que es para la manipulación de csv
  2. declaramos las constantes. 1 la tabla 2 las columnas que van a formar parte de la tabla
  3. creamos un arreglo que va a contener los diccionarios
  4. declaramos la función de lectura del documento csv
    1. lo abrimos
    2. decimos cual es
    3. colocamos modo r
    4. y le decimos que dentro de nuestro codigo va a ser f
    5. declaramos una variable con el valor csv.DictReader(archivo,fields)
      1. csv.dictreader: pide un archivo y las columnas del mismo para leerlo como diccionario clave valor
    6. hacemos un for que recorra la variable creada y con cada iteración coloque en el array vacío que creamos cada diccionario que se encuentra en el archivo en modo lectura
  5. creamos la función de guardar
    1. creamos una variable que sea un archivo temporal ya que no se puede utilizar un archivo abierto en otra funcion
    2. abrimos ese archivo temporal con los mismos datos que el original en forma de escritura
    3. declaramos una variable con csv.DictWriter(document,fields/columnas)
    4. llamamos a la varaible de escritura writer.writerrows(array creado)
      1. lo que hace es escribir lo que se encuentra en clients dentro del archivo
    5. llamamos al paquete os.remove(csv sin modificar)
      1. borra el primer archivo que abrimos
    6. os.raname(temporal-table-name, nombre del original)
      1. renombra el archivo temporal como el original

resumen: lo que hacen estas dos funciones trabajando en conjunto es sacar la informacion de un archivo en formato csv y pasarlo a una estructura de datos vacia dentro de nuestro programa para que nos sea mas facil manipular y no tener que consultar constantemente esos archivos. una vez que terminamos de agrear la informacion que queremos a nuestra estructura logica. la informacion la guardamos en un archivo temporal y por ultimo borramos el primer archivo que leimos y hacemos que el temporal con las ultimas modificaciones pase a ser el permanente

Otras notas para tener en cuenta:
.
1.- Cuando das UPDATE o DELETE, te pide el id del usuario, pero no lista las personas que hay en la table. Hay que acutualizar.
2.- Cuando das UPDATE o DELETE, te pide el id del usuario, Si ingresas un valor erroneo, el programa se cae; eso quiere decir que hay que agregar un mensaje que diga ‘id incorrecto, ingresalo de nuevo’

Si alguien tuvo algún error, les comento que la función _save_clients_to_storage(), debe quedar así:

def _save_clients_to_storage():
    tmp_table_name = '{}.tmp'.format(CLIENT_TABLE)
    with open(tmp_table_name, mode='w') as f:
        writer = csv.DictWriter(f, fieldnames=CLIENT_SCHEMA)
        writer.writerows(clients)

        os.remove(CLIENT_TABLE)
    os.rename(tmp_table_name, CLIENT_TABLE)

Mi código si quieren comparar

import csv
import os
import sys

CLIENT_SCHEMA = ["name", "company", "email", "position"]
CLIENT_TABLE = ".clients.csv"
clients = []

def _initialize_clients_from_storage():
    with open(CLIENT_TABLE, mode='r') as f:
        reader = csv.DictReader(f, fieldnames=CLIENT_SCHEMA)

        for row in reader:
            clients.append(row)

def _save_clients_to_storage():
	tmp_table_name = '{}.tmp'.format(CLIENT_TABLE)
	with open(tmp_table_name, mode='w') as f:
		writer = csv.DictWriter( f, fieldnames= CLIENT_SCHEMA )
		writer.writerows(clients)

	os.remove(CLIENT_TABLE) 
	os.rename( tmp_table_name, CLIENT_TABLE )



def create_clients(client):
    global clients
    if client not in clients:
        clients.append(client)
    else:
        print("client already is in the clien`t list")

def update_client(client_name, update_client_name):
    global clients

    if client_name in clients:
        index = clients.index(client_name)
        client[index] = update_client_name
    else:
        print("client is not inclients list")

def delete_client(client_name):
    global clients
    for idx, client in enumerate (clients):
        if idx == client_id:
            del clients[idx]
            break
    else:
        print("client is not inclients list")

def search_client(client_name):
    for client in clients:
        if client["name"] != client_name:
            continue
        else:
            return True 


def _get_client_field(field_name):
    field = None
    while not field:
        field = input("what is the client {}?".format(field_name))
    return field

def _get_client_name():
    client_name = None 
    while not client_name:
        client_name = input("what is the client name? ")

        if  client_name == "exit":
            client_name = None
            break

    if not client_name:
            sys.exit()
    
    return client_name 

def list_clients():
    for idx, client in enumerate(clients):
        print("{uid} | {name} | {company} | {email} | {position}".format(
            uid=idx,
            name=client["name"],
            company=client["company"],
            email=client["email"],
            position=client["position"]))

def _get_client_from_user ():
    client = {
            "name": _get_client_field("name"),
            "company": _get_client_field("company"),
            "email": _get_client_field("email"),
            "position": _get_client_field("position"),
        }


def _print_welcome():
    print("welcome to platzi ventas")
    print("*" * 5)
    print("what would you like to do today? ")
    print("[C]reate client")
    print("[U]pdate client")
    print("[D]elete client")
    print("[s]earch client")
    print("[L]ist client")

if __name__ == "__main__":
    _initialize_clients_from_storage()

    _print_welcome()
    command = input()
    command = command.upper()
    
    if command == 'C':
        client = {
            'name': _get_client_field('name'),
            'company': _get_client_field('company'),
            'email': _get_client_field('email'),
            'position': _get_client_field('position'),
        }
        create_clients(client)
        
  
    elif command == "U":
        client_id = int(_get_client_field('id'))
        updated_client = _get_client_from_user()

        update_client(client_id, updated_client)
        

    elif command == "D":
        client_id = int(_get_client_field('id'))

        delete_client(client_id)
        

    elif command == "L":
        list_clients()

    elif command == "S":
        client_name = _get_client_field("name")
        found = search_client(client_name)
        if found:
            print("The client is in the clients list")
        else:
            print("The client: {} is not our clients list ".format(client_name))

    else:
        print("invalid commnad")

    _save_clients_to_storage() 

Saludos, me sale el siguiente error y no comprendo porque, me podrian ayudar por favor

PermissionError: [WinError 32] El proceso no tiene acceso al archivo porque está siendo utilizado por otro proceso: ‘client.csv.tmp’ -> ‘client.csv’

Para complementar esta clase, si están usando VS Code les recomiendo la extensión Excel Viewer, les permitirá ver en una pestaña los archivos CSV como una tabla:

Saludos amigos les comparto la documentacion acerca de esto, para python 3.9.2X+

Me da un error en el input() y no sé exactamente por qué. Help please 😦 ?

import csv
import os

CLIENT_TABLE = '.clients.csv'
CLIENT_SCHEMA = ['name', 'company', 'email', 'position']
clients = []


# Storage:
def _initialize_clients_from_storage():
	with open(CLIENT_TABLE, mode='r') as f:
		reader = csv.DictReader(f, fieldnames = CLIENT_SCHEMA)

		for row in reader:
			clients.append(row)


def _save_clients_to_storage():
	tmp_table_name = '{}.tmp'.format(CLIENT_TABLE)
	with open(tmp_table_name, mode='w') as f:
		writer = csv.DictWriter(f, fieldnames = CLIENT_SCHEMA)
		writer.writerows(clients)

	os.remove(CLIENT_TABLE)
	os.rename(tmp_table_name, CLIENT_TABLE)


# Utils:
def _get_client_field(field):
	client = input('What is the client {}? '.format(field))

	return client


def _get_client_from_user():
    client = {
        'name': _get_client_field('name'),
        'company': _get_client_field('company'),
        'email': _get_client_field('email'),
        'position': _get_client_field('position'),
    }

    return client


# Actions:
def create_client(client_name):
	global clients

	if client_name not in clients:
		clients.append(client_name)
	else:
		print('Client already is in the clients list')


def list_clients():
	for uid, client in enumerate(clients):
		print('{uid} | {name} | {company} | {email} | {position}'.format(
			name = client['name'],
			company = client['company'],
			email = client['email'],
			position = client['position'],
		))


def update_client(client_id, updated_client):
	global clients

	if len(clients) - 1 >= client_id:
		clients[client_id] = updated_client
	else:
		print('{} is not in clients list'.format(client_id))


def delete_client(client_id):
	global clients

	for uid, client in enumerate(clients):
		if uid == client_id:
			del clients[uid]
			break


def search_client(client_name):
	for client in clients:
		if client['name'] != client_name:
			continue
		else:
			return True


# Welcome Message:
def _print_welcome():
	print('WELCOME TO PLATZI VENTAS')
	print('*' * 50)
	print('What would you like to do today?')
	print('[C]reate client')
	print('[R]ead clients list')
	print('[U]pdate client')
	print('[D]elete client')
	print('[S]earch client')


# Entry Program:
if __name__ == '__main__':
	_initialize_clients_from_storage()
	_print_welcome()

	command = input('Select option: ')
	command = command.upper()

	if command == 'C':
		client = _get_client_from_user()
		create_client(client)
		list_clients()
	elif command == 'R':
		list_clients()
	elif command == 'U':
		print('What item do you want to edit?')
		print('Select an id:')
		list_clients()
		client_id = int(_get_client_field('id'))
		updated_client = _get_client_from_user()

		update_client(client_id, updated_client)
		list_clients()
	elif command == 'D':
		print('What item do you want to delete?')
		print('Select an id:')
		list_clients()
		client_id = int(_get_client_field('id'))

		delete_client(client_id)
		list_clients()
	elif command == 'S':
		client_name = _get_client_field('name')
		found = search_client(client_name)

		if found:
			print('{} is in the clients list'.format(client_name))
		else:
			print('The client {} is not in our clients list'.format(client_name))
	else:
		print('Invalid option')

	_save_clients_to_storage()

Salida de la terminal:

➜ python main.py
WELCOME TO PLATZI VENTAS
**************************************************
What would you like to do today?
[C]reate client
[R]ead clients list
[U]pdate client
[D]elete client
[S]earch client
Select option: C
Traceback (most recent call last):
  File "main.py", line 109, in <module>
    command = input('Select option: ')
  File "<string>", line 1, in <module>
NameError: name 'C' is not defined

De todas las clases de Python con el Master Aroesti, esta es la que más me ha gustado 😄

Excelente clase instructor David, me gusto bastante conocer esta forma de almacenar los datos con el uso de archivos locales.

Les comparto un enlace para generar un archivo .csv con datos aleatorios.
https://www.mockaroo.com/

Hey hey hey! más despacio, pnche hacker! XD
No, no. Ya en serio. Que bien han estado los últimos videos de este curso, desde que explicas los strings, listas, diccionarios, tuplas, etc. Has metido en un sólo proyecto estos temas, y has ido variando el uso de cada uno de los temas vistos, de acuerdo al nivel de complejidad (en aumento).
Ahora sí me ha gustado bastante este nuevo curso de Python 😉

Aún me quedan algunas dudas.
Revisaré el código

Hola, tuve que hacer algunas modificaciones al código, para que me funcionara el método de actualizar.

import csv
import os

CLIENT_SCHEMA = ['name', 'company', 'email', 'position']
CLIENT_TABLE = 'clients.csv'
clients = []


def create_client(client):
    global clients

    if client not in clients:
        clients.append(client)
    else:
        print('Client already in client\'s list')


def list_clients():
    print('uid |  name  | company  | email  | position ')
    print('*' * 50)

    for idx, client in enumerate(clients):
        print('{uid} | {name} | {company} | {email} | {position}'.format(
            uid=idx,
            name=client['name'],
            company=client['company'],
            email=client['email'],
            position=client['position']))


def update_client(client_id, updated_client):
    global clients
    i = 0;

    for client in clients:
        if client['name'] == client_id:
            clients[i] = updated_client
        i += 1;
    else:
        print('Client is not in clients list')


def delete_client(client_id):
    global clients

    if client_id in clients:
        clients.remove(client_id)
    else:
        print('Client is not in clients list')


def search_client(client_name):
    for client in clients:
        if client['name'] != client_name:
            continue
        else:
            return True


def _get_client_field(field_name, message='What is the client {}?'):
    field = None

    while not field:
        field = input(message.format(field_name))

    return field


def _get_client_from_user():
    client = {
        'name': _get_client_field('name'),
        'company': _get_client_field('company'),
        'email': _get_client_field('email'),
        'position': _get_client_field('position'),
    }

    return client


def _initialize_clients_from_storage():
    global clients

    with open(CLIENT_TABLE, mode='r') as f:
        reader = csv.DictReader(f, fieldnames=CLIENT_SCHEMA)

        for row in reader:
            clients.append(row)


def _save_clients_to_storage():
    tmp_table_name = '{}.tmp'.format(CLIENT_TABLE)
    with open(tmp_table_name, mode='w') as f:
        writer = csv.DictWriter(f, fieldnames=CLIENT_SCHEMA)
        writer.writerows(clients)

        os.remove(CLIENT_TABLE)
    os.rename(tmp_table_name, CLIENT_TABLE)


def _print_welcome():
    print('WELCOME TO PLATZI VENTAS')
    print('*' * 50)
    print('What would you like to do today?:')
    print('[C]reate client')
    print('[L]ist clients')
    print('[U]pdate client')
    print('[D]elete client')
    print('[S]earch client')


if __name__ == '__main__':
    _initialize_clients_from_storage()
    _print_welcome()

    command = input()
    command = command.upper()

    if command == 'C':
        client = _get_client_from_user()

        create_client(client)
    elif command == 'L':
        list_clients()
    elif command == 'U':
        client_id = _get_client_field('id')
        updated_client = _get_client_from_user()

        update_client(client_id, updated_client)
    elif command == 'D':
        client_id = _get_client_field('id')

        delete_client(client_id)
    elif command == 'S':
        client_name = _get_client_field('name')
        found = search_client(client_name)

        if found:
            print('The client is in the client\'s list')
        else:
            print('The client: {} is not in our client\'s list'.format(client_name))
    else:
        print('Invalid command')

    _save_clients_to_storage()```

Comunidad xD
Cuando estaba corriendo el código me saltó este problema:

Traceback (most recent call last):
  File "main.py", line 159, in <module>
    _save_clients_to_storage()
  File "main.py", line 21, in _save_clients_to_storage
    writer = csv.DictWriter(f, fieldNames = CLIENTS_SCHEMA)
TypeError: __init__() missing 1 required positional argument: 'fieldnames'

Reescribí el código una y otra vez y no cambiaba el resultado. La ultima vez que lo hice, antes de reescribir el código elminé ‘.clients.csv.tmp’, después de realizar este proceso de eliminar y reescribir el código, dejó de lanzar el problema. Espero les sirva. Espero también que alguien me pueda decir si sin querer resolví el problema o fue pura suerte.

(Me imagino que tiene sentido, porque, el error se almacenaba en el archivo temporal hasta que lo eliminé, entonces dejó de estar ahí, aunque soy novato, no estoy seguro)

Pedazo del código:

def _initialize_clients_from_storage():
    with open(CLIENT_TABLE, mode='r') as f:
        reader = csv.DictReader(f, fieldnames=CLIENT_SCHEMA)

        for row in reader:
            clients.append(row)


def _save_clients_to_storage():
    tmp_table_name = '{}.tmp'.format(CLIENT_TABLE)
    with open(tmp_table_name, mode='w') as f:
        writer = csv.DictWriter(f, fieldnames=CLIENT_SCHEMA)
        writer.writerows(clients)

        os.remove(CLIENT_TABLE)
    os.rename(tmp_table_name, CLIENT_TABLE)

Aqui esta mi codigo con varios cambios

import sys
import csv
import os

CLIENT_TABLE = ".clients.csv"
CLIENT_SCHEMA = ["name", "last name", "company", "email", "position"]
last_name = None
company = None
email = None
position = None
name = None
command = None
command_update = None 
clients = []

def _initialize_clients_from_storage():
	with open(CLIENT_TABLE, mode="r") as f:
		reader = csv.DictReader(f,fieldnames=CLIENT_SCHEMA)

		for row in reader:
			clients.append(row)


def save_clients_to_storage():
	tmp_table_name = "{}.tmp".format(CLIENT_TABLE)
	with open(tmp_table_name, mode="w") as f:
		writer = csv.DictWriter(f, fieldnames=CLIENT_SCHEMA)
		writer.writerows(clients)
		f.close()

		os.remove(CLIENT_TABLE)
		os.rename(tmp_table_name, CLIENT_TABLE)


def create_client(client):
    global clients

    if client not in clients:
    	clients.append(client)

    else:
        print(f"Client {client} already in client's list")


def list_clients():
    print('uid |  name  |  last name  | company  | email  | position ')
    print('*' * 50)

    for idx, client in enumerate(clients):
        print('{uid} | {name} |  {last_name} | {company} | {email} | {position}'.format(
            uid=idx, 
            name=client['name'],
            last_name=client['last name'], 
            company=client['company'], 
            email=client['email'], 
            position=client['position']))


def update_client(client_id,updated_client):
	global clients

	if len(clients) - 1 >= client_id:
		clients[client_id] = updated_client


def _get_update_client(update_field):
	global command_update
	global name
	global last_name
	global company
	global email
	global position

	while not command_update:
		command_update = input("What is the client field that you want update? ")

	command_update.upper()

	if command_update == "N":
		while not name:
			name = input("What is the new name? ")
		return name

	elif command_update == "L":
		while not last_name:
			last_name = input("What is the new last name? ")
		return last_name

	elif command_update == "C":
		while not company:
			company = input("What is the new company? ")
		return company

	elif command_update == "E":
		while not email:
			email = input("What is the new email? ")
		return email

	elif command_update == "P":
		while not position:
			position = input("What is the new position? ")
		return position

	else:
		print("Invalid command, try again")


def delete_client(client_id):
    global clients

    for idx, client in enumerate(clients):
        if idx == client_id:
            del clients[idx] 
            break


def search_client(client_name):
    for client in clients:
        if client['name'] != client_name:
            continue
        else:
            return True


def _get_client_field(field_place):
    field = None

    while not field:
        field = input(f"what is the client {field_place}? ")
    
    return field


def _client_field():
	global command_update
	global command
	global clients
	client = {}

	if command == "C":
		client = {
			"name": _get_client_field("name"),
			"last name": _get_client_field("last name"),
			"company": _get_client_field("company"),
			"email": _get_client_field("email"),
			"position": _get_client_field("position"),
		}
		return client
	elif command == "U":
		_get_update_client(clients[client_id])
		if command_update == "N":
			client = {
				"name": name,
				"last name": client,
				"company": client,
				"email": client,
				"position": client,
			}
			return client
		elif command_update == "L":
			client = {
				"name": client,
				"last name": last_name,
				"company": client,
				"email": client,
				"position": client,
			}
			return client
		elif command_update == "C":
			client = {
				"name": client,
				"last name": client,
				"company": company,
				"email": client,
				"position": client,
			}
			return client
		elif command_update == "E":
			client = {
				"name": client,
				"last name": client,
				"company": client,
				"email": email,
				"position": client,
			}
			return client
		elif command_update == "P":
			client = {
				"name": client,
				"last name": clientnt,
				"company": client,
				"email": client,
				"position": position,
			}
			return client
		else:
			print("Invalid command, please try again")


def _not_in_clients(client_name):
	global clients

	if client_name not in clients:
		 print(client_name, "is not in client's list")


def _print_welcome():
	print("*"*20 ,"WELCOME TO THE DATA CENTER", "*"*20)
	print("What would yo like to do today?")
	print("[C]reate client")
	print("[R]ead client")
	print("[U]pdate client")
	print("[D]elete client")
	print("[S]earch client")


if __name__ == '__main__':
	_initialize_clients_from_storage()

	_print_welcome()

	command = input()
	command = command.upper()


	if command == "C":
		client = _client_field()

		create_client(client)

	elif command == "R":
		list_clients()

	elif command == "D":
		list_clients()
		print("-"*45)
		client_id = int(_get_client_field('id'))

		delete_client(client_id)
		print("-"*45)

	elif command == "U":
		client_id = int(input("What is the client id "))
		print("[N]ame client")
		print("[L]ast client")
		print("[C]ompany client")
		print("[E]mail client")
		print("[P]osition client")
		updated_client = _client_field()
		
		update_client(client_id,updated_client)

	elif command == "S":
		client_name = _get_client_field('name')
		found = search_client(client_name)
        
		if found:
			print('The client is in the client\'s list')
		else:
			print('The client: {} is not in our client\'s list'.format(client_name))

	elif command == "E":
		_exit(exit)

	else:
		print("Invalid command, try again")

save_clients_to_storage()```

Si el archivo con los datos esta en otro directorio y tengo que buscarlo. ¿Cómo se haría esto?

def _save_clients_to_storage():
	...

Porque usar nombres de funciones suficientemente claras?

  • Porque como se mencionó al principio del curso escribimos código para humanos.

Y ademas de seguir la filosofía de python que se dejó muy clara en el lenguaje
solo escribe:

import this

Un menú mas atractivo se puede lograr con pythondialog, que es una implementación en python de la legendaria libreria dialog en C por Savio Lam

para instalar

pip install pythondialog

importamos el objeto Dialog

from dialog import Dialog
...

El menú de inicio 

def _print_welcome():
d = Dialog()
code, tag = d.menu(“WELCOME TO THE DATA CENTER”,
choices=[(“C”, “Create client”),
(“R”, “Read client”),
(“U”, “Update client”),
(“D”, “Delete client”),
(“S”, “Search client”)
])
return code, tag

El formulario de crear cliente


def _client_field():
d = Dialog()
code, values = d.form(“fomulario”, [
(“Nombres”, 1, 1, “”, 1, 15, 65, 0),
(“Apellidos”, 2, 1, “”, 2, 15, 65, 0),
(“Empresa”, 3, 1, “”, 3, 15, 65, 0),
(“Email”, 4, 1, “”, 4, 15, 65, 0),
(“Cargo”, 5, 1, “”, 5, 15, 65, 0),
])

return {"name": values[0], "last name": values[1],
        "company": values[2], "email": values[3],
        "position": values[4]}

Un menu mas atractivo

from dialog import Dialog


## menu principal
def _print_welcome():
    d = Dialog()
    code, tag = d.menu("WELCOME TO THE DATA CENTER",
                       choices=[("C", "Create client"),
                                ("R", "Read client"),
                                ("U", "Update client"),
                                ("D", "Delete client"),
                                ("S", "Search client")
                                ])
    return code, tag

## formulario de cliente
def _client_field():
    d = Dialog()
    code, values = d.form("fomulario", [
        ("Nombres",   1, 1, "", 1, 15, 65, 0),
        ("Apellidos", 2, 1, "", 2, 15, 65, 0),
        ("Empresa",   3, 1, "", 3, 15, 65, 0),
        ("Email",     4, 1, "", 4, 15, 65, 0),
        ("Cargo",     5, 1, "", 5, 15, 65, 0),
    ])

    return {"name": values[0], "last name": values[1],
            "company": values[2], "email": values[3],
            "position": values[4]}

En mi codigo cree una funcion llamada loop que repitiera el proceso por si se requiere agregar o alterar la informacion sin salir de la “sesion”

import csv
import sys
import os


CLIENT_TABLE = '.clients.csv'
CLIENT_SCHEMA = ['name', 'company', 'email', 'position']
clients = []


def _initialize_clients_from_storage():
	with open(CLIENT_TABLE, mode="r") as f:
		reader = csv.DictReader(f,fieldnames=CLIENT_SCHEMA)

		for row in reader:
			clients.append(row)


def _save_clients_to_storage():
    tmp_table_name = '{}.tmp'.format(CLIENT_TABLE)
    with open(tmp_table_name, mode='w') as f:
        writer = csv.DictWriter(f, fieldnames=CLIENT_SCHEMA)
        writer.writerows(clients)            

    os.remove(CLIENT_TABLE)
    os.rename(tmp_table_name, CLIENT_TABLE)


def create_client(client):
    global clients

    if client not in clients:
        clients.append(client)
    else:
        print('Client already exist in the client\'s list')


def list_clients():
    global clients
    for idx, client in enumerate(clients):
        print('*' * 50)
        print('{uid} | {name} | {company} | {email} | {position}'.format(uid=idx, name=client['name'], company=client['company'], email=client['email'], position=client['position']))
        

def update_client(client_id, new_client):
    global clients
    
    if len(clients) - 1 >= client_id:
        clients[client_id] = new_client
    else:
        print('Client not in client\'s list')
    

def delete_client(client_id):
    global clients

    for idx, client in enumerate(clients):
        if idx == client_id:
            del clients[idx]
            break


def search_client(client_name):
    global clietns

    for client in clients:
        if client['name'] != client_name:
            continue
        else:
            return True


def _print_welcome():
    print('WELCOME TO PLATZI VENTAS')
    print('*' * 50)
    print('WHAT WOULD YOU LIKE TO DO TODAY')
    print('[C]reate client')
    print('[D]elete client')
    print('[U]pdate client')
    print('[S]earch client')
    print('[L]ist clients')


def _get_client_field(field_name, message='what\'s the client {}?'):
    field = None

    while not field:
        field = input(message.format(field_name))

    return field

"""
this function get useles when we add the dictionaries but i'll keep here to check
def _get_client_name():
    client_name = None
    while not client_name:
        client_name = input('What is the client name?')

        if client_name == 'exit':
            client_name = None
            break

    if not client_name :
        sys.exit()

    return client_name
"""     
def _get_client():
    client = {
        'name': _get_client_field('name'),
        'company': _get_client_field('company'),
        'email': _get_client_field('email'),
        'position': _get_client_field('position'),
    }

    return client


def CRUD():
    
        command = input().upper()   

        if command == 'C':
            client = _get_client()
            create_client(client)
            list_clients()
        elif command == 'D':
            list_clients()
            client_id = int(_get_client_field('id'))

            delete_client(client_id)
            list_clients()
        elif command == 'U':
            list_clients()

            client_id = int(_get_client_field('id'))
            new_client = _get_client()

            update_client(client_id, new_client)
            list_clients()
        elif command == 'L':
            list_clients()
        elif command == 'S':
            client_name = _get_client_field('name')
            found = search_client(client_name)

            if found:
                print('The client is in the client\'s list')
            else:
                print('The client: {} is not in the client\'s list'.format(client_name))

        else:
            print('Invalid command')

        _save_clients_to_storage()
            
        loop()


def loop():
        com = input('WANT TO DO SOMETHING MORE? (Y/N)').upper()

        if  com == 'Y':
            _print_welcome()
            CRUD()
        elif com == 'N':
            pass
        else:
            print('Invalid command')


if __name__ == '__main__':
    _initialize_clients_from_storage()
    _print_welcome()
    
    CRUD()




para los que le sale error en windows como a mi yo lo resolvi poniendo un f.close() despues del os.remove(client_table)

pd: yo lo puse en español pero es despues que quitan el archivo client.csv
le ponen el f.close()

def _guardar_cliente_almacenamiento():
    temp_nom_tab="{}.tmp".format(client_table)
    with open(temp_nom_tab,mode="w") as f:
        escribir=csv.DictWriter(f, fieldnames=esquema_clientes)
        escribir.writerows(clients)
        os.remove(client_table)
        f.close()
        os.rename(temp_nom_tab,client_table)

Me demore 20 mins en encontrar el error… que error tan fastidiosos jaja

ANTES

if command == ‘C’:
client = get_client_fields()
create_client(client)
list_clients()
print(type(client))
print(type(clients))
elif command == ‘R’:
client = get_client_fields()
found = retrieve_client(client)
if found:
_command_success()
list_client(client)
else: client_not_found()
elif command == ‘U’:
client = get_client_fields()
update_client(client)
elif command == ‘D’:
client = get_client_fields()
delete_client(client)
elif command == ‘L’:
list_clients()
else: print(“we cannot help you”)

if name == ‘main’:
_initialize_clients_from_storage()

_save_clients_to_storage()

SOLUCION

if name == ‘main’:
_initialize_clients_from_storage()

if command == ‘C’:
client = get_client_fields()
create_client(client)
list_clients()
print(type(client))
print(type(clients))
elif command == ‘R’:
client = get_client_fields()
found = retrieve_client(client)
if found:
_command_success()
list_client(client)
else: client_not_found()
elif command == ‘U’:
client = get_client_fields()
update_client(client)
elif command == ‘D’:
client = get_client_fields()
delete_client(client)
elif command == ‘L’:
list_clients()
else: print(“we cannot help you”)

_save_clients_to_storage()```

mejore mi codigo para que le diera opcion al usuario de seguir en el programa o salir de el
jajaja acepto sugerencias o comentarios

import csv
import os

CLIENT_SCHEMA=['name', 'company' , 'email', 'position']
CLIENT_TABLE='.clients1.csv'
clients= []


def _initialize_clients_from_storage():
    global clients
    with open(CLIENT_TABLE, mode='r') as f:
        reader = csv.DictReader(f, fieldnames=CLIENT_SCHEMA)

        for row in reader:
            clients.append(row)



def _save_clients_to_storage():
    tmp_table_name = '{}.tmp'.format(CLIENT_TABLE)
    with open(tmp_table_name, mode='w') as f:
        write = csv.DictWriter(f, fieldnames=CLIENT_SCHEMA)
        write.writerows(clients)

    os.remove(CLIENT_TABLE)
    os.rename(tmp_table_name, CLIENT_TABLE)



def create_client(client):


    if client not in clients:
        clients.append(client)
    else:
        print('Client already in client\'s list')


def list_clients():
    print('uid |  name  | company  | email  | position ')
    print('*' * 50)

    for idx, client in enumerate(clients):
        print('{uid} | {name} | {company} | {email} | {position}'.format(
            uid=idx, 
            name=client['name'], 
            company=client['company'], 
            email=client['email'], 
            position=client['position']))


def update_client(client_id, updated_client):
    global clients

    if len(clients) - 1 >= client_id:
        clients[client_id] = updated_client
    else:
        print('Client not in client\'s list')


def delete_client(client_id):
    global clients

    for idx, client in enumerate(clients):
        if idx == client_id:
            del clients[idx] 
            break


def search_client(client_name):
    for client in clients:
        if client['name'] != client_name:
            continue
        else:
            return True


def _get_client_field(field_name, message='What is the client {}?'):
    field = None

    while not field:
        field = input(message.format(field_name))

    return field


def _get_client_from_user():
    client = {
        'name': _get_client_field('name'),
        'company': _get_client_field('company'),
        'email': _get_client_field('email'),
        'position': _get_client_field('position'),
    }

    return client


def _print_welcome():
    print('WELCOME TO PLATZI VENTAS')
    print('*' * 50)

def _print_Question():
    print('*' * 50)
    print('What would you like to do today?:')
    print('[C]reate client')
    print('[L]ist clients')
    print('[U]pdate client')
    print('[D]elete client')
    print('[S]earch client')


def _print_Bye():
    print('*' * 50)
    print('Good bye to PLATZI VENTAS')
    print('*' * 50)


def _First_main():
    global clients
    _print_Question()
    _initialize_clients_from_storage()
    

    command = input()
    command = command.upper()

    if command == 'C':
        client = _get_client_from_user()

        create_client(client)
    elif command == 'L':
        list_clients()
    elif command == 'U':
        client_id = int(_get_client_field('id'))
        updated_client = _get_client_from_user()

        update_client(client_id, updated_client)
    elif command == 'D':
        client_id = int(_get_client_field('id'))

        delete_client(client_id)
    elif command == 'S':
        client_name = _get_client_field('name')
        found = search_client(client_name)
        
        if found:
            print('The client is in the client\'s list')
        else:
            print('The client: {} is not in our client\'s list'.format(client_name))
    else:
        print('Invalid command')

    _save_clients_to_storage()

def Continued():
    print('*' * 50)
    print('Do you want to continue executing some action? ')
    print('[Y]es or [N]o: ')
    command=input()
    command = command.upper()
    if command == 'S':
        return True
    else:
        return False



if __name__ == '__main__':

    _print_welcome()
    seguir = True
    while seguir:
        clients=[]
        _First_main()
        clients=[]
        seguir = Continued()

    _print_Bye()

Este capitulo de csv, es bastante importante y extenso, deberia darse un curso completo para profundizar en el mismo, que aqui son las bases para muchas cosas

Estoy trabajando con windows y el comando touch no funciona entonces trate de realizarlo manual, pude crear el cliente ejecuta bien y todo, el problema es a la hora de volverlo a ejecutar el pv.py para leer la lista de clientes y ya no me lo permite alguno sabe que problema puede ser

Traceback (most recent call last):
File “pv.py”, line 114, in <module>
_initialize_clients_from_storage()
File “pv.py”, line 87, in _initialize_cl
for row in reader:
File "C:\Users\SALAZAR\AppData\Local\Progr
ne 112, in next
row = next(self.reader)
ValueError: I/O operation on closed file.

import csv
import os


CLIENT_SCHEMA = ['name', 'company', 'email', 'position']
CLIENT_TABLE = '.clients.csv'
clients = []


def create_client(client):
    global clients

    if client not in clients:
        clients.append(client)
    else:
        print('Client already in client\'s list')


def list_clients():
    print('uid |  name  | company  | email  | position ')
    print('*' * 50)

    for idx, client in enumerate(clients):
        print('{uid} | {name} | {company} | {email} | {position}'.format(
            uid=idx, 
            name=client['name'], 
            company=client['company'], 
            email=client['email'], 
            position=client['position']))


def update_client(client_id, updated_client):
    global clients

    if len(clients) - 1 >= client_id:
        clients[client_id] = updated_client
    else:
        print('Client not in client\'s list')


def delete_client(client_id):
    global clients

    for idx, client in enumerate(clients):
        if idx == client_id:
            del clients[idx] 
            break


def search_client(client_name):
    for client in clients:
        if client['name'] != client_name:
            continue
        else:
            return True


def _get_client_field(field_name, message='What is the client {}?'):
    field = None

    while not field:
        field = input(message.format(field_name))

    return field


def _get_client_from_user():
    client = {
        'name': _get_client_field('name'),
        'company': _get_client_field('company'),
        'email': _get_client_field('email'),
        'position': _get_client_field('position'),
    }

    return client


def _initialize_clients_from_storage():
    if not os.path.exists(CLIENT_TABLE):
        with open(CLIENT_TABLE, mode='w') as f:
            pass

    else:
        with open(CLIENT_TABLE, mode='r') as f:
            reader = csv.DictReader(f, fieldnames=CLIENT_SCHEMA)

        for row in reader:
            clients.append(row)


def _save_clients_to_storage():
        tmp_table_name = '{}.tmp'.format(CLIENT_TABLE)
        with open(tmp_table_name, mode='w') as f:
            writer = csv.DictWriter(f, fieldnames=CLIENT_SCHEMA)
            writer.writerows(clients)

            os.remove(CLIENT_TABLE)
            f.close()
            os.rename(tmp_table_name, CLIENT_TABLE)


def _print_welcome():
    print('WELCOME TO PLATZI VENTAS')
    print('*' * 50)
    print('What would you like to do today?:')
    print('[C]reate client')
    print('[L]ist clients')
    print('[U]pdate client')
    print('[D]elete client')
    print('[S]earch client')


if __name__ == '__main__':
    _initialize_clients_from_storage()
    _print_welcome()

    command = input()
    command = command.upper()

    if command == 'C':
        client = _get_client_from_user()

        create_client(client)
    elif command == 'L':
        list_clients()
    elif command == 'U':
        client_id = int(_get_client_field('id'))
        updated_client = _get_client_from_user()

        update_client(client_id, updated_client)
    elif command == 'D':
        client_id = int(_get_client_field('id'))

        delete_client(client_id)
    elif command == 'S':
        client_name = _get_client_field('name')
        found = search_client(client_name)
        
        if found:
            print('The client is in the client\'s list')
        else:
            print('The client: {} is not in our client\'s list'.format(client_name))
    else:
        print('Invalid command')

    _save_clients_to_storage()```

Estoy trabajando con windows y el comando touch no funciona entonces trate de realizarlo manual, pude crear el cliente ejecuta bien y todo, el problema es a la hora de volverlo a ejecutar el pv.py para leer la lista de clientes y ya no me lo permite alguno sabe que problema puede ser

Traceback (most recent call last):
File “pv.py”, line 114, in <module>
_initialize_clients_from_storage()
File “pv.py”, line 87, in _initialize_cl
for row in reader:
File "C:\Users\PARGA\AppData\Local\Progr
ne 112, in next
row = next(self.reader)
ValueError: I/O operation on closed file.

import csv
import os


CLIENT_SCHEMA = ['name', 'company', 'email', 'position']
CLIENT_TABLE = '.clients.csv'
clients = []


def create_client(client):
    global clients

    if client not in clients:
        clients.append(client)
    else:
        print('Client already in client\'s list')


def list_clients():
    print('uid |  name  | company  | email  | position ')
    print('*' * 50)

    for idx, client in enumerate(clients):
        print('{uid} | {name} | {company} | {email} | {position}'.format(
            uid=idx, 
            name=client['name'], 
            company=client['company'], 
            email=client['email'], 
            position=client['position']))


def update_client(client_id, updated_client):
    global clients

    if len(clients) - 1 >= client_id:
        clients[client_id] = updated_client
    else:
        print('Client not in client\'s list')


def delete_client(client_id):
    global clients

    for idx, client in enumerate(clients):
        if idx == client_id:
            del clients[idx] 
            break


def search_client(client_name):
    for client in clients:
        if client['name'] != client_name:
            continue
        else:
            return True


def _get_client_field(field_name, message='What is the client {}?'):
    field = None

    while not field:
        field = input(message.format(field_name))

    return field


def _get_client_from_user():
    client = {
        'name': _get_client_field('name'),
        'company': _get_client_field('company'),
        'email': _get_client_field('email'),
        'position': _get_client_field('position'),
    }

    return client


def _initialize_clients_from_storage():
    if not os.path.exists(CLIENT_TABLE):
        with open(CLIENT_TABLE, mode='w') as f:
            pass

    else:
        with open(CLIENT_TABLE, mode='r') as f:
            reader = csv.DictReader(f, fieldnames=CLIENT_SCHEMA)

        for row in reader:
            clients.append(row)


def _save_clients_to_storage():
        tmp_table_name = '{}.tmp'.format(CLIENT_TABLE)
        with open(tmp_table_name, mode='w') as f:
            writer = csv.DictWriter(f, fieldnames=CLIENT_SCHEMA)
            writer.writerows(clients)

            os.remove(CLIENT_TABLE)
            f.close()
            os.rename(tmp_table_name, CLIENT_TABLE)


def _print_welcome():
    print('WELCOME TO PLATZI VENTAS')
    print('*' * 50)
    print('What would you like to do today?:')
    print('[C]reate client')
    print('[L]ist clients')
    print('[U]pdate client')
    print('[D]elete client')
    print('[S]earch client')


if __name__ == '__main__':
    _initialize_clients_from_storage()
    _print_welcome()

    command = input()
    command = command.upper()

    if command == 'C':
        client = _get_client_from_user()

        create_client(client)
    elif command == 'L':
        list_clients()
    elif command == 'U':
        client_id = int(_get_client_field('id'))
        updated_client = _get_client_from_user()

        update_client(client_id, updated_client)
    elif command == 'D':
        client_id = int(_get_client_field('id'))

        delete_client(client_id)
    elif command == 'S':
        client_name = _get_client_field('name')
        found = search_client(client_name)
        
        if found:
            print('The client is in the client\'s list')
        else:
            print('The client: {} is not in our client\'s list'.format(client_name))
    else:
        print('Invalid command')

    _save_clients_to_storage()```

Ese es mi codigo ,ya intente de todo, me sale que el permiso esta denegado.

<code>
import os
import csv

CLIENT_SCHEMA=['name','company','email','position']
CLIENT_TABLE='.clients.csv'
clients=[]


def _initialize_clients_from_storage():
	with open(CLIENT_TABLE, mode='r')as f:
		reader=csv.DictReader(f,fieldnames=CLIENT_SCHEMA)

		for row in reader:
			clients.append(row)

def _save_clients_to_storage():
	tmp_table_name = '{}.tmp'.format(CLIENT_TABLE)
	with open(tmp_table_name, mode='w') as f:
		writer = csv.DictWriter(f, fieldnames=CLIENT_SCHEMA)
		writer.writerows(clients)
   os.remove(CLIENT_TABLE)
   os.rename(tmp_table_name, CLIENT_TABLE)



def create_client(client):
	global clients
	if client not in clients:
		clients.append(client)
	else:
		print("Client already is in the client\'s list")

def list_clients():
	global clients
	for i , client in enumerate(clients):
		print("id:{}  name:{}  email:{} company:{} position:{}".format(i,client['name'],client['email'],client['company'],client['position']).split(','))

def update_client(client_id,updated_client):
	global clients
	if len(clients)  >= client_id:
		clients[client_id] = updated_client
	else:
		_client_not_list()


def delete_client(client_id):
	global clients
	if len(clients) >= client_id:
		del clients[client_id]
	else:
		_client_not_list()

def search_client(client_name):
	global clients
	buscar=0

	for client in clients:
	  if client['name']==client_name:
		print(client)
	  else:
		buscar+=1
	if len(clients)<=buscar:
	   print("Client doesn't find")


def _print_welcome():
	print('Welcome my program for sell')
	print('*'*50)
	print('What would you like to do today?')
	print('[C]reate client')
	print("[L]ist clients")
	print('[U]pdate client')
	print('[D]elete client')
	print('[S]earch client')
	print('[E]xit')


def _get_client_field(field_name):
	field=None
	while not field:
		field=raw_input("What is the client {}".format(field_name))


	return field



def _client_not_list():
	return ("Client is not in clients list")


def use_client():
	client = {
		'name': _get_client_field('name'),
		'company': _get_client_field('company'),
		'email': _get_client_field('email'),
		'position': _get_client_field('position')

	}
	return client


if __name__== '__main__':
	  _initialize_clients_from_storage()
	  comand=0

	  while(comand != 'E'):
	   _print_welcome()
	   comand = raw_input()
	   comand = comand.upper()
	   if comand == 'C':
		client=use_client()
		create_client(client)
		raw_input()
	   elif command == 'L':
		list_clients()
		raw_input()
	   elif comand == 'D':
		client_id=int(_get_client_field("id"))
		delete_client(client_id)
		raw_input()
	   elif comand == 'U':
		 client_id = int(_get_client_field('id'))
		 updated_client=use_client()
		 update_client(client_id,updated_client)
		 raw_input()
	   elif comand == 'S':
		 client_name =_get_client_field("name")
		 found=search_client(client_name)
	   elif comand== 'E':
		   break
	   else:
		print('Invalid command')
		raw_input()

	  _save_clients_to_storage()


Muy buena clase, Gracias!

El punto inicial es para ocultar archivos o carpetas

import csv
import os

CLIENT_TABLE = 'clients.csv'
CLIENT_SCHEMA = ['position', 'company', 'name', 'email']
clients = []


def _initialize_clients_from_storage():

    with open(CLIENT_TABLE, mode='r') as f:
        reader = csv.DictReader(f, fieldnames=CLIENT_SCHEMA)

        for row in reader:
            clients.append(row)


def _save_clients_to_storage():
    tmp_table_name = '{}.tmp'.format(CLIENT_TABLE)
    
    with open(tmp_table_name, mode='w') as f:
        writer = csv.DictWriter(f, fieldnames=CLIENT_SCHEMA)
        writer.writerows(clients)

    os.remove(CLIENT_TABLE)
    os.rename(tmp_table_name, CLIENT_TABLE)


def create_client(client):
    global clients

    if client not in clients:
        clients.append(client)
    else:
        print('Client already is in the clients list')


def list_clients():
    global clients

    for idx, client in enumerate(clients):
        try:
            pass
            print('{uid} | {name} | {company} | {email} | {position}'.format(
                uid=idx,
                name=client['name'],
                company=client['company'],
                email=client['email'],
                position=client['position']
            ))
        except KeyError:
            pass


def update_client(client_name):
    global clients

    for client in clients:
        if client['name'] == client_name:

            client['name'] = _get_client_field('new name')
            client['company'] = _get_client_field('new company')
            client['email'] = _get_client_field('new email')
            client['position'] = _get_client_field('new position')

            list_clients()


def delete_client(client_name):
    global clients

    for client in clients:
        if client['name'] == client_name:
            del client['name']
            del client['company']
            del client['email']
            del client['position']


def search_client(client_mame):
    global clients

    for client in clients:
        if client['name'] != client_mame:
            continue
        else:
            return True


def _get_client_field(field_name):
    field = None

    while not field:
        field = input('What is the client {}?'.format(field_name))
    
    return field


def _print_welcome():
    print('WELCOME TO PLATZI VENTAS')
    print('*' * 50)
    print('What would you like to do today?')
    print('[C]reate client')
    print('[D]elete client')
    print('[U]pdate client')
    print('[S]earch client')


if __name__ == '__main__':
    _initialize_clients_from_storage()
    _print_welcome()

    command = input()
    command = command.upper()

    if command == 'C':

        client ={
            'name': _get_client_field('name'),
            'company': _get_client_field('company'),
            'email': _get_client_field('email'),
            'position': _get_client_field('position'),
        }

        create_client(client)
        list_clients()

    elif command == 'D':

        client_name = _get_client_field('name')
        delete_client(client_name)
        list_clients()

    elif command == 'U':

        client_name = _get_client_field('name')
        update_client(client_name)

    elif command == 'S':

        client_name = _get_client_field('name')
        found = search_client(client_name)

        if found:
            print('The client is in the clients list')
        else:
            print('The client: {} is not in the clients list'.format(client_name))
    else:
        print('Invalid command')


    _save_clients_to_storage()

Buenas noches compañeros. Adjunto mi codigo de la practica. Como recomendación (por si no sabian), deben tener cuidado al momento de generar el .csv ya que en algunos sistemas puede generar conflicto con la codificación. En mi caso mi OS es Windows y debe ser codificaciónutf-8

En editores como notepad++ se puede hacer esa verificación

Adjunto código

import sys
import csv
import os
import pandas as pd #libreria para dataframe
############################ Lista de Clientes #####################################
 
CLIENT_SCHEMA = ['Name','Company','Email','Position']
CLIENT_TABLE = '.clients.csv'
#CLIENT_TABLE = open('.clients.csv', encoding="utf8")
clients = [ ## Lista de Clientes
  
        
        ] # Nombres iniciales

def _initialize_clients_from_storage():
    with open(CLIENT_TABLE, mode = 'r') as f:
        reader = csv.DictReader(f, fieldnames = CLIENT_SCHEMA)
        for row in reader:
            clients.append(row)
            
            
def _save_clients_to_storage():
    tmp_table_name = '{}.tmp'.format(CLIENT_TABLE)
    with open(tmp_table_name, mode = 'w') as f:
        writer = csv.DictWriter(f, fieldnames = CLIENT_SCHEMA)
        writer.writerows(clients)
        f.close()        
        os.remove(CLIENT_TABLE)
        os.rename(tmp_table_name,CLIENT_TABLE)
                
############################ Crear Clientes #####################################
def create_client(client):# Crea nuevos clientes
    global clients  #Podemos tomar la variable global dentro de la funcion    
    if client not in clients: # Si el nuevo cliente no esta en la lista
        print('Creando.......') # Muestra aviso   
        clients.append(client) # Lo adiciona          
    else: #Si esta en la lista
        print('Client already is in the client\'s list') # Muestra aviso        
        
############################ Listar Clientes #####################################
def list_clients(): #lista los clientes actuales
    print('uid |  Name  | Company  | Email  | Position ') # Encabezado
    print('='*50)  # Encabezado
    for idx, client in enumerate(clients):
        #print('{}: {}'.format(idx, client['Name'])) 
        print('{uid} | {Name} | {Company} | {Email} | {Position}'.format(
                uid = idx,
                Name = client['Name'],
                Company = client['Company'],
                Email = client['Email'],
                Position = client['Position']))    
  

############################ Actualizar Clientes #####################################      
def update_client(client_id, updated_client):
    global clients
    if len(clients) - 1 >= client_id:
        clients[client_id] = updated_client
    else:
        print('Client not in client\'s list')

############################ Eliminar Clientes #####################################    
def delete_client(client_id):
    global clients

    for idx, client in enumerate(clients):
        if idx == client_id:
            del clients[idx] 
            break
        else:
            return print('Client is not in client\'s list') # Muestra aviso
            
def alert_empty():
    return print('Client is not in client\'s list') # Muestra aviso

############################ Busqueda de Clientes #####################################    

def search_client(client_name):
    for client in clients:
        if client['Name'] != client_name:                        
            continue
        else:
            return True


############################ Funciones Auxiliares ##################################### 

#def _getc_client_name(): # Funcion auxiliar para traer el nombre del cliente
#    client_name = None    
#    while not client_name: # While para que pregunte el nombre
#        client_name = input('What is the client name? ') # Lee el nombre del cliente en el input
#        if client_name == 'exit' or client_name == 'EXIT' or client_name == 'E': #Si se da estas opciones
#           client_name = None
#            break
#        
#        if not client_name: # Libreria sys para salir del codigo/programa
#            sys.exit()
#       
#    return client_name
    

def _get_client_field(field_name):  #Toma los campos introducidos por el usuario
    field = None # Por defecto esta vacio, si sigue asi no entra al sgte while
    while not field:
        field = input('What is the client {}? '.format(field_name))
    return field


def _get_client_from_user(): #Toma la informacion introducida por el cliente
    client = {
        'Name': _get_client_field('Name'),
        'Company': _get_client_field('Company'),
        'Email': _get_client_field('Email'),
        'Position': _get_client_field('Position'),
    }
    return client


def _print_welcome(): #Mensaje de Bienvenida
    print('='*50)
    print("Bienvenidos a PlatziVentas!!!")
    print('='*50)
    print("What would you like to do today?") # Menu de bievenida
    print("[C]reate Client")
    print("[L]ist Client")
    print("[U]pdate Client")
    print("[D]elete Client")
    print("[S]earch Client") 
    
############################ Programa Principal #####################################

if __name__ == '__main__': # Punto de partida/programa principal
    _initialize_clients_from_storage()
    _print_welcome() # Llama mensaje de Bienvenida
    command = input() # Detiene la ejecucion del programa hasta que el usuario inserte el valor
    command = command.upper() #la opcion del usuario la vuelve mayuscula
     
    if command == 'C': #Crear Cliente
        client = {
                'Name': _get_client_field('Name'), # Vaya a las funciones, con el campo en especif
                'Company': _get_client_field('Company'),
                'Email': _get_client_field('Email'),
                'Position': _get_client_field('Position'),
                }
        create_client(client) # Crea el cliente
        list_clients() #Lista los clientes actuales
        
    elif command == 'L': #Lista los Clientes
        list_clients() #Lista los clientes actuales
        
    elif command == 'D': #Borra los Clientes
        client_id = int(_get_client_field('id'))
        delete_client(client_id)
        #list_clients()
        
    elif command == 'U': #Actualiza los clientes
        client_id = int(_get_client_field('id'))
        updated_client = _get_client_from_user()

        update_client(client_id, updated_client)
        #list_clients()
               
        
    elif command == 'S': #Busca los clientes
        client_name = _get_client_field('Name')
        found = search_client(client_name)
        
        if found:
            print('The client is in the client\'s list!!!')
            list_clients()
        else:
            print('The client: {} is not in our client\'s list!!!'.format(client_name))  
            list_clients()              
    
    else:
        print ('Invalid command!!!') #Imprime este aviso
    
    _save_clients_to_storage()
Me aparece este error en mi código pero no se por que esta mal el _initialize_clients_from_storage()

Alguien me podría ayudar a resolver el error de mi código? 

```C:\Users\Asus\Desktop\Respaldo\Documents\CursoPYTHON>platzi.py
Traceback (most recent call last):
  File "C:\Users\Asus\Desktop\Respaldo\Documents\Curso PYTHON\platzi.py", line 111, in <module>
    _initialize_clients_from_storage()
  File "C:\Users\Asus\Desktop\Respaldo\Documents\Curso PYTHON\platzi.py", line 9, in _initialize_clients_from_storage
    with open(CLIENT_TABLE, mode ='r') as f:
FileNotFoundError: [Errno 2] No such file or directory: 'C://Users//Asus//Desktop//Respaldo//Documents//Curso PYTHON .clients.csv'

Excelente, implementado y funcionando

Tengo una duda, tengo entendido que es considerada una mala práctica usar variables globales ¿no es mejor mandar como parámetro el archivo a la funcion que se vaya a usar?

Para guardar los datos no es necesario crear un temporal, se puede realizar

def _save_clients_to_storage():
  with open(CLIENTS_TABLE, "w") as f:
    writer = csv.DictWriter(f, fieldnames=CLIENT_SCHEMA)
    writer.writerows(clients)



Mi aporte:

  • .clients.csv el punto es para ocultar el archivo
  • ./clients.csv De esta manera es para dejar el archivo en la raiz del proyecto
  • Para que evitar crear el archivo manualmente, aquí esta esta funcion:
if not os.path.isfile(CLIENT_TABLE_FILE) or not os.access(CLIENT_TABLE_FILE, os.R_OK):
   open(CLIENT_TABLE_FILE, 'a').close()

Y el código del proyecto:

# -*- codign: utf-8 -*-

import sys, os, csv

# Const
CLIENT_TABLE_FILE='.clients.csv'
CLIENT_SCHEMA=['name', 'company', 'email', 'position']

# Variables & Const
global clients
global options


clients = []
options = [
    'List Client',
    'Create Client',
    'Update Client',
    'Delete Client',
    'Search Client',
    'Exit'
]


def run():
    """Start the software"""
    _init_clients_from_storage()
    show_title()
    read_element()


def show_title():
    """Show custom title of 'Platzi Seller'"""
    complement = title =  ('██████╗ ██╗      █████╗ ████████╗███████╗██╗    ███████╗███████╗██╗     ██╗     ███████╗██████╗')
    title += ('\n██╔══██╗██║     ██╔══██╗╚══██╔══╝╚══███╔╝██║    ██╔════╝██╔════╝██║     ██║     ██╔════╝██╔══██╗')
    title += ('\n██████╔╝██║     ███████║   ██║     ███╔╝ ██║    ███████╗█████╗  ██║     ██║     █████╗  ██████╔╝')
    title += ('\n██╔═══╝ ██║     ██╔══██║   ██║    ███╔╝  ██║    ╚════██║██╔══╝  ██║     ██║     ██╔══╝  ██╔══██╗')
    title += ('\n██║     ███████╗██║  ██║   ██║   ███████╗██║    ███████║███████╗███████╗███████╗███████╗██║  ██║')
    title += ('\n╚═╝     ╚══════╝╚═╝  ╚═╝   ╚═╝   ╚══════╝╚═╝    ╚══════╝╚══════╝╚══════╝╚══════╝╚══════╝╚═╝  ╚═╝')
    # Add Styles
    break_line = ('-' * len(complement) + "\n") * 2
    print("{}\n{}\n{}\n".format(break_line, title, break_line))
    show_menu()


def show_menu():
    """Show the menu of 'Platzi Seller'"""
    print("Write a number of the next options:")
    for key, value in enumerate(options):
        print("{}. {}".format(key, value))


def read_element():
    """Execute and make the process of the actions specifics"""
    response = 'No action allowed'
    option = 0
    while option != len(options) - 1:
        input_data = _get_client_field('Options: ', False)
        if not __empty(input_data) and (input_data.isdigit() == True):
            option = int(input_data)
            response = switch(option)
        print(response)


def switch(option):
    return {
        0: show_all_clients,
        1: create_client,
        2: update_client,
        3: delete_client,
        4: search_client,
        (len(options) - 1): exit_software
    }[option]()


def exit_software():
    sys.exit(0)
    return "Good Bye!"


def show_all_clients():
    """Print all Clients"""
    elements = 'This is your list:\n#'
    for element in CLIENT_SCHEMA:
        elements += " | {}".format(element)
    response = "{}\n".format(elements)
    for key, value in enumerate(clients):
        response += "{index} | {client}".format(index=key, client=print_client(value))
    return response


def print_client(client):
    if len(client) <= 0:
        return 'No exist data for this client'
    return  "{name} | {company} | {email} | {position}\n".format(
        name=client['name'],
        company=client['company'],
        email=client['email'],
        position=client['position'],
    )


def create_client():
    """Create a Client"""
    name = _get_client_field('name')
    company = _get_client_field('company')
    email = _get_client_field('email')
    position = _get_client_field('position')
    if not __empty(name) and not __empty(company) and not __empty(email) and not __empty(position):
        clients.append({ 'name': name, 'company': company, 'email': email, 'position': position })
        _save_client_to_storage()
        return show_all_clients()
    else:
        return "The client have values empty"


def update_client():
    """Update a Client"""
    response = 'Any Change'
    show_all_clients()
    index = _get_client_field('index')
    if _search_client(index):
        index = int(index)
        name = _get_client_field('name')
        company = _get_client_field('company')
        email = _get_client_field('email')
        position = _get_client_field('position')
        if not __empty(name) and not __empty(company) and not __empty(email) and not __empty(position):
            client = { 'name': name, 'company': company, 'email': email, 'position': position }
            clients[index] = client
            response = "Client #{} is updated\n\n{}".format(index, show_all_clients())
            _save_client_to_storage()
    return response


def delete_client():
    """Delete a Client"""
    response = 'Any Change'
    show_all_clients()
    index = _get_client_field('index')
    if _search_client(index):
        index = int(index)
        del clients[index]
        response = "Client #{} is deleted\n\n{}".format(index, show_all_clients())
        _save_client_to_storage()
    return response


def _search_client(index, get_object = False):
    response = False
    if get_object:
        response = "Client not found"
    if not __empty(index):
        index = int(index)
        if __checkRangeArray(index, clients):
            response = True
            if get_object:
                response = clients[index]
    return response


def search_client():
    show_all_clients()
    index = _get_client_field('index')
    return print_client(_search_client(index, True))


# Complements
def __empty(value):
    response = True
    if value and value != None:
        if len(value) >= 0:
            response = False
    return response


def __checkRangeArray(index, array):
    return index >= 0 and index <= len(array) - 1


def _get_client_field(message, option = True):
    field = None
    while __empty(field):
        title = ''
        if option:
            title = "What is the client {message}? ".format(message=message)
        else:
            title = message
        field = input(f'\n{title}')
    return field


# Files
def _init_clients_from_storage():
    if not os.path.isfile(CLIENT_TABLE_FILE) or not os.access(CLIENT_TABLE_FILE, os.R_OK):
        open(CLIENT_TABLE_FILE, 'a').close()
    with open(CLIENT_TABLE_FILE, mode="r") as file:
        reader = csv.DictReader(file, fieldnames=CLIENT_SCHEMA)
        for row in reader:
            clients.append(row)


def _save_client_to_storage():
    tmp_table = '{}.tmp'.format(CLIENT_TABLE_FILE)
    with open(tmp_table, mode="w") as file:
        writer = csv.DictWriter(file, fieldnames=CLIENT_SCHEMA)
        writer.writerows(clients)
        # Modify Files
        os.remove(CLIENT_TABLE_FILE)
        os.rename(tmp_table, CLIENT_TABLE_FILE)


if __name__ == '__main__':
    run()

me aparece el siguiente error y por más que intento no logro resolverlo:

Traceback (most recent call last):
  File "C:\Users\Samuel\Desktop\Platzi\Curso Python\main.py", line 141, in <module>
    _save_clients_to_storage()
  File "C:\Users\Samuel\Desktop\Platzi\Curso Python\main.py", line 22, in _save_clients_to_storage
    writer.writerows(clients)
  File "C:\Users\Samuel\AppData\Local\Programs\Python\Python37\lib\csv.py", line 158, in writerows
    return self.writer.writerows(map(self._dict_to_list, rowdicts))
  File "C:\Users\Samuel\AppData\Local\Programs\Python\Python37\lib\csv.py", line 148, in _dict_to_list
    wrong_fields = rowdict.keys() - self.fieldnames
TypeError: unhashable type: 'list'```

hola me puede ayudar con este error, AttributeError: ‘NoneType’ object has no attribute ‘keys’ y lo esta generando esta linea, File “clientes1.py”, line 26, in _save_clients_to_storage
writer.writerows(clients)

import os

print("\nCrear un archivo")
print("=================")

NOMBRE_ARCHIVO = 'datos.txt'

archivo = open(NOMBRE_ARCHIVO, 'w')
archivo.write('Esta es una prueba \ny otra prueba.')
archivo.close

if NOMBRE_ARCHIVO in os.listdir("."):
    print ("\nArchivo creado en la ruta: \n\n\t{0}/{1}".format(
        os.getcwd(), NOMBRE_ARCHIVO))
else:
    print ("El archivo no fue creado!!!\n")```

El . al principio simboliza que es en directorio actual

import sys;
import csv;
import os;

CLIENT_TABLE = '.clients.csv';
CLIENT_SCHEMA = ['name', 'company', 'email', 'position'];
clients = [];

def _initialize_client_from_storage():
    with open(CLIENT_TABLE, mode='r') as f:
        reader = csv.DictReader(f, fieldnames=CLIENT_SCHEMA);

        for row in reader:
            clients.append(row);


def _save_client_to_starage():
    tmp_table_name = '{}.tmp'.format(CLIENT_TABLE);

    with open(tmp_table_name, mode='w') as f:
        writer = csv.DictWriter(f, fieldnames=CLIENT_SCHEMA);
        writer.writerows(clients);

        os.remove(CLIENT_TABLE);
        os.rename(tmp_table_name, CLIENT_TABLE);



def create_client(client):
    global clients

    if client not in clients:
        clients.append(client);
    else:
        print('Client already in the client\'s list');


def list_clients():
    for idx, client in enumerate(clients):
        print('{uid} | {name} | {email} | {company} | {postion} '.format(
            uid = idx,
            name = client['name'],
            email = client['email'],
            company = client['company'],
            postion = client['position']
        ));

def update_client(client_name):
    global clients;

    for idx, client in enumerate(clients):
        if client['name'] == client_name:
            clients[idx] = {
                'name': _get_client_field('name'),
                'company': _get_client_field('company'),
                'email': _get_client_field('email'),
                'position': _get_client_field('postion'),
            }
            break;
        elif client == clients[-1]:
            print('Client name isn\'t in clients list');
        else:
            continue;


def delete_client(client_name):
    global clients;

    for idx, client in enumerate(clients):
        if client['name'] == client_name:
            clients.pop(idx);
            break;
        elif client == clients[-1]:
            print('Client name isn\'t in clients list');
        else:
            continue;

def search_client():
    global clients

    client_name = _get_client_name();

    for client in clients:
        if client['name'] == client_name:
            return True;
            break;
        else:
            continue;


def _get_client_name():
    return input('What is the client name?: ').capitalize();


def _get_client_field(field):
    global clients;

    _field = None;

    while not _field:
        _field = input('What is the client {}: '.format(field));

        if field == 'exit':
            sys.exit();

    if field == 'name':
        for field_name in clients:
            if field_name['name'] == _field.capitalize():
                print('Client already in the client\'s list');
                sys.exit();

    if field == 'email':
        return _field;

    return _field.capitalize();

def _print_welcome():
    print('WELCOME TO PLATZI VENTAS');
    print('*' * 50);
    print('What would do you today ?');
    print('''
        [c]reate client
        [u]pdate client
        [d]elete client
        [s]earch client
        [l]ist clients
    ''')

if __name__ == "__main__":
    _initialize_client_from_storage();
    _print_welcome();

    command = input().lower();

    if command == 'c':
        client = {
            'name': _get_client_field('name'),
            'company': _get_client_field('company'),
            'email': _get_client_field('email'),
            'position': _get_client_field('postion'),
        }
        create_client(client);
    elif command == 'd':
        client_name = _get_client_name();
        delete_client(client_name);
    elif command == 'u':
        client_name = _get_client_name();
        update_client(client_name);
    elif command == 's':
        client_found = search_client();

        if client_found:
            print('The client is in the client\'s list');
        else:
            print('The client is not in our client\'s list'.format());
    elif command == 'l':
        list_clients();
    else:
        print('Invalided command');

    _save_client_to_starage();

que buena clase!!

en el momento de la funcion

def _save_clients_to_storage():
    tmp_table_name = f'{CLIENT_TABLE}.tmp'
    with open(tmp_table_name, mode='w') as f:
        writer = csv.DictWriter(f, fieldnames=CLIENT_SCHEMA)
        writer.writerows(clients)

        os.remove(CLIENT_TABLE)
        f.close()
        os.rename(tmp_table_name, CLIENT_TABLE)
        ```

yo he resuelto un problema que me arrojo el programa que me indicaba que escribia en la tabla y luego al renombrarla como no estaba cerrada la tabla me indicaba que estaba siendo utilizada en otro proceso con lo cual, he tenido que cerrar la tabla antes de renombrarla y me ha funcionado perfectamente.

El remover la tabla no permite ir guardando todos los contactos. Antes de ingresar a Tom, estaba David, pero luego de ingresarlo no se mantuvo ni se agregó a la tabla general de guardado en csv.

no entiendo porque no me coje el .csv si ya lo creee
, cuals seria el comando en windows para ahcer eso

  • La función open nos permite abrir archivo y la función close cerrarlos.
  • La mejor manera de manipular archivo es usar context manager with open(filename) as f
  • Tiene varios modos de apertura como r (read), w (write).
  • Para manipular archivos csv podemos usar csv.reader y csv.writer, también podemos manipular los archivos csv con dictionarios con csv.dicrteader y csv,dictwriter.

#💩 Hay errores que te sirven para aprender y otros que te sirven para perder el tiempo. Tuve una mezcla de los dos. 🤷🏽‍♂️ 🤦🏽‍♂️
.
Después de que abriera el archivo, pero me saliera el error[errno 2] leyendo en los comentarios pensé que se trataba de marcar el path del archivo. copié y pegué el path (en macOS) por lo que un nuevo error saltó y ya no abría el archivo.
.
Un par de horas surfeando la web e iterando soluciones dí con un artículo en stackoverflow que me salvó y pude abrir el archivo de nuevo. El error/solución era el siguiente:

Re-type your variable filePath = /Users/Jose/Documents manually

There are some invisible 'LEFT-TO-RIGHT MARK' (u200e) and 'FIRST STRONG ISOLATE' (u2068) characters in the string

Sucede que cuando copias y pegas un Path en un IDE muchas veces tienen cosas “invisibles” como el u200e y u2068. Solución: escribir a mano el Path.
.
Problema 2 solucionado persistía el problema 2. Es cuando me di cuenta que había puesto mal el archivo a abrir. Había puesto CLIENT_TABLE en lugar de tmp_table_name.
.

Cosas valiosas encontradas durante esta búsqueda:

.
The Absolute Minimum Every Software Developer Absolutely Positively Must Know About Unicode and Character Sets No Excuses
.

  • Make sure the file exists: use os.listdir() to see the list of files in the current working directory
  • Make sure you’re in the directory you think you’re in with os.getcwd() (if you launch your code from an IDE, you may well be in a different directory)
    .
    Let me clarify how Python finds files:
    .
  • An absolute path is a path that starts with your computer’s root directory, for example ‘C:\Python\scripts…’ if you’re on Windows.
    .
  • A relative path is a path that does not start with your computer’s root directory, and is instead relative to something called the working directory. You can view Python’s current working directory by calling os.getcwd().

funciona el codigo :v algo que me funciona por fin, luego de copiar el codigo del video, y lo hice en javascript, sin local storage, muy chevere, a ver si se puede profundizar mas en este lenguaje

Excelente, muchas gracias

import sys
import csv
import os

CLIENT_TABLE = '.clients.csv'
CLIENT_SCHEMA = ['name', 'company', 'email', 'position']
clients = []

def _initialize_clients_from_storage():
    with open(CLIENT_TABLE, mode='r') as f:
        reader = csv.DictReader(f, fieldnames=CLIENT_SCHEMA)

        for row in reader:
            clients.append(row)


def _save_clients_to_storate():
    tmp_table_name = '{}.tmp'.format(CLIENT_TABLE)
    with open(tmp_table_name, mode='w') as f:
        writer = csv.DictWriter(f, fieldnames=CLIENT_SCHEMA)
        writer.writerows(clients)

    os.remove(CLIENT_TABLE)
    os.rename(tmp_table_name, CLIENT_TABLE)
    


def create_client(client):
    global clients

    if client not in clients:
        clients.append(client)
    else:
        print('Client already is in the client\'s list')


def list_clients():
    global clients

    for idx, client in enumerate(clients):
        print('{uid} | {name} | {company} | {email} | {position}'.format(
            uid = idx,
            name = client['name'],
            company=client['company'],
            email= client['email'],
            position = client['position']
        ))


def update_client(client_id, updated_client_name):
    global clients

    if len(clients) - 1 >= client_id:
        clients[client_id] = updated_client_name
    else:
        _print_message_client()

    # if client_name in clients:
    #     index = clients.index(client_name)
    #     clients[index] = updated_client_name
    # else:
    #     _print_message_client()


def delete_client(client_id):
    global clients

    for idx, client in enumerate(clients):
        if idx == client_id:
            del clients[idx]
            break


def seach_client(client_name):
    global clients

    for client in clients:
        if client['name'] != client_name:
            continue
        else:
            return True

def _get_client_field(field_name, message='What is the client {}? '):
    field = None

    while not field:
        field = input(message.format(field_name))

    return field

def _get_client_from_user():
    client = {
        'name': _get_client_field('name'),
        'company': _get_client_field('company'),
        'email': _get_client_field('email'),
        'position': _get_client_field('position'),
    }

    return client


def _print_welcome():
    print('=' * 40)
    print('Welcome to Platzi ventas')
    print('=' * 40)
    print('What would you like to do today')
    print('-' * 40)
    print('[C]reate client')
    print('[L]ist   client')
    print('[U]pdate client')
    print('[D]elete client')
    print('[S]earch client')
    print('*' * 40)


def _get_client_name():
    client_name = None

    while not client_name:
        client_name = input('What is the client name? ')

        if client_name == 'exit':
            client_name = None
            break

    if not client_name:
        sys.exit()

    return client_name


def _print_message_client():
    print('Client is not in clients list')

if __name__ == '__main__':
    _initialize_clients_from_storage()

    _print_welcome()

    command = input()
    command = command.upper()

    if command == 'C':
        client = {
            'name': _get_client_field('name'),
            'company': _get_client_field('company'),
            'email': _get_client_field('email'),
            'position': _get_client_field('position'),
        }

        create_client(client)
    elif command == 'D':
        client_id = int(_get_client_field('id'))
        delete_client(client_id)
    elif command == 'L':
        list_clients()
    elif command == 'U':
        client_id = int(_get_client_field('id'))

        updated_client_name = _get_client_from_user()
        update_client(client_id, updated_client_name)
    elif command == 'S':
        client_name = _get_client_field('name')
        found = seach_client(client_name)
        if found:
            print('The client is in the client\'s list')
        else:
            print('The client: {} is not in our client\'s list'.format(client_name))
    else:
        a = 1
        b = 2
        print(a)
        print(b)
        #a, b = b, a + b
        a = b
        b = a + b
        print(a)
        print(b)
        print('Invalid command')

    _save_clients_to_storate()