Python Create a List file and write query - python

so sorry for my question if it seems so easy but I am newbie user of python and I can not find a way to solve it.
I have a "dish.py" file which includes some sub-lists
Fruits={"Ap":Apple
"Br":Black Mulberry
"Ch":Black Cherry
}
Meals={"BN":Bean
"MT":Meat
"VG":Vegetable
}
Legumes={"LN":Green Lentil
"P": Pea
"PN":Runner Peanut
}
I want to impelement the dish.py file in a code that at the end, I want to create a query inside of the file
with open("/home/user/Py_tut/Cond/dish.py", 'r') as dish:
content = dish.read()
print dish.closed
dm=dict([dish])
nl=[x for x in dm if x[0]=='P']
for x in dm:
x=str(raw_input("Enter word:"))
if x in dm:
print dm[x]
elif x[0]==("P"):
nl.append(x)
print .join( nl)
It may be look so messy but
dm=dict([dish]) I want to create a dictionary for query
nl=[x for x in dm if x[0]=='P'] I want to write words begin with "P" letter
Here is my questions:
1. Q: I suppose there is a problem with my dish.py file. How can I reorganize it?
2. Q: How can I apply a query to the file and extract the words begin with "P"
Thank you so much in advance

dict() can't load strings:
>>> dict("{'a': 1, 'b': 2}")
Traceback (most recent call last):
File "<pyshell#0>", line 1, in <module>
dict("{'a': 1, 'b': 2}")
ValueError: dictionary update sequence element 0 has length 1; 2 is required
As a sequence it would be ("{", "'", "a", "'", ":",...
Instead I would use the json module, change the dish.py format (changing extension to .json and using JSON syntax) and change the code.
dish.json
{
"Fruits": {
"Ap": "Apple",
"Br": "Black Mulberry",
"Ch": "Black Cherry"
},
"Meals": {
"BN": "Bean",
"MT": "Meat",
"VG": "Vegetable"
},
"Legumes": {
"GL": "Green Lentin",
"P": "Pea",
"PN": "Running Peanut"
}
}
__init__.py
import json
with open("/home/user/Py_tut/Cond/dish.py", 'r') as dish:
content = dish.read()
print(dish.closed)
dm = json.loads(content) # loads JSON
nl=[x for x in dm if x[0]=='P']
for x in dm:
x = str(raw_input("Enter word:"))
if x in dm:
print dm[x]
elif x[0] == ("P"):
nl.append(x)
print "".join(nl)
Q: How can I apply a query to the file and extract the words begin with "P" Thank you so much in advance
Assuming that you want to get every string separated by either space or newline and return them into a list, i'd do this:
import re #Importing RegExp module
def wordsBeginP():
with open("words.txt") as wordsfile: # Querying a file
words = wordsfile.open
parsed = re.sub(r"\n", " ", words) # Replace \n to " "
return [for i in parsed.split(" ") if i[0] == "P"] # Return list of words

So I think you have more than these two issues/questions.
First, if you want to include 'hardcoded' lists, dicts and such, you probably want to include dish with dish.py being in your working directory.
That is, if your data structures in the python file are actually in the correct form:
Fruits={"Ap":'Apple',
"Br":'Black Mulberry',
"Ch":'Black Cherry'
}
Meals={"BN":'Bean',
"MT":'Meat',
"VG":'Vegetable'
}
Legumes={"LN":'Green Lentil',
"P":'Pea',
"PN":'Runner Peanut'
}
Finally, you can search in all the datastructures that were named and included in the file, under the created namespace of the include (which is dish).
for f in [dish.Fruits,dish.Meals,dish.Legumes]:
for k,v in f.items():
if k.startswith('P'):
print k,v
Also interesting for you might be pickling (though there are some caveats).

Related

Dynamically update JSON files based on config

Suppose I have a config file like this where I list a bunch of values. I am running a function in which I am checking that a set of strings will always begin with one of these defined values.
start_values = [
"cats",
"dogs",
"birds",
"horses"
]
And I also have a json file on which I want run unit tests on to make sure that my function is running properly, like this.
{
"sentence_tests": [
"horses eat grass.",
"birds fly high.",
"cats like to nap.",
"dogs are cool."
]
}
However, the problem I am facing is that if I want to change one of my start_values to be something else, I want to also update my json file for that specific value. For example, if I change "dogs" to "cows", I want that to update automatically in my json file instead of having to do that manually.
So this is how I would want it to be after I change the start_values:
Modified start_values:
start_values = [
"cats",
"cows",
"birds",
"horses"
]
Modified json file:
{
"sentence_tests": [
"horses eat grass.",
"birds fly high.",
"cats like to nap.",
"cows are cool."
]
}
Is there a way to do this in python?
import json
with open(filename, "rt") as f:
sentences = json.loads(f.read())
for i, value in enumerate(starts_values):
words = sentences["sentences_tests"][i].split()
if words[0] != value:
words[0] = value
words = " ".join(words)
sentences["sentences_tests"][i] = words
with open(filename, "wt") as f:
f.write(json.dumps(sentences, indent=4))
Yes,
you can easily load a JSON object using the json python library. It will transform into a python dictionary. All you have to do after this is rewrite the file.

Use IF statement to search json file

I need to search this json file and print only the peole with a Y status:
[[{"Name": "person1", "Status": "Y"}], [{"Name": "person2", "Status": "N"}], [{"Name": "person3", "Status": "Y"}]]
I can open the file and display the data ok, but need to search within it.
Could someone help complete this if statement for me?
It needs to look at the keyvalue? Status and print only the two people with Y
for name in OpenFile:
**# if Status == Y what do I do here? :**
print ("Name : " +name[i]['Name'])
print ("Status : " +name[i]['Status'])
You need to iterate over the lists, extract the dict from it and check the key 'Status':
for element in OpenFile:
ele = element[0] # grab the dict
if ele.get('Status') == 'Y':
print 'Name: {}'.format(ele.get('Name')
print 'Status: {}'.format(ele.get('Status')
Your OpenFile object is a list of lists, which inside it's dict structure.
So, you want to address the first object in your list (that's the dict) and then perform your check. You do that with ele.get()
It looks like you are referencing [i], while name is your iterator. Change it to something like this:
for name in OpenFile:
**# if Status == Y what do I do here? :**
print ("Name : " +name['Name'])
print ("Status : " +name['Status'])
at the same time, your json formatted data looks like it's formatted like this:
List[list[dict],list[dict],list[dict],] so it'd only make sense to navigate to the Name value like this:
print(OpenFile[0][0]['Name'])
Try if this returns person1 and then base your next if-statement on this.
Additional debugging tool:
use type() to identify how your json is formatted:
type(OpenFile)
type(OpenFile[0])
type(OpenFile[0][0])
etc., use the error to figure out how your json is formatted

Parsing a file that looks like JSON to a JSON

I'm trying to figure out was is the best way to go about this problem:
I'm reading text lines from a certain buffer that eventually creates a certain log that looks something like this:
Some_Information: here there's some information about date and hour
Additional information: log summary #1234:
details {
name: "John Doe"
address: "myAdress"
phone: 01234567
}
information {
age: 30
height: 1.70
weight: 70
}
I would like to get all the fields in this log to a dictionary which I can later turn into a json file, the different sections in the log are not important so for example if myDictionary is a dictionary variable in python I would like to have:
> myDictionary['age']
will show me 30.
and the same for all other fields.
Speed is very important here that's why I would like to just go through every line once and get it in a dictionary
My way about doing this would be to for each line that contains ":" colon I would split the string and get the key and the value in the dictionary.
is there a better way to do it?
Is there any python module that would be sufficient?
If more information is needed please let me know.
Edit:
So I've tried something that to me look to work best so far,
I am currently reading from a file to simulate the reading of the buffer
My code:
import json
import shlex
newDict = dict()
with open('log.txt') as f:
for line in f:
try:
line = line.replace(" ", "")
stringSplit = line.split(':')
key = stringSplit[0]
value = stringSplit[1]
value = shlex.split(value)
newDict[key] = value[0]
except:
continue
with open('result.json', 'w') as fp:
json.dump(newDict, fp)
Resulting in the following .json:
{"name": "JohnDoe", "weight": "70", "Additionalinformation": "logsummary#1234",
"height": "1.70", "phone": "01234567", "address": "myAdress", "age": "30"}
You haven't described exactly what the desired output should be from the sample input, so it's not completely clear what you want done. So I guessed and the following only extracts data values from lines following one that contains a '{' until one with a '}' in it is encountered, while ignoring others.
It uses the re module to isolate the two parts of each dictionary item definition found on the line, and then uses the ast module to convert the value portion of that into a valid Python literal (i.e. string, number, tuple, list, dict, bool, and None).
import ast
import json
import re
pat = re.compile(r"""(?P<key>\w+)\s*:\s*(?P<value>.+)$""")
data_dict = {}
with open('log.txt', 'rU') as f:
braces = 0
for line in (line.strip() for line in f):
if braces > 0:
match = pat.search(line)
if match and len(match.groups()) == 2:
key = match.group('key')
value = ast.literal_eval(match.group('value'))
data_dict[key] = value
elif '{' in line:
braces += 1
elif '}' in line:
braces -= 1
else:
pass # ignore line
print(json.dumps(data_dict, indent=4))
Output from your example input:
{
"name": "John Doe",
"weight": 70,
"age": 30,
"height": 1.7,
"phone": 342391,
"address": "myAdress"
}

Python Dictionary from External file

I am trying to make a dictionary in Python, but I do not know how to do two things.
When I search for keywords in a dictionary, instead of just looking for direct matches, I would like it to find every word that has the keywords in it. E.G. Search: Cat - Results: Cat, Allocate.
I would like the dictionary to load an external file, so new terms that I add to the dictionary can be saved when I load it up afterwards.
You can use following methods:
For 1.
print ("Welcome back to the dictionary");
dict = {"CAT": "A small four legged animal that likes to eat mice",
"DOG": "A small four legged animal that likes to chase cats",
"ALLOCATE": "to give something to someone as ​their ​share of a ​total ​amount, to use in a ​particular way",
}
def Dictionary():
x = input("\n\nEnter a word: \n>>>");
x = x.upper();
found = False
for y in dict:
if x in y:
found = True
print (x,":",dict[x])
Dictionary()
break
if not found:
y = input ("Unable to find word. Enter a new definition of your word: \n>>>");
dict.update({x:y})
Dictionary()
Dictionary()
For 2: You can load data directly from a json file
import json
dict = {}
with open("test.json", "r") as config_file:
dict = json.load(config_file)
where test.json being your file for e.g.
test.json
{"CAT": "A small four legged animal that likes to eat mice",
"DOG": "A small four legged animal that likes to chase cats",
"ALLOCATE": "to give something to someone as ​their ​share of a ​total ​amount, to use in a ​particular way",
}
This should let you match cat in allocate.
for key in dict.keys():
if x in key:
do some stuff

How can I read a text file and replace numbers?

If I have many of these in a text file;
<Vertex> 0 {
-0.597976 -6.85293 8.10038
<UV> { 0.898721 0.149503 }
<RGBA> { 0.92549 0.92549 0.92549 1 }
}
...
<Vertex> 1507 {
12 -5.3146 -0.000708352
<UV> { 5.7487 0.180395 }
<RGBA> { 0.815686 0.815686 0.815686 1 }
}
How can I read through the text file and add 25 to the first number in the second row? (-0.597976 in Vertex 0)
I have tried splitting the second line's text at each space with .split(' '), then using float() on the third element, and adding 25, but I don't know how to implicitly select the line in the text file.
Try to ignore the lines that start with "<", for example:
L=["<Vertex> 0 {",
"-0.597976 -6.85293 8.10038",
"<UV> { 0.898721 0.149503 }",
"<RGBA> { 0.92549 0.92549 0.92549 1 }"
]
for l in L:
if not l.startswith("<"):
print l.split(' ')[0]
Or if you read your data from a file:
f = open("test.txt", "r")
for line in f:
line = line.strip().split(' ')
try:
print float(line[0]) + 25
except:
pass
f.close()
The hard way is to use Python Lex/Yacc tools.
The hardest (did you expect "easy"?) way is to make a custom function recognizing tokens (tokens would be <Vertex>, numbers, bracers, <UV> and <RGBA>; token separators would be spaces).
I'm sorry but what you're asking is a mini language if you cannot guarantee the entries respect the CR and LFs.
Another ugly (and even harder!) way is, since you don't use recursion in that mini language, using regex. But the regex solution would be long and ugly in the same way and amount (trust me: really long one).
Try using this library: Python Lex/Yacc since what you need is to parse a language, and even when regex is possible to use here, you'll end with an ugly and unmaintainable one. YOU HAVE TO LEARN THE TIPS of language parsing to use this. Have a look Here
If the verticies will always be on the line after , you can look for that as a marker, then read the next line. If you read the second line, .strip() leading and trailing whitespace, then .split() by the space character, you will have a list of your three verticies, like so (assuming you have read the line into a string varaible line:
>>> line = line.strip()
>>> verticies = line.split(' ')
>>> verticies
['-0.597976', '-6.85293', '8.10038']
What now? Call float() on the first item in your list, then add 25 to the result.
The real challenge here is finding the <Vertex> marker and reading the subsequent line. This looks like a homework assignment, so I'll let you puzzle that out a bit first!
If your file is well-formatted, then you should be able to parse through the file pretty easily. Assuming <Vertex> is always on a line proceeding a line with just the three numbers, you could do this:
newFile = []
while file:
line = file.readline()
newFile.append(line)
if '<Vertex>' in line:
line = file.readline()
entries = line.strip().split()
entries[0] = str(25+float(entries[0]))
line = ' ' + ' '.join(entries)
newFile.append(line)
with open(newFileName, 'w') as fileToWrite:
fileToWrite.writelines(newFile)
This syntax looks like a Panda3d .egg file.
I suggest you use Panda's file load, modify, and save functions to work on the file safely; see https://www.panda3d.org/manual/index.php/Modifying_existing_geometry_data
Something like:
INPUT = "path/to/myfile.egg"
def processGeomNode(node):
# something using modifyVertexData()
def main():
model = loader.loadModel(INPUT)
for nodePath in model.findAllMatches('**/+GeomNode').asList():
processGeomNode(nodePath.node())
if __name__=="__main__":
main()
It is a Panda3D .egg file. The easiest and most reliable way to modify data in it is by using Panda3D's EggData API to parse the .egg file, modify the desired value through these structures, and write it out again, without loss of data.

Categories