How do I convert a python string to a dictionary? [duplicate] - python

This question already has answers here:
How to dump a dict to a JSON file?
(7 answers)
Closed 11 hours ago.
How do I take a certain variable (string) and add it to a brand new dictionary to be parsed into another file called cars.json? The program asks the user a few questions about their car and then each variable should be parsed into a dictionary. The item name would be something preset, such as a model, and the value should be variable.
Here is what I tried.
cars.py
class CarCreator:
def __init__(self, make, model, year, color):
self.make = make
self.model = model
self.year = year
self.color = color
main.py
from cars import CarCreator
carVarAtt = CarCreator(None, None, None, None)
with open("./cars.json", "a") as f:
carVarMake = input("What is the make of your car? (Ford, Honda, Etc...)\n")
carVarModel = input("What is the model of your car? (Focus, Civic, Etc...)\n")
carVarYear = input("What is the year of your car? (2018, 2019, Etc...)\n")
carVarColor = input("What is the color of your car? (Red, Blue, Etc...)\n")
carVarAtt.make = carVarMake
carVarAtt.model = carVarModel
carVarAtt.year = carVarYear
carVarAtt.color = carVarColor
carVarName = f'"{carVarMake} {carVarModel}"'
f.write("{\n")
f.write(f" {carVarName}: ")
f.write("{\n")
f.write(f' "Make": "{carVarMake}",\n')
f.write(f' "Model": "{carVarModel}",\n')
f.write(f' "Year": {carVarYear},\n')
f.write(f' "Color": "{carVarColor}"\n')
if f is None:
f.write(" },\n")
elif f is not None:
f.write(" }\n")
f.write("}")
Instead of writing all those f.write()s, I need to take carVarMake, carVarModel, etc., and assign them to items in a dictionary. Is there a library or built-in Python function already made for this or do I need to do this manually?

Using the information you got from the user input, you can create a Python dictionary. These dictionaries can be stored in a JSON file using the json module in Python.
import json
# Your code for getting user input comes here
cars = {}
cars[carVarName] = {
"Make": carVarMake,
"Model": carVarModel,
"Year": carVarYear,
"Color": carVarColor
}
with open("./cars.json", "a") as file:
json.dump(cars, file)
Note that here I've moved the file writing outside of where your input collection takes place. You're welcome to ignore that change and maintain the structure you had before. As long as you save your information to a Python dictionary, the json module makes it very easy to save your dictionary to a JSON file format. You don't need to install this module as it is built in.

You just have to change your code slightly:
import json
from cars import CarCreator
carVarAtt = CarCreator(None, None, None, None)
carVarMake = input("What is the make of your car? (Ford, Honda, Etc...)\n")
carVarModel = input("What is the model of your car? (Focus, Civic, Etc...)\n")
carVarYear = input("What is the year of your car? (2018, 2019, Etc...)\n")
carVarColor = input("What is the color of your car? (Red, Blue, Etc...)\n")
carVarAtt.make = carVarMake
carVarAtt.model = carVarModel
carVarAtt.year = carVarYear
carVarAtt.color = carVarColor
new_data = {
f"{carVarMake} {carVarModel}": {
"Make": f"{carVarMake}",
"Model": f"{carVarModel}",
"Year": f"{carVarYear}",
"Color": f"{carVarColor}",
}
}
with open("./cars.json", "r") as data_file:
data = json.load(data_file)
data.update(new_data)
with open("./cars.json", "w") as data_file:
json.dump(data, data_file, indent=4)
Note that I prefer to open the file in the reading mode, save the content to a variable, then update the variable to add the new content, and finally open the file in writing mode, to "dump" everything. that may cause an error if the file doesn't exist yet. In that case, you can use this:
try:
with open("./cars.json", "r") as data_file:
data = json.load(data_file)
except FileNotFoundError:
with open("./cars.json", "w") as data_file:
json.dump(new_data, data_file, indent=4)
else:
data.update(new_data)
with open("./cars.json", "w") as data_file:
json.dump(data, data_file, indent=4)
If that is too much, there is nothing wrong with using appending as you did.
with open("./cars.json", "a") as data_file:
Now, if you have to do this for every new car Object you create, I would recommend creating a method inside of the class CarCreator that asks the user for the input, and another method to generate the dictionary and add it to the JSON file. Then you would call these methods in your main.py as needed.
Also, if you want to follow python code conventions, you should reserve the camel case only for classes (myClass), and use the snake case for variables (my_variable).
Programming name conventions
Name conventions in python

Related

how can i add something to a dictionary in python which is present in another file from another python file

I am trying to get contacts in form of a python dictionary, this dictionary is present in the file named 'phone.py', and I want to add a contact to this dictionary from another function which is in another file named 'test.py'.
phone.py
phone_numbers={
'john': '+91123456789',
'berry': '+91987654321',
}
test.py
import phone.py
def add_contact():
name_contact = input("what is the name :")
phone_contact = input("contact number")
file = open("phone.py", "a", encoding='utf-8')
file.truncate()
file.write("'"+name_contact+"'" + ':'+"'+91"+phone_contact+"'"+",")
file.close()
add_contact()
what I am currently getting as result.
phone.py
phone_numbers={
'john': '+91123456789',
'berry': '+91987654321',
}'jerry': '+916543217890',
what I want it to be.
phone.py
phone_numbers={
'john': '+91123456789',
'berry': '+91987654321',
'jerry': '+916543217890',
}
Your file has textual content.
You can use the following method add lines to your file
def add_contact():
name_contact, phone_contact = read_param()
lines = None
with open('phone.py') as input_file:
lines = input_file.readlines()
lines[-1:] = "'{0}':'+91{1}',{2}".format(name_contact, phone_contact, '\r')
lines.append("}")
with open("phone.py", 'w') as output_file:
output_file.writelines(lines)
output_file.close()
def read_param():
name_contact = input("what is the name :")
phone_contact = input("contact number :")
return name_contact, phone_contact
But it is better to keep the data in json format or even simpler (not in the form of dict but one contact in each line)
for example
simple records like this
"john": "+91123456789"
"berry": "+91987654321"
.
.
.
and just append new line
def append_line():
with open('phone.py', 'a') as input_file:
name_contact, phone_contact = read_param()
input_file.writelines("'{0}':'+91{1}'".format(name_contact, phone_contact))
json
your file contents be like this
{
"john": "+91123456789",
"berry": "+91987654321"
}
and use the following code
def add_contact_json():
with open('phone.py') as json_file:
data = json.load(json_file)
name_contact, phone_contact = read_param()
data[name_contact] = "'+91{0}".format(phone_contact)
with open('phone.py', 'w') as json_file:
json.dump(data, json_file)

Have problem with input(using JSON) in file

How can I input information in json file with commas between values?
import json
class Calculation():
"""The Program class(ALL)"""
def __init__(self,money_earned = 0,money_spended = 0):
self.money_earned = money_earned
self.money_spended = money_spended
def m_s(self):
"""input daily spend to file"""
self.money_spended = str(input("How much money you spend today?"))
print(self.money_spended)
file = "data_txt_cat/spend.json"
with open(file,"a") as f_obj:
json.dump(self.money_spended,f_obj)
def m_e(self):
"""input daily earn to file"""
self.money_earned = input("How much money earned today? ")
print(self.money_earned)
file = "data_txt_cat/earn.json"
with open(file, "a") as f_obj:
json.dump(self.money_earned, f_obj)
spend = Calculation()
spend.m_s()
spend.m_e()
Currently this writes a file with "11""12" in it from that input, rather than JSON output
The problem is that you're writing a json object with just a single value, rather than really a json structure
Try putting your inputs into a dictionary or list and adding a newline
Additionally, if you're not making some sort of key-value mapping, consider if you're really using JSON at all
You may find it convenient to use a dictionary .update() method
import json
earned = {
"value": [] # this is the list being appended to
}
try:
with open("whatever.json", "r") as fh: # open for reading and writing
earned.update(json.load(fh))
except FileNotFoundError:
print("warning: no starting file")
with open("whatever.json", 'w') as fh: # NOTE clobbers - consider backup and swap
earned["value"].append(input("How much money earned today?: "))
json.dump(earned, fh) # rewrite file

Adding nested dictionaries into an already existing JSON file with dictionary

I've recently started to learn some python.
After finishing all the learnpython.org tutorials I'm trying something on my own (So you know my knowledge level).
I want to build a small script that lets you build a DnD character and save it in a file. The idea was to use JSON (Since this was included in the learnpython tutorials) and put in dictionaries along the lines of:
data = { playerName ; {"Character Name" : characterName, "Character Class" : characterClass...ect.}}
I was hoping that it is possible to add new dics into the JSON file inside that original data dic, So the dictionary is a list of playerName's that have the character dics under them.
Not only did I fail to get it exactly like this, I also fail at just adding following dictionaries without making the file unreadable. Here is my code, since it isn't very long:
import json
def dataCollection():
print("Please write your character name:")
characterName = input()
print("%s, a good name! \nNow tell me your race:" % characterName)
characterRace = input()
print("And what about the class?")
characterClass = input()
print("Ok so we have; \nName = %s \nRace = %s \nClass = %s \nPlease tell me the player name now:" % (characterName, characterRace, characterClass))
playerName = input()
print("Nice to meet you %s. \nI will now save your choices..." % playerName)
localData = { playerName :
{"Character Name" : characterName,
"Character Class" : characterClass,
"Character Race" : characterRace}}
with open("%s_data_file.json" % playerName, "a") as write_file:
json.dump(localData, write_file)
dataCollection()
with open("data_file.json", "r") as read_file:
data = json.load(read_file)
# different .json name here since I'm trying around with different files
print(data)
Edit: It might also be possible that JSON is not the "right" thing to use for my idea. If you have any alternative ideas for storing that information (Besides straight txt file), feel free to suggest them!
i made little modification, i try to read the file for init the data json, if it fail i init the data.
import json
def createPlayer():
print("Please write your character name : ")
characterName = input()
print("%s, a good name! \nNow tell me your race : " % characterName)
characterRace = input()
print("Nice to meet you %s. \nI will now save your choices..." % characterName)
try :
with open('data_file.json') as json_file:
data = json.load(json_file)
except :
data = {}
data['player'] = []
data['player'].append({
'name': characterName,
'race': characterRace,
})
with open("data_file.json", "w+") as write_file:
json.dump(data, write_file)
createPlayer()
with open("data_file.json", "r") as read_file:
data = json.load(read_file)
print(data)
I think that the way you think of a dictionnary might not be exactly what it is.
A dictionary is a data structure that can holds many key-value pairs.
Here the key to your dictionary would be the player's name and the value would be the dictionary that holds the character's name, class and race.
So a json file that holds a dictionary cannot be appended to because a json file can only hold 1 json object.
{ 'playerName': {...character\'s attributes...}}
If you were to open the file and append a json object (like you do at the end of dataCollection) then your file would be like this
{ 'playerName':
{...characters attributes...}
}
{ 'playerName2':
{...characters attributes...}
}
And when reading the file json will stop when the first json object it finds will end. So it won't load the 2nd dictionary.
If you want to add something to the dictionary inside your json file, you need to load the json file to access the dictionary and then add your new key-value pair and then dump this new dictionary. Which will result in the following json file:
{ 'playerName':
{...characters attributes...},
'playerName2':
{...characters attributes...}
}
I hope it's kinda clear.

CSV rewriter keeps creating new headers

My code is creating the same headers each time, I want it to create one and append the data to a CSV without creating a new header.
What it looks like in the CSV
What I want it to look like
import csv
with open("Details.csv","a+") as Details:
w=csv.writer(Details,delimiter=",")
headers1=["Name","Age","Year Group"]
line=Details.readlines()
if line!=["Name","Age","Year Group"]:
w.writerow(headers1)
print("Welcome User, to my Topics Quiz!\n-------------------------------
--------\nYou can choose from 3 different topics:\n • History\n •
Music\n • Computer Science\n---------------------------------------")
print("Before we start, we need to register an account.")
User=input("Enter your name:\n")
Age=input("Enter your age:\n")
Year=input("Enter your year group:\n")
details=[User,Age,Year]
w.writerow(details)
Details.close()
with open("UserPass.csv","a+") as Userpass:
w=csv.writer(Userpass,delimiter=",")
headers2=["Username","Password"]
if headers2 not in Userpass:
w.writerow(headers2)
NewUser=(User[:3]+Age)
print("Great! Your username is set to: {}".format(NewUser))
Pass=input("Enter a password for your account:\n")
userpass=[NewUser,Pass]
w.writerow(userpass)
Userpass.close()
Any help is greatly appreciated.
You are opening file in appending mode (https://docs.python.org/3/library/functions.html#open), so this line=Details.readlines() will always be empty line and your headers will be written every time (code will always get into if).
It is similar with other file. So I suggest you first check if file exist, and if not create it and add headers, and remove headers part from with:
import csv
import os.path
if not os.path.isfile("Details.csv"):
with open("Details.csv", "a+") as Details:
w = csv.writer(Details, delimiter=",")
headers1 = ["Name", "Age", "Year Group"]
w.writerow(headers1)
Details.close()
if not os.path.isfile("UserPass.csv"):
with open("UserPass.csv", "a+") as Userpass:
w = csv.writer(Userpass, delimiter=",")
headers2 = ["Username", "Password"]
w.writerow(headers2)
Userpass.close()
with open("Details.csv", "a+") as Details:
w = csv.writer(Details, delimiter=",")
print("Welcome User, to my Topics Quiz!\n-------------------------------"
"--------\nYou can choose from 3 different topics:\n • History\n • "
"Music\n • Computer Science\n---------------------------------------")
print("Before we start, we need to register an account.")
User = input("Enter your name:\n")
Age = input("Enter your age:\n")
Year = input("Enter your year group:\n")
details = [User, Age, Year]
w.writerow(details)
Details.close()
with open("UserPass.csv", "a+") as Userpass:
w = csv.writer(Userpass, delimiter=",")
NewUser = (User[:3] + Age)
print("Great! Your username is set to: {}".format(NewUser))
Pass = input("Enter a password for your account:\n")
userpass = [NewUser, Pass]
w.writerow(userpass)
Userpass.close()
There are different problems in your code:
1) Empty line between lines with data in csv file, it happens because of the nonbinary type of opening and can be fixed by adding that arg in open function:
w=csv.writer(Details,delimiter=",",lineterminator='\n')
2) In your case Details.readlines() method was returning [], because of the a+ type of opening, it's supposed to add lines in the end of file, so pointer is in the end already and we need to return it at the beginning by using that code:
line=Details.seek(0)
3) Also, we need only first line, so just use readline() method. And after all, your condition should look that way, because of the return type and the fact that there's \n in the end of every line:
if line!="Name,Age,Year Group\n":
And the full code of that part. Let me know if it works well for you:
w=csv.writer(Details,delimiter=",",lineterminator='\n')
headers1=["Name","Age","Year Group"]
line=Details.seek(0)
line=Details.readlines()[0]
print(line)
if line!="Name,Age,Year Group\n":
w.writerow(headers1)
I don't understand everything your code is trying to accomplish, but the following will add a row to the Details.csv without creating any new headers:
import csv
import os
csv_fileheader = "Name", "Age", "Year Group"
csv_filename = "Details.csv"
print("Welcome User, to my Topics Quiz!\n"
"---------------------------------------\n"
"You can choose from 3 different topics:\n"
" • History\n • Music\n • Computer Science\n"
"---------------------------------------")
print("Before we start, we need to register an account.")
user = input("Enter your name:\n")
age = input("Enter your age:\n")
year = input("Enter your year group:\n")
if not os.path.isfile(csv_filename): # Create file if it doesn't exist.
with open(csv_filename, "w", newline='') as csv_file:
csv.writer(csv_file).writerow(csv_fileheader) # Put header row in it.
with open(csv_filename, "a+", newline='') as details2:
writer = csv.writer(details2, delimiter=",")
writer.writerow((user, age, year))
You should consider following the PEP 8 - Style Guide for Python Code recommendations as it will make your code easier for both you and others to read.

How to create a dictionary based on a text file?

I'm writing a simple python game where I have a text file in the following format where the key on the left is the player's name and the value on the right is the player's score:
Name 134
Next Name 304958
Etc....
Question: How can I read in a text file in that format and create a dictionary from the values on each line, and once the player exits the program, the file is updated with the latest dictionary entries?
I already have some code commented out that I've started but have been unable to implement and get working. Any help is appreciated.
Here is my code:
# with open('scores.txt', 'r') as file:
# scores = {}
# for line in file:
# line = line.split()
# do stuff
# with open("scores.txt", "w") as f: # Save dictionary in file
# do stuff
To load that format:
with open('scores.txt', 'r') as infile:
scores = {}
for line in infile:
name, _, score = line.rpartition(' ')
scores[name] = int(score)
To save that format:
with open('scores.txt', 'w') as outfile:
for name, score in scores:
outfile.write('%s %s\n' % (name, score))
penne12 is correct, though. You could save a few lines of code by using the json library to store JSON instead of this particular text format.
Here's an example that uses JSON as suggested in the comments:
import json
def load_game_data():
data = None
with open('savegame.json', 'r') as savefile:
data = json.load(savefile)
return data
def save_game_data(data):
with open('savegame.json', 'w') as savefile:
json.dump(data, savefile)
# Store the game data as a dictionary:
data = { 'player_name' : 'wolfram', 'hp' : 8 }
save_game_data(data)
data = load_game_data()
print(data)
# prints {'player_name': 'wolfram', 'hp': 8}
print(data['player_name'])
print(data['hp'])
The data gets saved to disk as JSON and is loaded from disk as a dictionary, which is easy to use. You'll need to add code error handling, of course, this is just intended as a simple illustration.

Categories