For a project I'm creating an online library system. Now, I have loaded the books and all their info with a json file. The json file looks something like this:
[
{
"author": "Unknown",
"country": "Sumer and Akkadian Empire",
"imageLink": "images/the-epic-of-gilgamesh.jpg",
"language": "Akkadian",
"link": "https://en.wikipedia.org/wiki/Epic_of_Gilgamesh\n",
"pages": 160,
"title": "The Epic Of Gilgamesh",
"ISBN": "978123438397",
"year": -1700
},
{
"author": "Unknown",
"country": "Achaemenid Empire",
"imageLink": "images/the-book-of-job.jpg",
"language": "Hebrew",
"link": "https://en.wikipedia.org/wiki/Book_of_Job\n",
"pages": 176,
"title": "The Book Of Job",
"ISBN": "9781238427897",
"year": -600
},
{
"author": "Unknown",
"country": "India/Iran/Iraq/Egypt/Tajikistan",
"imageLink": "images/one-thousand-and-one-nights.jpg",
"language": "Arabic",
"link": "https://en.wikipedia.org/wiki/One_Thousand_and_One_Nights\n",
"pages": 288,
"title": "One Thousand and One Nights",
"ISBN": "9781234564897",
"year": 1200
},
{
"author": "Unknown",
"country": "Iceland",
"imageLink": "images/njals-saga.jpg",
"language": "Old Norse",
"link": "https://en.wikipedia.org/wiki/Nj%C3%A1ls_saga\n",
"pages": 384,
"title": "Nj\u00e1l's Saga",
"ISBN": "9781234566827",
"year": 1350
},
{
"author": "Jane Austen",
"country": "United Kingdom",
"imageLink": "images/pride-and-prejudice.jpg",
"language": "English",
"link": "https://en.wikipedia.org/wiki/Pride_and_Prejudice\n",
"pages": 226,
"title": "Pride and Prejudice",
"ISBN": "9781234955897",
"year": 1813
},
{
"author": "Honor\u00e9 de Balzac",
"country": "France",
"imageLink": "images/le-pere-goriot.jpg",
"language": "French",
"link": "https://en.wikipedia.org/wiki/Le_P%C3%A8re_Goriot\n",
"pages": 443,
"title": "Le P\u00e8re Goriot",
"ISBN": "9781234525797",
"year": 1835
},
{
"author": "Samuel Beckett",
"country": "Republic of Ireland",
"imageLink": "images/molloy-malone-dies-the-unnamable.jpg",
"language": "French, English",
"link": "https://en.wikipedia.org/wiki/Molloy_(novel)\n",
"pages": 256,
"title": "Molloy, Malone Dies, The Unnamable, the trilogy",
"ISBN": "9781234767747",
"year": 1952
},
{
"author": "Giovanni Boccaccio",
"country": "Italy",
"imageLink": "images/the-decameron.jpg",
"language": "Italian",
"link": "https://en.wikipedia.org/wiki/The_Decameron\n",
"pages": 1024,
"title": "The Decameron",
"ISBN": "9781235622297",
"year": 1351
},
{
"author": "Jorge Luis Borges",
"country": "Argentina",
"imageLink": "images/ficciones.jpg",
"language": "Spanish",
"link": "https://en.wikipedia.org/wiki/Ficciones\n",
"pages": 224,
"title": "Ficciones",
"ISBN": "9781234562237",
"year": 1965
},
{
"author": "Emily Bront\u00eb",
"country": "United Kingdom",
"imageLink": "images/wuthering-heights.jpg",
"language": "English",
"link": "https://en.wikipedia.org/wiki/Wuthering_Heights\n",
"pages": 342,
"ISBN": "9781234567897",
"title": "Wuthering Heights",
"year": 1847
},
{
"author": "Albert Camus",
"country": "Algeria, French Empire",
"imageLink": "images/l-etranger.jpg",
"language": "French",
"link": "https://en.wikipedia.org/wiki/The_Stranger_(novel)\n",
"pages": 185,
"title": "The Stranger",
"ISBN": "9781234562447",
"year": 1942
}
]
One of the requirements is to be able to add, edit and delete a book in the library system. I tried to program a function which adds a book to the system/json file, but it will append after the squared bracket in the json file. And I need it to append right before the last squared bracket. This is the piece of that is supposed add a book:
def addBook(self):
print("Please fill in the following information:")
author = input("Author: ")
country = input("Country: ")
image = input("Image Link: ")
lang = input("Language: ")
link = input("Link: ")
pages = int(input("Pages: "))
title = input("Title: ")
isbn = input("ISBN: ")
year = int(input("Year: "))
y = { "author": author,
"country": country,
"imageLink": image,
"language": lang,
"link": link,
"pages": pages,
"title": title,
"ISBN": isbn,
"year": year
}
a_file = open("books.json", "a")
json.dump(y, a_file)
a_file.close()
Then I also tried to code a function that can edit the details of a book, but I failed miserably. First there is a feature which searches for the book you want, then I need to find a way to select a book:
def selectCatalogue(self):
os.system('cls')
bookInfo = input("Please fill the author or title of the book in: ")
m = 1
for i in data:
if bookInfo.casefold() in i['author'].casefold():
print('['+ str(m) + '] '+ 'Author: '+ i['author'])
print(' ' + 'Country: ' + i['country'])
print(' ' + 'Image link: ' + i['imageLink'])
print(' ' + 'Language: ' + i['language'])
print(' ' + 'Link: ' + i['link'])
print(' ' + 'Pages: ' + str(i['pages']))
print(' ' + 'Title: ' + i['title'])
print(' ' + 'ISBN: ' + i['ISBN'])
print(' ' + 'Year: ' + str(i['year']))
print(' ')
m = m + 1
if bookInfo.casefold() in i['title'].casefold():
print('['+ str(m) + '] '+ 'Author: '+ i['author'])
print(' ' + 'Country: ' + i['country'])
print(' ' + 'Image link: ' + i['imageLink'])
print(' ' + 'Language: ' + i['language'])
print(' ' + 'Link: ' + i['link'])
print(' ' + 'Pages: ' + str(i['pages']))
print(' ' + 'Title: ' + i['title'])
print(' ' + 'ISBN: ' + i['ISBN'])
print(' ' + 'Year: ' + str(i['year']))
print(' ')
m = m + 1
choice = input("Please enter the number of the book you were looking for: ")
# if choice == m:
# need to find a way to select a book
Then I programmed a function which is supposed to be able to edit details of the book:
def editBook(self):
Catalogue().selectCatalogue()
print("What do you want to edit? ")
print('[1] Author')
print('[2] Country')
print('[3] Image link')
print('[4] Language')
print('[5] Link')
print('[6] Pages')
print('[7] Title')
print('[8] ISBN')
print('[9] Year')
choice = input()
with open("books.json", "r+") as jsonFile:
data = json.load(jsonFile)
if choice == '1':
# with open("replayScript.json", "r+") as jsonFile:
# data = json.load(jsonFile)
data["author"] = input("Please enter the new author name: ")
if choice == '2':
data["country"] = input("Please enter the new country name: ")
if choice == '3':
data["imageLink"] = input("Please enter the new image link: ")
if choice == '4':
data["language"] = input("Please enter the new language: ")
if choice == '5':
data["link"] = input("Please enter the new link: ")
if choice == '6':
data["author"] = int(input("Please enter the new number of pages: "))
if choice == '7':
data["title"] = input("Please enter the new title: ")
if choice == '8':
data["ISBN"] = int(input("Please enter the new ISBN: "))
if choice == '9':
data["year"] = int(input("Please enter the new year: "))
Lastly I need to make a function that can delete books, but I'm clueless.
Is there someone who can help me with this? I would really appreciate it!!
Add : Have a look here, I think they explain quite well why you can't just append a new book to the end of your json.
You have a json with a list of dictionaries. If you want to add or delete a book, just get access to a single list element (which is a dictionary) and remove the element, or in case you want to add a book, load the data, append your new book and dump it back to json:
with open('your_json.json', 'r') as f:
data = json.load(f)
data.append(new_book) #new_book is the dict with the new book information
with open('new_json.json', 'w') as g:
json.dump(data, g)
SelectCatalogue():
You don't need to look twice for book or author, you can do that in one step.
At the end you have a variable choice, where you want to select a book by a number, I guess this is in case you have multiple books by one author and you want to select only one specific? You don't need that m as counter, just use enumerate, so you have a number (which is the list index of the dict) for each book.
def selectCatalogue():
bookInfo = input("Please fill the author or title of the book in: ")
for idx, dic in enumerate(data):
if bookInfo.casefold() in [dic['author'].casefold(), dic['title'].casefold()]:
print('['+ str(idx) + '] '+ 'Author: '+ dic['author'])
print(' ' + 'Country: ' + dic['country'])
print(' ' + 'Image link: ' + dic['imageLink'])
print(' ' + 'Language: ' + dic['language'])
print(' ' + 'Link: ' + dic['link'])
print(' ' + 'Pages: ' + str(dic['pages']))
print(' ' + 'Title: ' + dic['title'])
print(' ' + 'ISBN: ' + dic['ISBN'])
print(' ' + 'Year: ' + str(dic['year']))
print(' ')
choice = int(input("Please enter the number of the book you were looking for: "))
data[choice] # <-- this will get you access to one dict which you can print like above if you want
return choice
I added the return statement because you can use it in the edit_book() function to access the book you want to change information.
Here is the new edit function, which asks for book/author, then the number you want (and stores it), then asks which information you want to change, at the end dump the new json to a json file.
def editBook():
book_idx = selectCatalogue() # you need it to access later when editing information
print("What do you want to edit? ")
print('[1] Author')
print('[2] Country')
print('[3] Image link')
print('[4] Language')
print('[5] Link')
print('[6] Pages')
print('[7] Title')
print('[8] ISBN')
print('[9] Year')
choice = input()
with open("books.json", "r") as jsonFile:
data = json.load(jsonFile)
# data is the whole list of dicts, you want to access one element of the list, book_idx added
if choice == '1':
data[book_idx]["author"] = input("Please enter the new author name: ")
if choice == '2':
data[book_idx]["country"] = input("Please enter the new country name: ")
if choice == '3':
data[book_idx]["imageLink"] = input("Please enter the new image link: ")
if choice == '4':
data[book_idx]["language"] = input("Please enter the new language: ")
if choice == '5':
data[book_idx]["link"] = input("Please enter the new link: ")
if choice == '6':
data[book_idx]["author"] = int(input("Please enter the new number of pages: "))
if choice == '7':
data[book_idx]["title"] = input("Please enter the new title: ")
if choice == '8':
data[book_idx]["ISBN"] = int(input("Please enter the new ISBN: "))
if choice == '9':
data[book_idx]["year"] = int(input("Please enter the new year: "))
#write the edited list of dicts back to json
with open('books_edited.json', 'w') as jsonFile:
json.dump(data, jsonFile)
Regarding your last problem, deleting a book:
As you can see I accessed the dictionary with its list index in the other functions. For this task you just need to call the selectCatalogue() and save the chosen book index to a variable. Then delete that element data[index] and write the new data back to json.
You should be able to get that done by yourself now :)
Since you work in a class and I don't have it, I removed some of the parts to get it running. Don't forget to add it back to it.
Related
This question already has an answer here:
How to create a counter that counts unrighteous inputs
(1 answer)
Closed 2 months ago.
I need to put this code in a loop so that you can choose whichever number first and go back to the start after whichever one you choose, but everything I've tried hasn't worked and need help.
peoples = {
"Mary": {
"name": "Mary",
"budget": 100,
"items": {
"Game": 0,
"Book": 0,
"Kindle": 0
},
"status": "incomplete"
},
"Steve": {
"name": "Steve",
"budget": 100,
"items": {
"Tie": 0,
"Scarf": 0,
"Amazon Echo": 0
},
"status": "incomplete"
},
"Kevin": {
"name": "Kevin",
"budget": 65,
"items": {
"Mario Kart": 0
},
"status": "incomplete"
},
"Jane": {
"name": "Jane",
"budget": 50,
"items": {
"Gift Card": 0,
"Gloves": 0
},
"status": "incomplete"
},
"Chris": {
"name": "Chris",
"budget": 100,
"items": {
"Chocolates": 0,
"Galaxy Tab": 0
},
"status": "incomplete"
}
}
print("""
Menu
--------------------
1. Update Shopping List
2. Complete Shopping List
3. Display Shopping List
4. Exit Application
--------------------
Make your selection
""")
option = int(input("Enter an option: "))
if option == 1:
people = input("Who are you updating?: ")
print("\nCurrent values of people",people)
print(peoples[people])
print("\nAvailable items and their prices are:")
for item in peoples[people]["items"]:
print(item, peoples[people]["items"][item])
item_to_update = input("Enter an item to update: ")
price = int(input("Enter updated price: "))
budget = peoples[people]["budget"] - peoples[people]["items"]
[item_to_update] - price
peoples[people]["items"][item_to_update] = price
peoples[people]["budget"] = budget
print("\nUpdated values of people",people)
print(peoples[people])
option = int(input("\nEnter an option: "))
if option == 2:
update = input("Choose one of the 5 people to complete their shopping list: ")
if update in peoples:
print("You have chosen",update)
answer = input("Do you want to complete their shopping list (Y/N)? ")
if answer.upper() == "Y":
peoples[people]['status'] = 'complete'
print("Shopping list has been completed!")
option = int(input("\nEnter an option: "))
if option == 3:
display = input("Who's do you want to look at?: ")
print("\nShopping List Of",display)
print(peoples[display])
option = int(input("\nEnter an option: "))
if option == 4:
print("Thank You For Shopping With Us!")
I've tried putting in different versions of loop, but it always either results in the program ignoring it and not going back to the start, or breaking when I choose something else then 1 at the start.
option = input("Enter an option: ")
if option == "1":
people = input("\nWho are you updating?: ")
print("\nCurrent values of people",people)
print(peoples[people])
print("\nAvailable items and their prices are:")
for item in peoples[people]["items"]:
print(item, peoples[people]["items"][item])
item_to_update = input("Enter an item to update: ")
price = int(input("Enter updated price: "))
budget = peoples[people]["budget"] - peoples[people]["items"][item_to_update] - price
peoples[people]["items"][item_to_update] = price
peoples[people]["budget"] = budget
print("\nUpdated values of people",people)
print(peoples[people])
elif option == "2":
update = input("Choose one of the 5 people to complete their shopping list: ")
if update in peoples:
print("You have chosen",update)
peoples[people]['status'] = 'complete'
print("Shopping list has been completed!")
elif option == "3":
display = input("Who's do you want to look at?: ")
print("\nShopping List Of",display)
print(peoples[display])
elif option == "4":
print("Thank You For Shopping With Us!")
break
else:
print("That's not a valid answer! Try again!")
With the same list above, After adding in my information to the set example given, I would get the error below.
error with pic: https://i.stack.imgur.com/BrqBB.png
peoples = {
"Mary": {
"name": "Mary",
"budget": 100,
"items": {
"Game": 0,
"Book": 0,
"Kindle": 0
},
"status": "incomplete"
},
"Steve": {
"name": "Steve",
"budget": 100,
"items": {
"Tie": 0,
"Scarf": 0,
"Amazon Echo": 0
},
"status": "incomplete"
},
"Kevin": {
"name": "Kevin",
"budget": 65,
"items": {
"Mario Kart": 0
},
"status": "incomplete"
},
"Jane": {
"name": "Jane",
"budget": 50,
"items": {
"Gift Card": 0,
"Gloves": 0
},
"status": "incomplete"
},
"Chris": {
"name": "Chris",
"budget": 100,
"items": {
"Chocolates": 0,
"Galaxy Tab": 0
},
"status": "incomplete"
}
}
print("""
Menu
--------------------
1. Update Shopping List
2. Complete Shopping List
3. Display Shopping List
4. Exit Application
--------------------
Make your selection
""")
while True:
option = input("Enter an option: ")
if option == "1":
people = input("\nWho are you updating?: ")
print("\nCurrent values of people",people)
print(peoples[people])
print("\nAvailable items and their prices are:")
for item in peoples[people]["items"]:
print(item, peoples[people]["items"][item])
item_to_update = input("Enter an item to update: ")
price = int(input("Enter updated price: "))
budget = peoples[people]["budget"] - peoples[people]["items"][item_to_update] - price
peoples[people]["items"][item_to_update] = price
peoples[people]["budget"] = budget
print("\nUpdated values of people",people)
print(peoples[people])
elif option == "2":
update = input("Choose one of the 5 people to complete their shopping list: ")
if update in peoples:
print("You have chosen",update)
peoples[people]['status'] = 'complete'
print("Shopping list has been completed!")
elif option == "3":
display = input("Who's do you want to look at?: ")
print("\nShopping List Of",display)
print(peoples[display])
elif option == "4":
print("Thank You For Shopping With Us!")
break
else:
print("That's not a valid answer! Try again!")
It now looks exactly like this, and it still gives back a syntax error on the first elif statement. I don't understand what the problem is if it's properly indented and should follow the correct rules to use it.
edited with error: https://i.stack.imgur.com/rTW6k.png
The syntax error is finally gone, but now lies the problem where the code just repeats itself on the menu screen without going anywhere, like this:
repeating: https://i.stack.imgur.com/YNPdF.png
I would do something like this:
while True:
print(<instructions>)
option = input("Enter an option: ")
if option == "1":
do stuff...
elif option == "2":
do number two stuff..
elif option == "3":
do that third stuff..
elif option == "4":
print("Thank You For Shopping With Us!")
break
else:
print("That's not a valid answer! Try again!")
This will keep the menu in a loop and if option 4 is selected, it will break from the loop and continue on.
The issue now is with your indentation. You must indent your code properly for python to be able to understand what you want it to do, for instance:
x= "3"
if x == "2":
print("hello world")
print("outside the indent")
you console output would be:
>>outside the indent
but if your code looks like this:
x= "3"
if x == "2":
print("hello world")
print("outside the indent")
you would get no output from the console, everything is within the "if" code block. Indentation is crucial for python to exhibit the expected behavior. you need to make sure that all your code for each condition is indented properly inside the if blocks, like the example I gave above. Also, if you want this in a loop, you need to put it in a loop with the while True: statement, and indent everything inside it.
Your final result should look something like this:
peoples = {
"Mary": {
"name": "Mary",
"budget": 100,
"items": {
"Game": 0,
"Book": 0,
"Kindle": 0
},
"status": "incomplete"
},
"Steve": {
"name": "Steve",
"budget": 100,
"items": {
"Tie": 0,
"Scarf": 0,
"Amazon Echo": 0
},
"status": "incomplete"
},
"Kevin": {
"name": "Kevin",
"budget": 65,
"items": {
"Mario Kart": 0
},
"status": "incomplete"
},
"Jane": {
"name": "Jane",
"budget": 50,
"items": {
"Gift Card": 0,
"Gloves": 0
},
"status": "incomplete"
},
"Chris": {
"name": "Chris",
"budget": 100,
"items": {
"Chocolates": 0,
"Galaxy Tab": 0
},
"status": "incomplete"
}
}
print("""
Menu
--------------------
1. Update Shopping List
2. Complete Shopping List
3. Display Shopping List
4. Exit Application
--------------------
Make your selection
""")
while True:
option = input("Enter an option: ")
if option == "1":
people = input("\nWho are you updating?: ")
print("\nCurrent values of people",people)
print(peoples[people])
print("\nAvailable items and their prices are:")
for item in peoples[people]["items"]:
print(item, peoples[people]["items"][item])
item_to_update = input("Enter an item to update: ")
price = int(input("Enter updated price: "))
budget = peoples[people]["budget"] - peoples[people]["items"][item_to_update] - price
peoples[people]["items"][item_to_update] = price
peoples[people]["budget"] = budget
print("\nUpdated values of people",people)
print(peoples[people])
elif option == "2":
update = input("Choose one of the 5 people to complete their shopping list: ")
if update in peoples:
print("You have chosen",update)
peoples[people]['status'] = 'complete'
print("Shopping list has been completed!")
elif option == "3":
display = input("Who's do you want to look at?: ")
print("\nShopping List Of",display)
print(peoples[display])
elif option == "4":
print("Thank You For Shopping With Us!")
break
else:
print("That's not a valid answer! Try again!")
Also, please review this link as it is crucial you understand how to properly indent your code when writing python.
https://www.geeksforgeeks.org/indentation-in-python/
Can I somehow delete a value from a dictionary using its key?
The function del_contact is supposed to delete a contact using only the name of the contact, but unfortunately I have the dictionary and the value, but not the key. How can this be solved?
my_contacts = {
1: {
"Name": "Tom Jones",
"Number": "911",
"Birthday": "22.10.1995",
"Address": "212 street"
},
2: {
"Name": "Bob Marley",
"Number": "0800838383",
"Birthday": "22.10.1991",
"Address": "31 street"
}
}
def add_contact():
user_input = int(input("please enter how many contacts you wanna add: "))
index = len(my_contacts) + 1
for _ in range(user_input):
details = {}
name = input("Enter the name: ")
number = input("Enter the number: ")
birthday = input("Enter the birthday")
address = input("Enter the address")
details["Name"] = name
details["Number"] = number
details["Birthday"] = birthday
details["Address"] = address
my_contacts[index] = details
index += 1
print(my_contacts)
def del_contact():
user_input = input("Please enter the name of the contact you want to delete: ")
my_contacts.pop(user_input)
add_contact()
print(my_contacts)
The problem is that my key of the dictionary is 1 or Name, and I want to be able to remove the contact using only the value of Name.
Basically what you can do is iterate of the dict and save only the keys without that user's name.
This code will do the trick:
my_contacts = {1: {"Name": "Tom Jones",
"Number": "911",
"Birthday": "22.10.1995",
"Address": "212 street"},
2: {"Name": "Bob Marley",
"Number": "0800838383",
"Birthday": "22.10.1991",
"Address": "31 street"}
}
user_input = "Tom Jones"
my_contacts = {key: value for key, value in my_contacts.items() if value["Name"] != user_input}
There's two steps here:
Finding the key/value pair(s) that match
Deleting the keys you found
If you're only deleting a single item (even with multiple matches), always, these can be combined:
def del_contact():
user_input = input("Please enter the name of the contact you want to delete: ")
for k, v in my_contacts.items(): # Need both key and value, we test key, delete by value
if v["Name"] == user_input:
del my_contacts[k]
break # Deleted one item, stop now (we'd RuntimeError if iteration continued)
else:
# Optionally raise exception or print error indicating name wasn't found
If you might delete multiple entries, and must operate in place, you'd split the steps (because it's illegal to continue iterating a dict while mutating the set of keys):
def del_contact():
user_input = input("Please enter the name of the contact you want to delete: ")
to_delete = [k for k, v in my_contacts.items() if v["Name"] == user_input]
if not to_delete:
# Optionally raise exception or print error indicating name wasn't found
for k in to_delete:
del my_contacts[k]
Or if you're okay with replacing the original dict, rather than mutating it in place, you can one-line the multi-deletion case as:
def del_contact():
global my_contacts # Assignment requires explicitly declared use of global
user_input = input("Please enter the name of the contact you want to delete: ")
my_contacts = {k: v for k, v in my_contacts.items() if v["Name"] != user_input} # Flip test, build new dict
# Detecting no matches is more annoying here (it's basically comparing
# length before and after), so I'm omitting it
I think thats what you need, hope that helps:
Code:
my_contacts = {1: {"Name": "Tom Jones",
"Number": "911",
"Birthday": "22.10.1995",
"Address": "212 street"},
2: {"Name": "Bob Marley",
"Number": "0800838383",
"Birthday": "22.10.1991",
"Address": "31 street"}
}
def add_contact():
user_input = int(input("please enter how many contacts you wanna add: "))
index = len(my_contacts) + 1
for _ in range(user_input):
details = {}
name = input("Enter the name: ")
number = input("Enter the number: ")
birthday = input("Enter the birthday")
address = input("Enter the address")
details["Name"] = name
details["Number"] = number
details["Birthday"] = birthday
details["Address"] = address
my_contacts[index] = details
index += 1
print(my_contacts)
add_contact()
print(my_contacts)
def del_contact():
user_input = input("Please enter the name of the contact you want to delete: ")
values = [key for key in my_contacts.keys() if user_input in my_contacts[key].values()]
for value in values:
my_contacts.pop(value)
del_contact()
print(my_contacts)
Input:
{1: {'Name': 'Tom Jones', 'Number': '911', 'Birthday': '22.10.1995', 'Address': '212 street'}, 2: {'Name': 'Bob Marley', 'Number': '0800838383', 'Birthday': '22.10.1991', 'Address': '31 street'}, 3: {'Name': 'myname', 'Number': '1233455', 'Birthday': '12-12-22', 'Address': 'blabla street'}}
Please enter the name of the contact you want to delete: Bob Marley
Output:
{1: {'Name': 'Tom Jones', 'Number': '911', 'Birthday': '22.10.1995', 'Address': '212 street'}, 3: {'Name': 'myname', 'Number': '1233455', 'Birthday': '12-12-22', 'Address': 'blabla street'}}
Being that the index are used as keys for the dictionary, the range function can be used as follows:
def del_contact():
user_input = input("Please enter the name of the contact you want to delete: ")
for i in range(1,len(my_contacts)+1):
if my_contacts[i]['Name'] == user_input:
del my_contacts[i]
break
If there can be multiple contacts with the same name that need to be deleted, remove the break statement.
But as mentioned in the comments, there is no need to use an index as a key for the dictionaries. A potential bug you'll encounter with that, is if the first entry is deleted whose name is Tom Jones the dict will have a length of 1 with only one key - 2. Then when you try to add more contacts, when you check the length of the dictionary index = len(my_contacts) + 1, since length is 1, index will be 2. Hence my_contacts[index] = details will update the contact with a key of 2 or "Name": "Bob Marley" instead of adding a new contact.
I can build the json result with this code.
MY code:
import csv
import json
from os import sep
with open('tran_test.csv') as file:
dict_input = csv.reader(file, delimiter='|')
next(dict_input, None)
output = []
for line in dict_input:
promotion_code = line[0]
promotion_name = line[1]
coupon_code = line[2]
coupon_name = line[3]
coupon = {}
if coupon_code == '' and promotion_code !='':
pro_code = {}
pro_code['coupon_code'] = promotion_code
pro_code['type'] = 'promo_code'
pro_code['description'] = promotion_name
pro_code['redeem'] = 'false'
coupon = [pro_code]
elif coupon_code != '' and promotion_code == '':
cou_code = {}
cou_code['coupon_code'] = coupon_code
cou_code['type'] = 'coupon_code'
cou_code['description'] = coupon_name
cou_code['redeem'] = 'false'
coupon = [cou_code]
elif (coupon_code != '' and promotion_code !=''):
both_promo = {}
both_coup = {}
both_promo['coupon_code'] = promotion_code
both_promo['type'] = 'promo_code'
both_promo['description'] = promotion_name
both_promo['redeem'] = 'false'
both_coup['coupon_code'] = coupon_code
both_coup['type'] = 'coupon_code'
both_coup['description'] = coupon_name
both_coup['redeem'] = 'false'
coupon = (both_promo , both_coup)
else:
None
output_obj = {}
output_obj['coupons'] = coupon
output.append(output_obj)
print(json.dumps(output))
And the result like this:
[{"coupons": [{"coupon_code": "T000003155 ~ E000005182", "redeem": "false", "type": "promo_code", "description": "Net Spend - $800 Enjoy $80 off ~ Net Spend $2000 Enjoy 15%* off"}, {"coupon_code": "0494040", "redeem": "false", "type": "coupon_code", "description": "new join $300"}]}]
The sample csv:
Promotion Code|Promotion Name|Coupon Code|Coupon Name
T000003155 ~ E000005182|Net Spend - $800 Enjoy $80 off ~ Net Spend $2000 Enjoy 15%* off |0494040|new join $300
I want to split the promotion code and promotion name. This depends on '~'. And create two records separately.
Desired result:
[{"coupons": [{"coupon_code": "T000003155", "redeem": "false", "type": "promo_code", "description": "Net Spend - $800 Enjoy $80 off"},{"coupon_code": "E000005182", "redeem": "false", "type": "promo_code", "description": "Net Spend $2000 Enjoy 15%* off"}, {"coupon_code": "0494040", "redeem": "false", "type": "coupon_code", "description": "new join $300"}]}]
How can I do this?
In order to disentangle the entries in this CSV, you have to find the characters that delimit the values and split the string accordingly. As the format is quite strange with two entries separated by " ~ " in some cases, you'd have to do it manually:
line = "T000003155 ~ E000005182|Net Spend - $800 Enjoy $80 off ~ Net Spend $2000 Enjoy 15%* off |0494040|new join $300"
chunks = line.split("|")
coupon_codes = chunks[0].split(" ~ ")+[chunks[2]]
contents = chunks[1].split(" ~ ")+[chunks[3]]
c = [{"coupons": [{"coupon_code":coupon_codes[0],
"redeem":"false",
"type":"promo_code",
"description":contents[0]},
{"coupon_code":coupon_codes[1],
"redeem":"false",
"type":"promo_code",
"description":contents[1]},
{"coupon_code":coupon_codes[2],
"redeem":"false",
"type":"coupon_code",
"description":contents[2]}]}]
print(c)
Which returns your desired output:
[{'coupons': [{'coupon_code': 'T000003155', 'redeem': 'false', 'type': 'promo_code', 'description': 'Net Spend - $800 Enjoy $80 off'}, {'coupon_code': 'E000005182', 'redeem': 'false', 'type': 'promo_code', 'description': 'Net Spend $2000 Enjoy 15%* off '}, {'coupon_code': '0494040', 'redeem': 'false', 'type': 'coupon_code', 'description': 'new join $300'}]}]
This only works, however, if the CSV is well-formed and each line has the same delimiters in the same cells.
I have this JSON data:
{
"id": 1,
"name_company": "Acier Michel",
"inspecteur1": "Hou, L",
"inspecteur2": "Caana, C",
"inspecteur3": "Luc, C",
"type": "Water",
"location": "Laval"
},
{
"id": 2,
"name_company": "Aciers ABC Inc.",
"inspecteur1": "Vali, M",
"inspecteur2": "Alemane, K",
"inspecteur3": "laszik, M",
"type": "NA",
"location": "St-Joseph de Sorel"
}
I want to be able to input "name_company", and get as an output the "inspecteur1" name.
Tried this below but no success..
import json
database = "convertcsv.json"
data = json.loads(open(database).read())
fabricant = input("type company name : ")
for item in database["name_company"]:
if item["name_company"] == fabricant:
print("good")
else:
print("no existant")
You're almost there. A few issues for you to resolve:
Your Json-formatted data is not valid. You seem to be operating on a list, so please ensure that you include square brackets around your data like so:
[
{
"id": 1,
"name_company": "Acier Michel",
"inspecteur1": "Hou, L",
"inspecteur2": "Caana, C",
"inspecteur3": "Luc, C",
"type": "Water",
"location": "Laval"
},
{
"id": 2,
"name_company": "Aciers ABC Inc.",
"inspecteur1": "Vali, M",
"inspecteur2": "Alemane, K",
"inspecteur3": "laszik, M",
"type": "NA",
"location": "St-Joseph de Sorel"
}
]
You're using the filename string variable (database = "convertcsv.json") in your loop declaration, when you instead want to use the Json array from the data you've just read in to your program in order to iterate over each Json object (or, list of dicts in Python-speak). That would be the 'data' variable as you've defined it.
You also want to access the properties of each object (aka. dict) within the loop and not on the iterable itself since that is what the 'item' variable will represent in the loop as you've defined it. So, remove the ["name_company"] bit from the for loop declaration, but leave it in your if condition below.
Provided you've fixed your data, the code below should run:
import json
database = "convertcsv.json"
data = json.loads(open(database).read())
fabricant = input("type company name : ")
for item in data:
if item["name_company"] == fabricant:
print("good")
else:
print("no existant")
To print the inspecteur name, just add the line print(item["inspecteur1"])
import json
database = "convertcsv.json"
data = json.loads(open(database).read())
fabricant = input("type company name : ")
for item in data:
if item["name_company"] == fabricant:
print("good")
print(item["inspecteur1"])
else:
print("no existant")
If you are loading the data using json.loads() then append the json to a list.
data = []
data.append(json.loads(open(database).read())))
Now you can loop over the list and get the key - value pairs like similar to a dictionary
fabricant = input("type company name: ")
for item in data:
if item['name_company'] == str(fabricant):
print(item['inspecteur1'])
else:
print("Not Found")
Below code might help -
Main:
database = "convertcsv.json"
data = json.loads(open(database).read())
user_input_company = 'Aciers ABC Inc.'
records = collection_of_records(data)
for record in records:
if record.name_company == user_input_company :
print(record.inspecteur1)
def collection_of_records(set_of_records):
'''Return a tuple of bundles defined in records
'''
from collections import namedtuple
CompanyRecord = namedtuple('record', 'id name_company inspecteur1 inspecteur2 type location')
records = tuple(
CompanyRecord(company_values['id'], company_values['name_company'], company_values['inspecteur1'], company_values['inspecteur2'],
company_values['type'], company_values['location'])
for company_values in set_of_records['record']
)
return records
convertcsv.json
{
"record": [
{
"id": 1,
"name_company": "Acier Michel",
"inspecteur1": "Hou, L",
"inspecteur2": "Caana, C",
"inspecteur3": "Luc, C",
"type": "Water",
"location": "Laval"
},
{
"id": 2,
"name_company": "Aciers ABC Inc.",
"inspecteur1": "Vali, M",
"inspecteur2": "Alemane, K",
"inspecteur3": "laszik, M",
"type": "NA",
"location": "St-Joseph de Sorel"
}
]
}
References
https://docs.python.org/3/library/collections.html
Below is a code suggested by one of the stackoverflow user, I tried running it, but it is returning error. The error could be small , but as I am very new to Python I am unable to correct it. Kindly help.
Here is a snippet of json file
[{
"address": " Karaikudi, Sivagangai-623004",
"college": "College (Engineering)",
"courses": [],
"email": " contact#accet.net, dptacce#md5.vsnl.net.in",
"fax": "04565-224528",
"name": "A. C. College Of Engineering & Technology",
"phone": "04565-224535, 224528",
"recognition": " Madurai Kamaraj University",
"website": "www.accet.net"
},{
"address": " Medabakkam Road, Sholinganallur, Chennai-600119",
"college": "College (Pharmacy)",
"courses": [
{
"brief_details": " Age: 17 years on Dec. 31.",
"college_name": "A. J. College of Pharmacy",
"course_branch": "B.Pharmacy",
"course_duration": " 4-year",
"course_nature": " Full-Time",
"course_title": "",
"course_type": " Medical",
"no_of_seats": " 40",
"qualifications": " As above Those who have passed Diploma in Pharmacy with 50% (recognized by PCI) are directly admitted in the IInd year of B.Pharmacy.",
"selection_process": ""
}
],
"email": " contact#accet.net, dptacce#md5.vsnl.net.in",
"fax": "044-24502573",
"name": "A. J. College Of Pharmacy",
"phone": "044-24502572",
"recognition": " Dr. Mgr University And Approved By Aicte",
"website": "www.msajcpharm.in"
}]
Below is the code:
import json
import csv
def write_csv(jsonfile, outfile):
with open(jsonfile) as f:
data = json.loads(f.read())
college_dict = data[0]
college_keys = list(college_dict.keys())
college_keys.remove('courses')
college_keys.remove('college')
courses_dict = data[0]['courses'][0]
courses_keys = list(courses_dict.keys())
courses_keys.remove('brief_details')
with open(outfile, 'w', newline='') as f:
csv_writer = csv.writer(f)
headers = college_keys + courses_keys
csv_writer.writerow(headers)
row = (
[
college_dict[key] if college_dict[key] else 'NA'
for key in college_keys
]
+
[
courses_dict[key] if courses_dict[key] else 'NA'
for key in courses_keys
]
)
csv_writer.writerow(row)
jsonfile = '/home/maitreyee/Downloads/SchoolCollege.com/collegesdb/collegesdb1.json'
outfile = '/home/maitreyee/Downloads/SchoolCollege.com/collegesdb/collegesout.csv'
write_csv(jsonfile, outfile)
and following is the error I am encountering:
maitreyee#Maitreyee:~/Downloads/SchoolCollege.com$ python json2csv4.py
Traceback (most recent call last):
File "json2csv4.py", line 41, in <module>
write_csv(jsonfile, outfile)
File "json2csv4.py", line 15, in write_csv
courses_dict = data[0]['courses'][0]
IndexError: list index out of range
The list in your json is empty:
...
"courses": [],
...
So it's obvious you are getting an IndexError: list index out of range exception. You can fix this with:
courses_dict = data[0]['courses'][0] if data[0]['courses'] else None