Busy week, thanks for the replies.
RE: legality - ugh. It's amazing how legislation gets in the way of good
technology, especially when the technology the legislation prevents is 1000
times more secure than the paper gradebooks it forces teachers to maintain
and carry around with them because of the restrictions. After a few hours
of perusing Alabama state code, I can pretty confidently state that we don't
have any provisions against storing data outside of the state. We even have
one provision making it *easier* to transfer records between states targeted
at military kids. On the lighter side, I found a ton of legislation
protecting the records of student-athletes from their recruiters, and
several provisions ensuring that our football coaches are well paid and
cared for in retirement. I guess you see what our priorities are here in
the South. ROLL TIDE! :rolleyes: Either way, I'm OK with not being able to
penetrate every state in the US, as long as I can cover Alabama. The app is
for my wife first, and if it catches on and becomes a business of its own,
that's great. The cloud does give me the key benefit of being able to scale
from one teacher, to one school, to the whole state, to every state that
doesn't specifically prohibit out-of-state storage, with minimal additional
effort on my part. At least as long as I design it correctly to start with.
If my wife and her friends end up being the only ones that use it, then the
LAMP server on my own is overkill, and if it spreads to multiple states,
then I've got to hire people to maintain them (or rely on whatever IT group
the districts manage to cobble together to keep my servers running). Also,
the biggest complaint teachers have with locally served grade management
systems is they work great until the end of the 9 weeks when everybody is
putting in grades at the same time, then they crash or are incredibly slow
at the time when there is the biggest amount of pressure to get it all in.
The cloud solves this problem handily.
There are national confidentiality and accessibility laws regarding student
records, primarily FERPA, but they basically say that a particular students
records are only visible to their parents, teachers, and school officials,
and that parents have the rights to access their students' records at any
time. Standard security stuff. My day job is application development in a
bank - so this sort of security is pretty simple to me.
RE: spreadsheets - That was more of a metaphor for the user interface than a
description of everything I'm storing. Each grade also has comments
attached to it, can be dropped, exempted, have its own unique total points
separate from the rest of the students in the activity (for disability
accommodations), and other possible extended attributes. Storing this in a
google spreadsheet could work, but it would be confusing to the teacher to
actually work with the underlying spreadsheet. Data is data, but I am
making the assumption that GAE is at least a little more efficient
communicating with the data store than with an external service, and the
generic nature of the data store allows me to continue to expand the
capabilities without trying to squeeze them into a spreadsheet model. My
super-spreadsheets will take the concept of the note tag in the corner and
add several other graphical indicators of additional meta-data attached to
the all-important number in the middle of the cell.
RE: charts - I've already decided on ExtJS 4's charting library. It's all
HTML5 based (with canvas support for IE6), and transforms data into pretty
pictures on the client side... so all I have to do on the App engine side of
things is send and receive data, and update the underlying models.
RE: beforeunload - I specifically want to avoid beforeunload hooks.
Different browsers deal with an asynchronous request from this hook in
different ways, so there's no guarantee that the request would actually
execute, much less complete. I also am opposed to hijacking the browser
when a frustrated teacher is finally finished for the day and saying "please
wait while we save your data... please?" And that doesn't even take into
account browser crashes on aging hardware in the classrooms. My first
mantra is "don't be annoying"... so I think the extra overhead of sending
each update individually is worth it for increased usability. That grade
update handler is going to be a one-liner to just take the request and put
it on a task queue... it can't take long to do that, can it?
RE: 50,000 read/write/small a day: So let's say an average teacher has two
activities a day (it's not uncommon in math classes especially to have daily
homework and classwork grades). The average class has 25 students. So
that's 50 writes a day if I store all the grades in individual grade
objects. But my understanding is that there is a key index and then the
object itself that has to be written, so that's 100 writes, assuming all
properties are unindexed. Finally, the teacher usually teaches 6 periods a
day, so that turns into 600 write ops a day for one teacher entering 2
assignments a day. The common case is more like one assignment every other
day, which averages out to more like 150 write ops a day, but that's just
one teacher. So far, great - I can support about 350 teachers for free.
The real kicker comes on the read though... every time the teacher opens
their gradebook, it has to read all the grades for every assignment and
every student... which towards the end of the 9 weeks could be 100
assignments * 25 students = 2500 grade objects to read... Even in the more
common case of about 20 assignments per 9-weeks, you still are reading 20*25
= 500 grade objects per class. Multiply that by 6 classes, and the server
has to go find 3000 individual objects just to show all the grades for all
classes. Depending on how often they close their browser and/or log out
(teachers are supposed to every time they leave their desk to prevent kids
from sneaking around and changing something), they could load those
gradebooks several times throughout the day. I can use lazy loading (don't
download the data until they click the tab), but that's annoying (see
previous paragraph). Even then, they always will click at least one tab,
and then there's whichever tab is default that they weren't looking at, so
that's 1000 reads every time they open their browser. At a bare minimum,
the teacher will look at their gradebook 6 times a day to enter attendance
information, and they should log out when they are not at their desk,
they'll probably look at it at least twice again, once during their prep
period to enter some grades, and again after school. That's 8000 reads a
day. So now I can only take 6 teachers on the free quota, taking reads into
account... OUCH! On the other hand, if all grade information from the
course was in one object, then loading all the grades for all courses would
require 7 reads. 8 times a day brings that up to 56 reads a day. So we're
talking 100-1000 times more teachers on the free quota (or at any given
price point) based on datastore usage. And I avoid the problem where the
last half of the 9 weeks costs me more than the first half because there are
more objects to read.
In other words, moving from one-object-per-grade to one-object-per-course
reduces my datastore cost by 2 to 3 orders of magnitude. The question then
becomes whether that reduction comes at the cost of increased latency, which
translates to increased instances. One thing I know is that reading more
than 1000 grades at once is going to cost more calls to the data store,
increasing latency. And packaging the data up into JSON format will be
roughly the same whether it's coming from 3000 objects, or six objects with
25 properties containing lists of 20 elements. In fact, I may again save
some processing time if the native JSON serializer can directly encode
datastore objects. Hmmm... that actually gives me an idea... since reading
is more common than writing, maybe I should just store the data directly as
JSON strings rather than as lists. Then I have practically zero cost in the
common case of reading from the datastore, convert to JSON, send to client.
With the new native JSON serializer in 2.7, converting back and forth when
I have to update the data won't be that big of a deal either. Not to
mention, JSON is actually more compact for my numbers which are usually 2 or
3 digit integers (plus the comma) than the datastore's format which always
stores numbers as 8-byte doubles as far as I know. About the largest
(string-wise) number you'll see is something like 135.25 on a big test with
partial credit. And that's still a byte smaller than native format, even
counting the comma. Finally, I can store complex objects within the array,
where ListProperty only allows me to store simple types. This will work
nicely for the list of assignments, which has multiple pieces of info for
each assignment and was previously going to have to be represented as
multiple parallel lists, and for grades that have comments attached to them
(like: [95,90,75,{"grade":50,"comment":"turned in 5 days late"},95,75,...]).
I really think this is the solution I'm looking for.
--
You received this message because you are subscribed to the Google Groups
"Google App Engine" group.
To view this discussion on the web visit
https://groups.google.com/d/msg/google-appengine/-/9URP7mVq15gJ.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/google-appengine?hl=en.