[Tutor] How to effectively use a Student class with SQLite [Was Re: How to design object interactions with an SQLite db?]

Alan Gauld alan.gauld at btinternet.com
Fri Aug 14 10:34:07 CEST 2015


On 14/08/15 03:16, boB Stepp wrote:

>> Yes, that's a standard problem in any HR type application. Names suck as
>> database keys. But names are how humans interact.
>
> HR = Human Resources?

Sorry, yes. Anything involving people.

> the case of students with duplicate names, she might forget to enter
> one (or more, if there are that many).

You can't really mitigate for that kind of error.
Imagine popping up a dialog for every single record saying "Are you sure 
you didn't forget somebody else of the same name?" How annoying would 
that get?! Even if you only did it during bulk data input it would still 
be a pain.

> place and edit that student's data.  It seems that I would always have
> to display a certain amount of student information to make it
> *obvious* to the user which student she is editing.  Or is there an
> easier way?

No, you need to identify which subset of fields are sufficient to always 
identify a student. And that might mean all of them!

> I'm guessing this stands for "Model-view-controller" as in
>
> https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller

Correct. MVC is the standard UI OOP pattern, its been around a long time 
(with various minor variants) and it works. The main simplification is 
to sometimes join the View and Controller
into a singe object. Microsoft did this with their Windows
object model.

> is the controller serving as the API between the data (model) and the
> display (view)?

No, or only partly. The controller captures and processes user input. It 
controls the state machine that determines which actions are
valid and which are not depending on the states of the Model
and the current Views(there may be multiple views of the same
model) The controller is sometimes known as the "policy" of
the UI - the rules of how it works. As such the controller is
the thing that determines that an action is valid and makes the
call to the Models UI. In most MVC implementations the Model
will have a list of all open views and send a state update to
those views so they can update themselves. In a few cases the Controller 
does that bit sand the Model replies only to the
controller.

If you are using a network model where different devices may
have views onto the same object then you must use the first
option. In a single desktop app the second option tends to
be more efficient.

In all cases its the Model that exposes the API that provides
the business value/logic of the system. The View and Controller
are purely UI focussed.

> So is the idea here to decouple the program logic
> from the (possibly complicated) UI, is to have a module (controller?)
> which processes data resulting from the program logic (model) and then
> decides whether this should go to the menu portion of the display, or
> the part that generates a pop-up window, etc.?  And likewise
> user-generated events go to the controller module and it decides which
> data states get altered in the model?

Pretty close. Any window that displays data(state) of an Model is a 
view. You could have a graphical view and a table view of the same
data for example, and both could be on screen together. Or you could 
have two devices accessing the same data model over a network at the 
same time.

In both cases the Model has multiple views and one or more controllers.

> correctly, the program logic (model) and controller need to be
> designed in parallel?

Not always, but if you use the use case approach the controller
implements the sequence of events and the model implements the
actual actions. You can extract the actions from the use case and 
implement that separately. But in bigger projects the UI and
database teams will likely work in parallel and with close
co-operation.

> lines in other projects I have done.  I will have to search for most
> applicable materials to my current project.

A very simple example is the login use case

Actors - User, SUD(System under design), UserDB
Preconditions - None
Postcondition - SUD Home screen displayed to user

1) User starts application
2) SUD displays login screen with username and password fields.
    submit is greyed out
3) User fills in name and password
4) SUD validates field content and enables submit button
5) user hits submit
6) SUD validates user name and password
7) SUD displays home screen

1A1 - SUD fails to launch
1A2 User retries
4A1 User fails to fill in all fields
4A2 SUD does not enable submit
4B1 User fills a field with invalid characters
4B2 SUD presents error message
6A1 User does not exist
6A2 SUD notifies user of error
6B1 Password is invalid
6B2 SUD notifies user of error
6C1 Password has expired
6C2 SUD initiates change password use case.
6D1 After 3 unsuccessful login submissions the SUD
     locks the user account, logs a security threat
     and notifies the sys admin.

Notice its very common to have more error cases than happy path steps!
Notice too that some steps have multiple error cases.


> Hmm.  I was thinking that I would need all the student objects
> generated first and then move on to reports, etc.,

In general instantiating an object can be quite expensive both
in time and in memory. So if processing large numbers of
objects  (especially in read only mode) its often better
to have a grouping object until you find the ones you
need to do work with. It also minimises risk of premature
locking in the database.

>>>       2)  If a new student needs to be created by the user, then the
>>> Student class would have an appropriate method which would allow for
>>> data entry via the UI to both create a new student object and a new
>>> student db table entry with its own unique student_id primary key.

The studentModel will have both create (ie constructor) and update 
methods. Since both will be doing the same basic task you might call 
update from the constructor. The difference is the constructor will
be gathering the data either from direct input from the UI View
object or from the database(based on an ID) before calling update. 
Whereas updating a displayed object will likely come straight from
the controller to the model.update() method.

> Would you please elaborate on what you mean by StudentView object,
> StudentModel object and what you think I have meant thus far by my use
> of student object?

Hopefully the above comments suffice? If not ask away.

>> The program logic of the Model class would. The users of the Model reference
>> it through a Python variable like anything else. Its
>> object oriented programming not database oriented programming.
>> Use the objects.
>
> Again, I am not sure I am understanding all of what you mean here.

Just that from the codes point of view everything accesses the Python 
object in memory - just like it would a string or a file object. Its the 
model that knows about how that object is stored and does all the 
database calls etc. (A Record object would also do database calls but 
only of a group wide scope:

SELECT .... FROM CLASS WHERE .... ORDER BY ....

The model does all SQL that involves a single row/instance.

CREATE, DELETE, UPDATE, SELECT * FROM CLASS
(Although you should never actually use * in production code!)


So you should never be passing the database ID around in the app (except 
maybe from the record to the instantiation call). Instead
you pass the object itself.

> I am not familiar with either the argparse or cmd modules.  To the
> docs I must go!

Have fun, both can be used simply but have lots of depth
to explore too! argparse is recent Python 3 only, but there
are a couple of older modules do a similar job if you are
stuck on v2. (optparse? and getopt? I think they were called.)

HTH
-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos




More information about the Tutor mailing list