I am getting this traceback;
--- Trimmed parts ---
File "C:\Users\muhammed\Desktop\gifdatabase\gifdatabase.py", line 76, in maketransaction
gif.tags = list(set(gif.tags + tags))
File "C:\Program Files (x86)\Google\google_appengine\google\appengine\ext\ndb\model.py", line 2893, in __hash__
raise TypeError('Model is not immutable')
TypeError: Model is not immutable
Here is related parts of my code;
class Gif(ndb.Model):
author = ndb.UserProperty()
#tags = ndb.StringProperty(repeated=True)
tags = ndb.KeyProperty(repeated=True)
#classmethod
def get_by_tag(cls,tag_name):
return cls.query(cls.tags == ndb.Key(Tag, tag_name)).fetch()
class Tag(ndb.Model):
gif_count = ndb.IntegerProperty()
class PostGif(webapp2.RequestHandler):
def post(self):
user = users.get_current_user()
if user is None:
self.redirect(users.create_login_url("/static/submit.html"))
return
link = self.request.get('gif_link')
tag_names = shlex.split(self.request.get('tags').lower())
#ndb.transactional(xg=True)
def maketransaction():
tags = [Tag.get_or_insert(tag_name) for tag_name in tag_names]
gif = Gif.get_or_insert(link)
if not gif.author: # first time submission
gif.author = user
gif.tags = list(set(gif.tags + tags))
gif.put()
for tag in tags:
tag.gif_count += 1
tag.put()
if validate_link(link) and tag_names:
maketransaction()
self.redirect('/static/submit_successful.html')
else:
self.redirect('/static/submit_fail.html')
What is the problem with gif.tags = list(set(gif.tags + tags)) line?
You are inserting tags instead of keys, you need to access
tags = [Tag.get_or_insert(tag_name).key .....]
but you can also make this a single network hop like this
futures = [Tag.get_or_insert_async(tag_name) for tag_name in tag_names]
futures.append(Gif.get_or_insert_async(link))
ndb.Future.wait_all(futures)
gif = futures.pop().get_result()
tags = [future.get_result() for future in futures]
but that's not really the question just a suggestion ^, for clearer answer with .key is
gif.tags = gif.tags + [tag.key for tag in tags]
# or
gif.tags.extend([tag.key for tag in tags])
Related
I had a company assign me an assignment to implement a fileSystem class to run shell commands through python without using any libraries. Does anyone have any suggestions on how to get started? Not quite sure how to tackle this problem.
Problem:
Implement a FileSystem class using python
Root path is '/'.
Path separator is '/'.
Parent directory is addressable as '..'.
Directory names consist only of English alphabet letters (A-Z and a-z).
All functions should support both relative and absolute paths.
All function parameters are the minimum required/recommended parameters.
Any additional class/function can be added.
What I've worked on so far:
class Path:
def __init__(self, path):
self.current_path = path.split("/")
def cd(self, new_path):
new_split = new_path.split("/")
for i in new_split:
if i == "..":
new_split.pop(0)
self.current_path = self.current_path[:-1]
self.current_path += new_split
def getString(self):
return "/".join(self.current_path)
def pwd(self, path):
return self.current_path
def mkdir():
pass
def rmdir():
pass
#driver code
fs = Path()
fs.mkdir('usr')
fs.cd('usr')
fs.mkdir('local')
fs.cd('local')
return fs.pwd()
So, this is what I came up with. I know I need to clean it up
'''
class Path:
dir_stack = []
def __init__(self):
print("started")
main_dir = {'/': {}}
self.dir_stack.insert( len(self.dir_stack), main_dir)
def getCurrentMap():
global current_Level
current_Level = self.dir_stack[len(self.dir_stack) - 1]
def cd(self, folder):
if(folder == '../'):
self.dir_stack.pop()
current_Level = self.dir_stack[len(self.dir_stack) - 1]
current_Map = current_Level[(list(current_Level.keys())[0])]
print('lev', current_Map)
if folder in current_Map:
print('here')
self.dir_stack.insert(len(self.dir_stack), current_Map)
else:
print ("no existing folder")
def pwd(self):
path = ''
print(self.dir_stack)
for x in self.dir_stack:
path += (list(x.keys())[0]) + '/'
print(path)
def ls(self):
current_Level = self.dir_stack[len(self.dir_stack) - 1]
current_Map = current_Level[(list(current_Level.keys())[0])]
print(current_Map)
def mkdir(self, folder_Name):
current_Level = self.dir_stack[len(self.dir_stack) - 1]
newDir = {folder_Name: {}}
current_Map = current_Level[(list(current_Level.keys())[0])]
if folder_Name in current_Map:
warning = folder_Name + ' already exists in directory'
print(warning)
else:
current_Map.update(newDir)
def rmdir(self, folder_Name):
current_Level = self.dir_stack[len(self.dir_stack) - 1]
#make global var current_Map
current_Map = current_Level[(list(current_Level.keys())[0])]
if folder_Name in current_Map:
del current_Map[folder_Name]
else:
print('folder doesnt exist')
# driver code
fs = Path()
fs.mkdir('usr')
fs.mkdir('new')
fs.mkdir('files')
fs.cd('usr')
fs.mkdir('local')
fs.cd('new')
fs.pwd()
fs.cd('../')
fs.ls()
# fs.mkdir('local')
# fs.cd('local')
fs.pwd()
I'm learning Django and I'm trying to make a Cart, which the customer can get and item and add it in his/her order row and then the order will be submitted. so my teacher said use def initiate(customer), and I don't understand how to use it. Can someone please explain it to me? Thank you.
here is the code I'm working on it:
User = get_user_model()
class Customer(models.Model):
user = models.OneToOneField(User, on_delete=Product, related_name="User")
phone = models.CharField(max_length=20)
address = models.TextField()
balance = models.IntegerField(default=20000)
def deposit(self, amount):
self.balance += amount
self.save()
def spend(self, amount):
if amount > self.balance:
raise ValueError
self.balance -= amount
self.save()
class OrderRow(models.Model):
product = models.ManyToManyField(Product)
order = models.ForeignKey('Order', on_delete=models.CASCADE)
amount = models.IntegerField()
class Order(models.Model):
# Status values. DO NOT EDIT
STATUS_SHOPPING = 1
STATUS_SUBMITTED = 2
STATUS_CANCELED = 3
STATUS_SENT = 4
customer = models.ForeignKey('Customer', on_delete=models.SET_NULL)
order_time = models.DateTimeField(auto_now=True)
total_price = Sum(F('amount') * F('product__price'))
status = models.IntegerField(choices=status_choices)
#staticmethod
def initiate(customer):
Order.initiate(User)
def add_product(self, product, amount):
Order.status = 1
OrderRow.product = Product.objects.get(id=product.id)
print(product.id)
if OrderRow.objects.filter(product=product).exists():
preexisting_order = OrderRow.objects.get(product=product, order=self)
preexisting_order.amount += 1
preexisting_order.save()
else:
new_order = OrderRow.objects.create(
product=product,
cart=self,
amount=1,
)
new_order.save()
You are probably supposed to create a new Order associated with this customer. Something along the following lines:
#classmethod
def initiate(cls, customer):
return cls.objects.create(customer=customer, status=cls.STATUS_SHOPPING)
There are some other issues with your code. You cannot use SET_NULL if the fk is not nullable:
customer = models.ForeignKey('Customer', on_delete=models.SET_NULL, null=true)
There should not be multiple products per row:
class OrderRow(models.Model):
product = models.ForeignKey(Product) # not many2many!
# ...
Also, your add_product needs quite some fixing:
def add_product(self, product, amount):
self.status = self.STATUS_SHOPPING # the instance is self + use your descriptive variables
print(product.id)
# filter only rows in the current order!
if self.orderrow_set.filter(product=product).exists():
# fix naming: this is a row, not an order
preexisting_order_row = self.orderrow_set.get(product=product)
preexisting_order_row.amount += amount # why +1, you are adding amount
preexisting_order_row.save()
else:
new_order_row = OrderRow.objects.create(
product=product,
order=self,
amount=amount,
) # create saves already
I want to add some extra information into the exists abc file or if its possible while creating alembic cache with some extra information in maya or any cg application using pyhon.
I am appreciate any one can help me to edit the alembic file.
input example
meta_data = {'name': 'Hero', 'tag': 'test_show'}
abc_file = '/show/test_show/scene/hero.abc'
set meta data ?
from alembic import Abc
get meta data
from alembic import Abc
archive = Abc.IArchive(abc_file)
top = archive.getTop()
meta_data = top.getMetaData()
print meta_data__str()
Here's a complete script that does the job of copying the source alembic file and inserting some metadata:
import os
import alembic
def copy_props(i_props, o_props):
'''
Copy properties
'''
for index in range(i_props.getNumProperties()):
header = i_props.getPropertyHeader(index)
if header.isArray():
i_prop = alembic.Abc.IArrayProperty(
i_props,
header.getName())
prop_name = i_prop.getName()
prop_meta = i_prop.getMetaData()
o_prop = alembic.Abc.OArrayProperty(
o_props,
prop_name,
i_prop.getDataType(),
prop_meta,
0)
o_prop.setTimeSampling(i_prop.getTimeSampling())
for i in range(i_prop.getNumSamples()):
o_prop.setValue(i_prop.getValue(i))
elif header.isScalar():
i_prop = alembic.Abc.IScalarProperty(
i_props,
header.getName())
prop_name = i_prop.getName()
prop_meta = i_prop.getMetaData()
o_prop = alembic.Abc.OScalarProperty(
o_props,
prop_name,
i_prop.getDataType(),
prop_meta,
0)
o_prop.setTimeSampling(i_prop.getTimeSampling())
for i in range(i_prop.getNumSamples()):
o_prop.setValue(i_prop.getValue(i))
elif header.isCompound():
i_prop = alembic.Abc.ICompoundProperty(
i_props,
header.getName())
prop_name = i_prop.getName()
prop_meta = i_prop.getMetaData()
o_prop = alembic.Abc.OCompoundProperty(
o_props,
prop_name,
prop_meta)
copy_props(i_prop, o_prop)
def copy_object(i_obj, o_obj):
'''
Recursively copy object data
'''
if o_obj is None:
return
i_props = i_obj.getProperties()
o_props = o_obj.getProperties()
copy_props(i_props, o_props)
for index in range(i_obj.getNumChildren()):
i_child = i_obj.getChild(index)
i_child_name = i_child.getName()
i_child_meta = i_child.getMetaData()
o_child = alembic.Abc.OObject(o_obj, i_child_name, i_child_meta)
copy_object(i_child, o_child)
def copy_abc(i_path, o_path, app, description):
'''
Copy alembic file from i_path to o_path
'''
arc_in = alembic.Abc.IArchive(i_path)
arc_out = alembic.Abc.OArchive(o_path, asOgawa=True)
arc_out = alembic.Abc.CreateArchiveWithInfo(o_path, app, description)
top_in = arc_in.getTop()
top_out = arc_out.getTop()
copy_object(top_in, top_out)
def read(abc_file):
archive = alembic.Abc.IArchive(abc_file)
return alembic.Abc.GetArchiveInfo(archive)
if __name__ == '__main__':
i_path = os.path.join(
os.path.dirname(__file__),
'itest.abc'
)
o_path = os.path.join(
os.path.dirname(__file__),
'otest.abc'
)
copy_abc(i_path, o_path, 'Cool app', 'Cool description')
print('Created archive: ' + o_path)
archive_info = read(o_path)
print('App name: ' + archive_info.get('appName'))
print('Description: ' + archive_info.get('userDescription'))
print('Written: ' + archive_info.get('whenWritten'))
You can't write just arbitrary data but you can set description and application strings:
from alembic import Abc
MY_APP = 'My cool application'
def write(abc_file, description):
archive = Abc.CreateArchiveWithInfo(abc_file, MY_APP, description)
def read(abc_file):
archive = Abc.IArchive(abc_file)
top = archive.getTop()
return Abc.GetArchiveInfo(archive)
abc_file = 'alembic.abc'
write(abc_file, 'An abc file cool description')
archive_info = read(abc_file)
print(archive_info.get('appName'))
print(archive_info.get('userDescription'))
print(archive_info.get('whenWritten'))
class PostTemplate(BaseModel):
content = TextField(unique=True)
class VkGroup(BaseModel):
group_id = IntegerField(unique=True)
class PostTemplateVkGroup(BaseModel):
"""
http://charlesleifer.com/blog/a-tour-of-tagging-schemas-many-to-many-bitmaps-and-more/
"""
group = ForeignKeyField(VkGroup)
post_template = ForeignKeyField(PostTemplate)
def get_posted_templates_for_group(group_id: int) -> Iterable:
"""Get posted templates.
Args:
group_id (int): id группы
"""
queries = (PostTemplate
.select()
.join(PostTemplateVkGroups)
.join(VkGroup)
.where(VkGroup.group_id == group_id))
return queries
all_post_templates = PostTemplate.select()
Many-to-many relationship.
For every record in PostTemplateVkGroup post template from this record is used in group from this record.
all_post_templates = not_posted_templates | posted_templates
How I can get not_posted_templates?
If your database supports the "EXCEPT" operation, you can:
all_post_templates = PostTemplate.alias().select()
post_templates = get_posted_templates_for_group(...)
difference = all_post_templates - post_templates
Sqlite example:
class Post(Base):
title = TextField()
class Tag(Base):
tag = TextField()
class PostTag(Base):
post = ForeignKeyField(Post)
tag = ForeignKeyField(Tag)
db.create_tables([Post, Tag, PostTag])
data = (
('pa', ('ta1', 'ta2')),
('pb', ('tb1', 'tb2')),
('pc', ()))
for title, tags in data:
post = Post.create(title=title)
for tag in tags:
tag = Tag.create(tag=tag)
PostTag.create(post=post, tag=tag)
# Create some tags that aren't associated with any post.
Tag.create(tag='tx1')
Tag.create(tag='tx2')
pa1_tags = (Tag
.select()
.join(PostTag)
.join(Post)
.where(Post.title == 'pa'))
all_tags = Tag.alias().select()
diff = all_tags - pa1_tags
for t in diff:
print(t.tag)
# Prints
# tb1
# tb2
# tx1
# tx2
I have a question my db model looks like:
class UserAnswer (db.Model):
user = db.UserProperty()
name = db.StringProperty()
email = db.StringProperty()
occupation = db.IntegerProperty()
howreach = db.IntegerProperty()
rating = db.IntegerProperty()
comment = db.StringProperty(multiline=True)
class Involves(db.Model):
shortName = db.StringProperty()
fullName = db.StringProperty()
class UserInvolves(db.Model):
userAnswer = db.ReferenceProperty(UserAnswer)
involve = db.ReferenceProperty(Involves)
How can I do a select something like this:
def getInvolves(user):
results = db.GqlQuery("Select * from UserInvolves as ui where ui.userAnswer.ID='"+user.ID+"'")
I mean how I can get this id key? As when I try like above I recive an error:
Traceback (most recent call last):
File "C:\Program Files\Google\google_appengine\google\appengine\ext\webapp\__init__.py", line 517, in __call__
handler.post(*groups)
File "C:\Program Files\Google\google_appengine\demos\b00213576\main.py", line 217, in post
involves = getInvolves(answer)
File "C:\Program Files\Google\google_appengine\demos\b00213576\main.py", line 128, in getInvolves
results = db.GqlQuery("Select * from UserInvolves as ui where ui.userAnswer.ID='"+user.ID+"'")
AttributeError: 'UserAnswer' object has no attribute 'ID'
And I dont know how to convert to GAE :/
user_answer = UserAnswer.get_by_id(user.ID)
for user_involve in user_answer.userinvolves_set:
# these are your UserInvolves items