def _component(self, comp): if self.ndim == 2: return Image(self[..., comp], **dict_without(self._dict, 'components')) else: return Volume(self[..., comp], **dict_without(self._dict, 'components'))
def get_metadata_from(self, schema, prefer_self=True): """ Fill in the metadata for this schema from another Parameters ---------- schema : Schema Other schema from which to get metadata for this one prefer_mine : Bool If true, use values in self any case they exist and only get values from schema where they are absent. If true, overwrite self's values with those from schema Returns ------- Nothing : updates in place """ if prefer_self: newdict = copy.copy(schema._dict) newdict.update(self._dict) else: newdict = self._dict newdict.update(schema._dict) if isinstance(self, np.ndarray): newdict = dict_without(newdict, 'shape') for key, item in newdict.items(): setattr(self, key, item)
def make_vector_schema(schema, components=('x', 'y', 'z')): if isinstance(schema, VectorSchema): shape = schema.shape else: shape = np.append(schema.shape, len(components)) if isinstance(schema, RegularGridSchema): new = VectorGridSchema( components=components, shape=shape, **dict_without(schema._dict, ['shape', 'dtype', 'components'])) else: new = VectorSchema(components=components, shape=shape, **dict_without(schema._dict, ['shape', 'dtype', 'components'])) return new
def zeros_like(obj, dtype=None): """ Make an empty marray with the same shape and metadata as the template. Parameters ---------- obj : :class:`.Schema` Template object (schema or marray) dtype : :class:`numpy.dtype` Optional argument to override array type Returns ------- arr : :class:`.Marray` Empty (all zeros) marray with shape and metadata copied from obj """ if isinstance(obj, np.ndarray): return obj.__class__(np.zeros_like(obj, dtype=dtype), **obj._dict) else: return obj._corresponding_marray(np.zeros(obj.shape, dtype=dtype), **dict_without(obj._dict, 'shape'))
def interpret_1d(self, arr): return VectorGrid(arr.reshape(self.shape), **dict_without(self._dict, ['shape']))
def _dict(self): # I believe in all cases where we use Marray._dict we don't actually # want the dtype, it is always safer to infer it from the underlying # ndarray. dtype is only provided as a constructor argument in case we # want to override the default selection. return dict_without(super(Marray, self)._dict, 'dtype')
def _dict(self): return dict_without(dict(self._iteritems()), ('wavelen', 'index', 'polarization'))
def test_get_all_comments_of_user(logged_in, test_client, session, admin_user, describe, tomorrow, make_add_reply): with describe('setup'), logged_in(admin_user): assignment = helpers.create_assignment(test_client, state='open', deadline=tomorrow) course = assignment['course'] teacher1 = admin_user teacher2 = helpers.create_user_with_role(session, 'Teacher', course) student1 = helpers.create_user_with_role(session, 'Student', course) student2 = helpers.create_user_with_role(session, 'Student', course) sub1 = helpers.create_submission(test_client, assignment, for_user=student1) sub2 = helpers.create_submission(test_client, assignment, for_user=student2) add_reply1 = make_add_reply(sub1) add_reply2 = make_add_reply(sub2) with logged_in(teacher1): rep1_1 = add_reply1('Hello a reply', line=1) rep1_2 = add_reply1('Hello a reply', line=1) rep2 = add_reply1('Hello a reply', line=10) rep3 = add_reply2('Hello a reply', line=5) def get_url(user): return (f'/api/v1/assignments/{get_id(assignment)}/users' f'/{get_id(user)}/comments/') with describe('Can get all comments by a user'), logged_in(teacher1): result = [ { '__allow_extra__': True, 'replies': [ dict_without(rep1_1, 'author'), dict_without(rep1_2, 'author') ], 'line': 1, }, { '__allow_extra__': True, 'replies': [dict_without(rep2, 'author')], 'line': 10, }, { '__allow_extra__': True, 'replies': [dict_without(rep3, 'author')], 'line': 5, }, ] test_client.req('get', get_url(teacher1), 200, result) with describe('Does not get threads without own reply'): with logged_in(teacher2): # rep1_3 is allowed to exist in the reply, however this is not the # case with the current implementation. rep5 should never be in the # reply. rep1_3 = add_reply1('A reply by somebody else', line=1) rep5 = add_reply1('A reply by somebody else', line=100) test_client.req( 'get', get_url(teacher2), 200, [ { '__allow_extra__': True, 'replies': [ # rep1_1 and rep1_2 are allowed to be present dict_without(rep1_3, 'author') ], 'line': 1, }, { '__allow_extra__': True, 'replies': [dict_without(rep5, 'author')], 'line': 100, }, ], ) with logged_in(teacher1): test_client.req('get', get_url(teacher1), 200, result)
def test_disabling_peer_feedback( test_client, admin_user, session, describe, logged_in, yesterday, make_add_reply ): with describe('setup'), logged_in(admin_user): course = helpers.create_course(test_client) assignment = helpers.create_assignment( test_client, course, deadline=yesterday, state='open' ) teacher = helpers.create_user_with_role(session, 'Teacher', course) users = [ helpers.get_id( helpers.create_user_with_role(session, 'Student', course) ) for _ in range(5) ] user1, *other_users = users for user in users: helpers.create_submission(test_client, assignment, for_user=user) helpers.enable_peer_feedback(test_client, assignment) conns = get_all_connections(assignment, 1)[user1] base_url = f'/api/v1/assignments/{helpers.get_id(assignment)}' pf_sub = m.Work.query.filter_by( assignment_id=helpers.get_id(assignment), user_id=helpers.get_id(conns[0]), ).one() pf_url = f'{base_url}/peer_feedback_settings' add_reply = make_add_reply(pf_sub) with logged_in(user1): reply = add_reply( 'A peer feedback comment', expect_peer_feedback=True ) with describe('Students cannot disable peer feedback'), logged_in(user1): test_client.req('delete', pf_url, 403) with describe('Teachers can disable peer feedback'), logged_in(teacher): test_client.req('delete', pf_url, 204) get_all_connections(assignment, 0) with describe('Old feedback still exists after disabling' ), logged_in(teacher): test_client.req( 'get', f'/api/v1/submissions/{helpers.get_id(pf_sub)}/feedbacks/', 200, query={'with_replies': '1'}, result={ 'general': '', 'linter': {}, 'authors': [helpers.to_db_object(user1, m.User)], 'user': [{ 'id': int, '__allow_extra__': True, 'replies': [helpers.dict_without(reply, 'author')], }], } ) # Students can no longer see their peer feedback subs with describe('Student can no longer place new comments' ), logged_in(user1): add_reply( 'No peer feedback', expect_error=403, base_id=reply['comment_base_id'], ) with describe('deleting again does nothing'), logged_in(teacher): test_client.req('delete', pf_url, 204) get_all_connections(assignment, 0)
def test_giving_peer_feedback_comments( test_client, admin_user, session, describe, logged_in, yesterday, tomorrow, auto_approved, make_add_reply ): with describe('setup'), logged_in(admin_user): course = helpers.create_course(test_client) assignment = helpers.create_assignment( test_client, course, deadline=tomorrow, state='open' ) teacher = helpers.create_user_with_role(session, 'Teacher', course) users = [ helpers.get_id( helpers.create_user_with_role(session, 'Student', course) ) for _ in range(5) ] user1, *other_users = users subs_by_user = {} for user in users: helpers.create_submission(test_client, assignment, for_user=user) # Every user has two submissions subs_by_user[user] = helpers.create_submission( test_client, assignment, for_user=user ) helpers.enable_peer_feedback( test_client, assignment, amount=1, auto_approved=auto_approved ) conns = get_all_connections(assignment, 1)[user1] other_user = next(u for u in other_users if u not in conns) base_url = f'/api/v1/assignments/{helpers.get_id(assignment)}' pf_sub = subs_by_user[conns[0]] own_sub = subs_by_user[user1] add_reply = make_add_reply(pf_sub) with logged_in(teacher): teacher_rep = add_reply('Hello') base_comment_id = teacher_rep['comment_base_id'] teacher_rep.delete() with describe( 'Before deadline we have no connections (and cannot place feedback)' ), logged_in(user1): test_client.req( 'get', f'{base_url}/submissions/?latest_only', 200, result=[{ 'id': int, 'user': { 'id': user1, '__allow_extra__': True, }, '__allow_extra__': True, }] ) add_reply( 'Too early for a reply', expect_error=403, base_id=base_comment_id ) with logged_in(teacher): test_client.req( 'patch', base_url, 200, data={'deadline': yesterday.isoformat()} ) with describe( 'Will receive peer feedback submissions when getting all submissions' ), logged_in(user1): test_client.req( 'get', f'{base_url}/submissions/?latest_only&extended', 200, result=[pf_sub, own_sub], ) # Can also get older subs of a assigned user test_client.req( 'get', f'{base_url}/users/{conns[0]}/submissions/?extended', 200, result=[ pf_sub, { '__allow_extra__': True, 'user': {'id': conns[0], '__allow_extra__': True}, } ], ) with describe('Can comment on other submission'), logged_in(user1): reply = add_reply('A peer feedback comment', expect_peer_feedback=True) assert reply['approved'] == auto_approved with describe('Cannot change approval status yourself'), logged_in(user1): reply.set_approval(not auto_approved, err=403) with describe('Teacher can change approval status'), logged_in(teacher): reply = reply.set_approval(not auto_approved) with describe('Editing feedback resets approval status'): with logged_in(user1): # We don't reset it back to ``True`` if ``auto_approved`` is # ``True`` but we do set it back to ``False``. reply = reply.update('New content', approved=False) if auto_approved: # If reply is approved an ``auto_approved`` is ``True`` the # approval state should not change. with logged_in(teacher): reply.set_approval(True) with logged_in(user1): reply = reply.update('New content2', approved=True) with describe( 'Cannot place or edit peer feedback after pf deadline has expired' ): with logged_in(teacher): helpers.enable_peer_feedback( test_client, assignment, amount=1, auto_approved=auto_approved, days=0.5 ) assert get_all_connections(assignment, 1)[user1] == conns with logged_in(user1): add_reply('Another peer feedback comment', expect_error=403) reply.update('Cannot update!', err=403) with describe('Can always place peer feedback if pf time is None'): with logged_in(teacher): helpers.enable_peer_feedback( test_client, assignment, amount=1, auto_approved=auto_approved, days=None, ) with freezegun.freeze_time( DatetimeWithTimezone.utcnow() + timedelta(days=365 * 20) ), logged_in(user1): reply = reply.update('Can update way after the deadline!') with describe('Cannot add peer feedback to a non assigned sub' ), logged_in(other_user): add_reply( 'Not possible to add this', expect_error=403, base_id=reply['comment_base_id'] ) with describe('Student can see approved peer feedback after done'): with logged_in(teacher): reply = reply.set_approval(not auto_approved) test_client.req( 'get', f'/api/v1/submissions/{helpers.get_id(pf_sub)}/feedbacks/', 200, query={'with_replies': '1'}, result={ 'general': '', 'linter': {}, 'user': [{ 'id': int, '__allow_extra__': True, 'replies': [helpers.dict_without(reply, 'author'), ], }], 'authors': [helpers.to_db_object(user1, m.User)], }, ) test_client.req('patch', base_url, 200, data={'state': 'done'}) with logged_in(conns[0]): test_client.req( 'get', f'/api/v1/submissions/{helpers.get_id(pf_sub)}/feedbacks/', 200, query={'with_replies': '1'}, result={ 'general': '', 'linter': {}, 'authors': ([helpers.to_db_object(user1, m.User)] if reply['approved'] else []), 'user': ([{ 'id': int, '__allow_extra__': True, 'replies': [helpers.dict_without(reply, 'author')], }] if reply['approved'] else []), }, )