with open() throwing errors on a json file - python

So I'm super new to coding and I wanted to design a text based RPG as sort of a fun way to learn some stuff and I picked out the language Python because it was named after Monty Python. How perfect right? Well, that is what I thought until trying to get rooms to load.
I am using json files to store my room names, descriptions, and exits then trying to call them in python via a method I saw on YouTube, here is the code:
def getRoom(id):
ret = None
with open(str(id)+".json", "r") as f:
jsontext = f.read()
d = json.loads(jsontext)
d['id'] = id
ret = Room(**d)
This threw an IOError directory or file not found, so I added a try statement like so:
def getRoom(id):
ret = None
try:
with open(str(id)+".json", "r") as f:
jsontext = f.read()
d = json.loads(jsontext)
d['id'] = id
ret = Room(**d)
except IOError:
print("An error occured")
However now I am getting an "AttributeError: 'NoneType' object has no attribute 'name'" off my look command which I have coded like so:
def look(player, args):
print(player.loc.name)
print("")
print (player.loc.description)
In case this matters here is my json file that I have named 1.json:
{
"name": "A Small Bedroom",
"description": "The old bed room has probably seen many people over the years as the inn sits along a major trade route. The floor boards show wear and creak as you walk over them.",
"neighbors": {"w":2}
}
EDIT:
Full traceback:
Traceback (most recent call last):
File "game.py", line 79, in <module>
main(player) File "game.py", line 68, in main
player.loc = getRoom(1)
File "/home/illyduss/Urth/Locations/room.py", line 6, in getRoom
with open(str(id)+".json", "r") as f:
IOError: [Errno 2] No such file or directory: '1.json'

The error clearly says that the file is not to be found. Try the following.
1. make sure that the filename 1.json is available from where you are calling the python interpretor.
for example: if you are calling $ python game/game.py, then the file should be in the present working directory, not in game dir
Try using absolute paths if you can
import os
base_dir = /path/to/json/dir
filename = str(id)+".json"
abs_file = os.path.join(base_dir, filename)
with open(abs_file, "r"):
#do stuff
If you need the json files to be relative to the game.py file and still need the game file to be called from elsewhere, a good practice would be to define base_dir using __file__ attribute of the python file
base_dir = os.path.dirname(__file__)
The reason you're geting NoneType error is that somehow the loc variable is being set to None. which means that you are passing None to the Player's constructor. Since you haven't provided the code where you initialize player, I am assuming that you're passing the result of getRoom() as loc to the constructor. If that is the case, make sure that the value returned by getRoom is not None. you need an explicit return statement at the end of the function. return ret . by default any function without a return statement returns None. That could be your issue

Related

PyYAML: KeyError when trying to filter through multiple documents in a file

I've been sitting on this for several hours already, so any help would make this early year!
I'm trying to filter through .xes.yaml files which in most cases look like the picture provided at the very bottom of this question.
I am trying to loop through the files and filter for a specific trace, and when that trace is found, for specific instances of the events, which are the new documents in a yaml file (to my understanding).
Here is what I have so far:
directory = '/Users/xxx/Downloads/measure/lift'
# iterate over files in
# that directory
for filename in os.listdir(directory):
f = os.path.join(directory, filename)
if filename.endswith(".yaml"):
log = open(f)
for data in yaml.load_all(log, Loader=yaml.FullLoader):
if data['log']['trace']['cpee:name'] == 'Specific trace':
concept_instance = data['log']['trace']['concept:name'] # here is the number that corresponds to the concept:instance in events
if data['event']['concept:instance'] == concept_instance and data['event']['cpee:lifecycle:transition'] == 'activity/receiving':
print(data['event']['time:timestamp']) # as of right now, I only print the timestamp, because i need to make the other stuff work first
So, my problem is, that I get a KeyError for 'event' which I don't get.
(ba_gui) xxx#xxx-MBP xxx % /Users/xxx/opt/miniconda3/envs/xxx/bin/python /Users/xxx/xxx/overlay_graphs.py
Traceback (most recent call last):
File "/Users/xxx/xxx/overlay_graphs.py", line 32, in <module>
main()
File "/Users/xxx/xxx/overlay_graphs.py", line 21, in main
if data['event']['concept:instance'] == concept_instance and data['event']['cpee:lifecycle:transition'] == 'activity/receiving':
KeyError: 'event'
Also, when I remove the last if-statement for 'event', I get a KeyError for 'log', however when I add break after the if-statement, it works fine for some reason and it prints all concept_instances.
I would appreciate any help!!!! I'm getting mad looking at this any longer lol.

Python - Additional "members" appended to JSON object when passing it to function

I have the following JSON object located in its own file called build.json:
{
"name": "utils",
"version": "1.0.0",
"includes": [],
"libraries": [],
"testLibraries": []
}
I obtain this object in my Python program using the following method:
def getPackage(packageName):
jsonFilePath = os.path.join(SRCDIR, packageName, "build.json")
packageJson = None
try:
with open(jsonFilePath, "r") as jsonFile:
packageJson = json.load(jsonFile)
except:
return None
return packageJson
I verify that the JSON object for the current package (which is one of many packages I am iterating over) did not come back None in the following method. Note that I am temporarily printing out the keys of the dictionary:
def compileAllPackages():
global COMPILED_PACKAGES
for packageName in os.listdir(SRCDIR):
package = getPackage(packageName)
if package == None:
continue
# TEMP ==============
for i in package:
print(i)
# ===================
compiledSuccessfully = compilePackage(package)
if not compiledSuccessfully:
return False
return True
Lastly, I am currently also printing out the keys of the dictionary once it is received in the compilePackage function:
def compilePackage(package):
global COMPILED_PACKAGES, INCLUDE_TESTS
# TEMP ==============
for i in package:
print(i)
# ===================
...
Output from compileAllPackages function:
name
version
includes
libraries
testLibraries
Output from compilePackage function:
name
version
includes
libraries
testLibraries
u
t
i
l
s
I can not for the life of me figure out what is happening to my dictionary during that function call??? Please note that the build.json file is located within a directory named "utils".
Edit:
The Python script is located separate from the build.json file and works on absolute paths. It should also be noted that after getting that strange output, I also get the following exception when trying to access a valid key later (it seems to think the dictionary is a string?...):
Traceback (most recent call last):
File "/Users/nate/bin/BuildTool/unix/build.py", line 493, in <module>
main()
File "/Users/nate/bin/BuildTool/unix/build.py", line 481, in main
compiledSuccessfully = compileAllPackages()
File "/Users/nate/bin/BuildTool/unix/build.py", line 263, in compileAllPackages
compiledSuccessfully = compilePackage(package)
File "/Users/nate/bin/BuildTool/unix/build.py", line 287, in compilePackage
compiledSuccessfully = compilePackage(include)
File "/Users/nate/bin/BuildTool/unix/build.py", line 279, in compilePackage
includes = getPackageIncludes(package)
File "/Users/nate/bin/BuildTool/unix/build.py", line 194, in getPackageIncludes
includes = [package["name"]] # A package always includes itself
TypeError: string indices must be integers
Edit: If I change the parameter name to something other than 'package', I no longer get that weird output or an exception later on. This is not necessarily a fix, however, as I do not know what could be wrong with the name 'package'. There are no globals named as such either.
The answer ended up being very stupid. compilePackage() has the possibility of being called recursively, due to any dependencies the package may rely on. In recursive calls to the function, I was passing a string to the function rather than a dictionary.
I tried your code and the result is like this
Output from compileAllPackages function:
name
version
includes
libraries
testLibraries
Output from compilePackage function:
name
version
includes
libraries
testLibraries
My directory structure is like this
├── test.py
└── tt
└── cc
└── utils
└── build.json
I think your code is correct, it should be that the path parameter you passed is incorrect.

Shelve module in python not working: "db type cannot be determined"

I am trying to make a simple password-storing program in Python, and it seems pretty simple so I am wondering if I am using shelve wrong.
I have the main .py file:
import shelve
passwords = shelve.open('./passwords_dict.py')
choice = raw_input("Add password (a) or choose site (c)?")
if choice[0] == 'a':
site_key = raw_input("Add for which site? ").lower()
userpass = raw_input("Add any info such as username, email, or passwords: ")
passwords[site_key] = userpass
else:
site = raw_input("Which site? ").lower()
if site in passwords:
print "Info for " + site + ": " + passwords[site]
else:
print site, "doesn't seem to exist!"
print "Done!"
passwords.close()
And the other file, passwords_dict.py, is just an empty dictionary.
But when I try to run the program, I get this error:
Traceback (most recent call last):
File "passwords.py", line 3, in <module>
passwords = shelve.open('passwords_dict.py')
File "/usr/lib/python2.7/shelve.py", line 239, in open
return DbfilenameShelf(filename, flag, protocol, writeback)
File "/usr/lib/python2.7/shelve.py", line 223, in __init__
Shelf.__init__(self, anydbm.open(filename, flag), protocol, writeback)
File "/usr/lib/python2.7/anydbm.py", line 82, in open
raise error, "db type could not be determined"
anydbm.error: db type could not be determined
When I try to use anydbm instead, I get this error:
Traceback (most recent call last):
File "passwords.py", line 3, in <module>
passwords = anydbm.open('passwords_dict.py')
File "/usr/lib/python2.7/anydbm.py", line 82, in open
raise error, "db type could not be determined"
anydbm.error: db type could not be determined
And when I try to use dbm instead, I get this error:
Traceback (most recent call last):
File "passwords.py", line 3, in <module>
passwords = dbm.open('./passwords_dict.py')
dbm.error: (2, 'No such file or directory')
What am I doing wrong? Is there another way to store a dictionary and still be able to extract keys using user input (rather than the entire dictionary, which I suppose is what pickle does)?
I think you're misunderstanding how the shelve module works. It opens a database file. When you try and open an existing file that contains a Python script, it's trying to detect what database type the file contains (since shelve supports multiple backend databases).
I think instead you want something like this:
import os
import shelve
curdir = os.path.dirname(__file__)
passwords = shelve.open(os.path.join(curdir, 'password_db'))
This will create a new file in the same directory as your script called password_db.<db> where <db> is an implementation-specific database file extension.
I've experienced this issue as well. It seems to be related to undocumented conditions for the filename argument of shelve.open. It is currently very intransparent (e.g. shelve.open("/tmp/tmphTTQLda") works while shelve.open("/tmp/tmphTTQLd") doesn't). Failure and success of variable filenames are hard to predict. I requested an explanation in form a documentation enhancement at http://bugs.python.org/issue23174.
In my case opening a persistent dict outside shelve and passing it to shelve.Shelve works, e.g. code
a = dumbdbm.open(tempfile.mkstemp()[1])
b = shelve.Shelf(dict=a)
and do with b what you'd have done with the return value of shelve.open.
There is one bug with anydb https://bugs.python.org/issue13007 that could not use the right identification for gdbm files.
So if you are trying to open a valid gdbm file with shelve and is thorwing that error use this instead:
mod = __import__("gdbm")
file = shelve.Shelf(mod.open(filename, flag))
More information on this question: shelve db type could not be determined, whichdb is not recognizing gdb

TypeError: in Python

I have an issue, where a function returns a number. When I then try to assemble a URL that includes that number I am met with failure.
Specifically the error I get is
TypeError: cannot concatenate 'str' and 'NoneType' objects
Not sure where to go from here.
Here is the relevant piece of code:
# Get the raw ID number of the current configuration
configurationID = generate_configurationID()
# Update config name at in Cloud
updateConfigLog = open(logBase+'change_config_name_log.xml', 'w')
# Redirect stdout to file
sys.stdout = updateConfigLog
rest.rest(('put', baseURL+'configurations/'+configurationID+'?name=this_is_a_test_', user, token))
sys.stdout = sys.__stdout__
It works perfectly if I manually type the following into rest.rest()
rest.rest(('put', http://myurl.com/configurations/123456?name=this_is_a_test_, myusername, mypassword))
I have tried str(configurationID) and it spits back a number, but I no longer get the rest of the URL...
Ideas? Help?
OK... In an attempt to show my baseURL and my configurationID here is what I did.
print 'baseURL: '+baseURL
print 'configurationID: '+configurationID
and here is what I got back
it-tone:trunk USER$ ./skynet.py fresh
baseURL: https://myurl.com/
369596
Traceback (most recent call last):
File "./skynet.py", line 173, in <module>
main()
File "./skynet.py", line 30, in main
fresh()
File "./skynet.py", line 162, in fresh
updateConfiguration()
File "./skynet.py", line 78, in updateConfiguration
print 'configurationID: '+configurationID
TypeError: cannot concatenate 'str' and 'NoneType' objects
it-tone:trunk USER$
What is interesting to me is that the 369596 is the config ID, but like before it seems to clobber everything called up around it.
As kindall pointed out below, my generate_configurationID was not returning the value, but rather it was printing it.
# from generate_configurationID
def generate_configurationID():
dom = parse(logBase+'provision_template_log.xml')
name = dom.getElementsByTagName('id')
p = name[0].firstChild.nodeValue
print p
return p
Your configurationID is None. This likely means that generate_configurationID() is not returning a value. There is no way in Python for a variable name to "lose" its value. The only way, in the code you posted, for configurationID to be None is for generate_configurationID() to return None which is what will happen if you don't explicitly return any value.
"But it prints the configurationID right on the screen!" you may object. Sure, but that's probably in generate_configurationID() where you are printing it to make sure it's right but forgetting to return it.
You may prove me wrong by posting generate_configurationID() in its entirety, and I will admit that your program is magic.

EOL stops python on Calculate Field

Would anyone be able to help me modify these scripts to ignore the error and continue running ? I just need to figure out how to make the script skip over these errors and finish the rest of the lines.
Here is the full Python script:
# Import system modules
import sys, string, os, arcgisscripting
# Create the geoprocessor object
gp = arcgisscripting.create(9.3)
gp.OverWriteOutput = True
# Set the workspace. List all of the folders within
gp.Workspace = "C:\ZP4"
fcs = gp.ListWorkspaces("*","Folder")
for fc in fcs:
print fc
gp.CalculateField_management(fc + "\\Parcels.shp", "SIT_FULL_S", "myfunction(!SIT_HSE_NU!,!SIT_FULL_S!)", "PYTHON", "def myfunction(fld1,fld2):\n if (fld1=='0'or fld1=='00'or fld1<'00000000000'):\n return ''\n else:\n return fld2")
And here is the error I encounter:
Traceback (most recent call last):
File "C:\Documents and Settings\Andrew\Desktop\HOUSENUMERZERO.py", line 18, in
<module>
ERROR 000539: Error running expression: myfunction
(" ","69 FLOOD ST
") <type 'exceptions.SyntaxError'>: EOL while scanning single-quoted string (<st
ring>, line 1)
Failed to execute (CalculateField).
First option: wrap the gp.CalculateField_management(...) in a try/except, like so:
try:
gp.CalculateField_management(...)
except SyntaxError:
pass
This should allow your script to keep going, but I'm not sure what the state of gp will be.
A better option would be to preprocess each file, and deal with the fields that have the embedd new-lines in them; something like:
for fc in fcs:
fix_bad_fields(fp)
gp.Calculatate...
and fix_bad_fields looks something like (you'll have to research this as I am unfamiliar with .shp files -- I'll pretend it allows writing back to the same file, but if not you'll have to do some copying and renaming as well):
def fix_bad_fields(filename):
data_file = open_shp_file(filename)
for row in data_file:
row[0] = row[0].replace('\n', '')
row[1] = row[1].replace('\n', '')
row1.put_changes_on_disk() # force changes to disk (may not be necessary)
data_file.close()
Lots of guesswork in those particulars, but hopefully that gives you an idea and enough to go on.

Categories