Using Classes

M

Mag Gam

I have been using python for about 1 year now and I really like the
language. Obviously there was a learning curve but I have a programing
background which made it an easy transition. I picked up some good
habits such as automatic code indenting :), and making my programs
more modular by having functions.

I know that Python is very OOP friendly, but I could not figure out
why and when to use Classes in it. I mostly use it for simple text
parsing I suppose when a program gets "complicated" I should start
using Classes. Are there any tips or tricks people use to "force" them
into the OOP mentality? I would like to force myself to learn the
Python way but so far I could not figure out WHY I would need a class
for this...


TIA
 
B

Bruno Desthuilliers

Mag Gam a écrit :
I have been using python for about 1 year now and I really like the
language. Obviously there was a learning curve but I have a programing
background which made it an easy transition. I picked up some good
habits such as automatic code indenting :), and making my programs
more modular by having functions.

I know that Python is very OOP friendly, but I could not figure out
why and when to use Classes in it.

If you have some more or less formal "data type" defined by ie dicts
with some particular keys in them or tuples with a known structure, and
a few fonctions working on these dicts or tuples, then you have a
perfect use case for OO.

For other use case, have a look at the csv module or the various XML /
SGML / HTML parsers in the stdlib. There's a pretty interesting paper
from Alex Martelli here:

http://www.aleax.it/Python/os03_template_dp.pdf

I mostly use it for simple text
parsing I suppose when a program gets "complicated" I should start
using Classes.

Not necessarily. OO is one way to organize code and data, but there are
other ways that work as well, depending on the problem at hand and how
your brain is connected.
Are there any tips or tricks people use to "force" them
into the OOP mentality? I would like to force myself to learn the
Python way but so far I could not figure out WHY I would need a class
for this...

Not going into OO when you don't need it IS actually the "Python way" !-)
 
N

Neil Cerutti

Not going into OO when you don't need it IS actually the
"Python way" !-)

My most satisfying classes are the ones that gradually coalesce
from a functional program. They take actual shape during
refactoring.

I find classes to be the most successful when they improve my
conception of a program by gathering operations and data together
in a way that simplifies my program.

They have the least positive impact when I slap them together
early on, just to group up some data that appears to need
grouping.

It's pretty rare that I know the best operations for each bit of
data and how best to bundle that data until after a program is
functional. It is lucky my programs are relatively small. ;)
 
A

Alf P. Steinbach /Usenet

* Mag Gam, on 24.06.2010 13:58:
I have been using python for about 1 year now and I really like the
language. Obviously there was a learning curve but I have a programing
background which made it an easy transition. I picked up some good
habits such as automatic code indenting :), and making my programs
more modular by having functions.

I know that Python is very OOP friendly, but I could not figure out
why and when to use Classes in it. I mostly use it for simple text
parsing I suppose when a program gets "complicated" I should start
using Classes. Are there any tips or tricks people use to "force" them
into the OOP mentality? I would like to force myself to learn the
Python way but so far I could not figure out WHY I would need a class
for this...

Use whatever paradigm that yields code that you easily understand. <g>

Having said that, the main use of a class is to model some data with an
associated set of operations.

For this a class is merely a convenience, but sometimes the convenience can be
so great that any other approach would be impractical in comparision.

In some cases a non-class approach ends up with a number of routines foo, bar,
zlopf etc. that all take some argument of a "general" type and all internally
has some "if it's really a BRACHYKLURB, do A, assuming that it has
BRACHYKLURB-specific data, but if it's really a KNETCHOFICHUS, then do B,
assuming that it has KNETCHOFICHUS-specific data, and as default, if it's none
of those, do C".

This is a maintainance nightmare. You have to be sure that every such routine
discriminates correctly on type, checking all possibilities and doing the right
thing for each possibility. And you have to be sure of that in the face of
possible additions of new subtypes, or removal of a subtype (maintainance).

Then the answer is to introduce some classes and OOP stuff.

In essence, instead of letting general routines awkwardly and error-prone choose
the right type-specific routines depending on the object, let the object specify
the right type-specific routines directly. :)


Cheers & hth.,

- Alf
 
G

geremy condra

* Mag Gam, on 24.06.2010 13:58:

Use whatever paradigm that yields code that you easily understand. <g>

Having said that, the main use of a class is to model some data with an
associated set of operations.

For this a class is merely a convenience, but sometimes the convenience can
be so great that any other approach would be impractical in comparision.

In some cases a non-class approach ends up with a number of routines foo,
bar, zlopf etc. that all take some argument of a "general" type and all
internally has some "if it's really a BRACHYKLURB, do A, assuming that it
has BRACHYKLURB-specific data, but if it's really a KNETCHOFICHUS, then do
B, assuming that it has KNETCHOFICHUS-specific data, and as default, if it's
none of those, do C".

If making up words is an art form, we are in the presence of a master.

/applause

Geremy Condra
 
M

Mag Gam

Thanks everyone for your responses. They were very useful and I am
glad I asked the question.

I think having a concrete example would help me better, lets say I have this.


Trian A, Arrived at 6:00AM Jun 25, Left at 8:00AM Jun 25
Trian B, Arrived at 2:00AM Jun 26, Left at 12:00AM Jun 26
Trian C, Arrived at 4:00AM Jun 2, Left at 11:00AM Jun 2
Trian D, Arrived at 7:00AM Jun 11, Left at 3:00AM Jun 11


How would I build an OOP model with Python?

class Train:
"""A simple example class"""

def Arrive(self):
return 'Arrived at: '
def Left(self):
return 'Left at: '

Does that look right? Lets say I want to figure out how long each
train waited on the platfor
 
D

Dennis Lee Bieber

Thanks everyone for your responses. They were very useful and I am
glad I asked the question.

I think having a concrete example would help me better, lets say I have this.


Trian A, Arrived at 6:00AM Jun 25, Left at 8:00AM Jun 25
Trian B, Arrived at 2:00AM Jun 26, Left at 12:00AM Jun 26
Trian C, Arrived at 4:00AM Jun 2, Left at 11:00AM Jun 2
Trian D, Arrived at 7:00AM Jun 11, Left at 3:00AM Jun 11
Arrived where? Left where? Especially as "Trian D" "left" four hours
before it "arrived"... said:
Does that look right? Lets say I want to figure out how long each
train waited on the platfor
I'd probably model that as an attribute of a station/platform

This doesn't quite answer your specific "how long" question (in
truth, I've got the reverse here -- each Station has a fixed "wait"
time, but the time is different for different stations).

It also isn't a very well thought out example, I wrote it on the
fly. A better simulation would use callbacks into each train, and time
ordered queue of events. That way the main loop would basically consist
of pulling off the first (lowest time value) event -- set that time as
"now", invoke the callback passing "now" (which would activate the
method in the train that defined that event); the train would then put
out its status, compute its next event time, insert that new event onto
the queue (being a time-ordered priority queue, the new event is
inserted at the proper time place, not just at the end). Instead, I'm
using a simple incrementing time and invoking each train with "now",
letting each train compute if the event time has been reached.


-=-=-=-=-=-=-=-
import time

class Station(object):
def __init__(self, name, waitTime):
#waitTime is in hours
self.name = name
self.waitTime = waitTime

class Route(object):
def __init__(self, name):
self.name = name
self.stations = []
def next(self, current):
to = (current + 1) % len(self.stations)
return to
def addStation(self, station):
self.stations.append(station)

class Train(object):
def __init__(self, name, speed, route, currentStation):
#speed is in distance-units per hour
self.name = name
self.speed = speed
self.route = route
self.station = currentStation
self.nextEventTime = 0
self.enroute = False
def update(self, time):
if (self.enroute
and (time >= self.nextEventTime)):
self.enroute = False
self.nextEventTime = (time
+ self.route.stations[
self.station].waitTime)
print ("%8s\t%-15s\tTrain %s arriving %s"
% (time,
self.route.name,
self.name,
self.route.stations[self.station].name))
elif (not self.enroute
and (time >= self.nextEventTime)):
self.enroute = True
currentStation = self.station
self.station = self.route.next(currentStation)
self.nextEventTime = (time
+ (globalMap[
(self.route.stations[currentStation],
self.route.stations[self.station]) ]
/ self.speed))
print ("%8s\t%-15s\tTrain %s departing %s for %s"
% (time,
self.route.name,
self.name,
self.route.stations[currentStation].name,
self.route.stations[self.station].name))
else:
pass

class Railroad(object):
def __init__(self, trains, time=0):
self.trains = trains
self.time = time
for train in self.trains:
train.time = self.time
def update(self, timeDelta=0.125):
#timeDelta is in hours.
self.time += timeDelta
for train in self.trains:
train.update(self.time)

############
# create a few stations

london = Station("London", 0.5)
paris = Station("Paris", 0.33)
moscow = Station("Moscow", 1.51)
athens = Station("Athens", 0.5)
rome = Station("Rome", 0.25)
madrid = Station("Madrid", 0.25)
beijing = Station("Beijing", 0.2)
mumbai = Station("Mumbai", 0.45)
berlin = Station("Berlin", 0.33)
edinburgh = Station("Edinburgh", 0.33)

# define world map (distance table); highly fictional data
globalMap = { (london, paris) : 500, (london, moscow) : 1250,
(london, athens) : 1000, (london, rome) : 750,
(london, madrid) : 750, (london, beijing) : 2500,
(london, mumbai) : 2000, (london, berlin) : 675,
(london, edinburgh) : 450,
(paris, moscow) : 750, (paris, athens) : 500,
(paris, rome) : 250, (paris, madrid): 250,
(paris, beijing) : 2000, (paris, mumbai) : 1500,
(paris, berlin) : 175, (paris, edinburgh) : 950,
(moscow, athens) : 750, (moscow, rome) : 1000,
(moscow, madrid) : 1500, (moscow, beijing) : 1250,
(moscow, mumbai) : 750, (moscow, berlin) : 750,
(moscow, edinburgh) : 1700,
(athens, rome) : 750, (athens, madrid) : 1000,
(athens, beijing) : 2000, (athens, mumbai) : 1000,
(athens, berlin) : 325, (athens, edinburgh) : 1450,
(rome, madrid) : 750, (rome, beijing) : 2250,
(rome, mumbai) : 1750, (rome, berlin) : 500,
(rome, edinburgh) : 1200,
(madrid, beijing) : 2500, (madrid, mumbai) : 1750,
(madrid, berlin) : 500, (madrid, edinburgh) : 1200,
(beijing, mumbai) : 800, (beijing, berlin) : 2250,
(beijing, edinburgh) : 2950,
(mumbai, berlin) : 1250, (mumbai, edinburgh) : 2450,
(berlin, edinburgh) : 1125 }

# create reverse mappings
for (frm, to) in globalMap.keys():
globalMap[ (to, frm) ] = globalMap[ (frm, to) ]

# create some routes; remember routes are cycles, the last city connects
to
# the first
orient = Route("Orient Express")
worldTour = Route("WorldTour")
euroZone = Route("Europe")

orient.addStation(paris)
orient.addStation(athens)
orient.addStation(moscow)
orient.addStation(mumbai)
orient.addStation(beijing)
orient.addStation(moscow)

worldTour.addStation(edinburgh)
worldTour.addStation(london)
worldTour.addStation(madrid)
worldTour.addStation(rome)
worldTour.addStation(athens)
worldTour.addStation(mumbai)
worldTour.addStation(beijing)
worldTour.addStation(moscow)
worldTour.addStation(berlin)
worldTour.addStation(paris)

euroZone.addStation(paris)
euroZone.addStation(madrid)
euroZone.addStation(rome)
euroZone.addStation(athens)
euroZone.addStation(berlin)

#create trains
wt = Train("World Tour", 75, worldTour, 0)
oe = Train("Orient Express", 125, orient, 0)
exp = Train("Morning Express", 150, euroZone, 0)
mc = Train("Morning Commute", 50, euroZone, 0)
ec = Train("Evening Commute", 50, euroZone, 3)

#create railroad
rr = Railroad([wt, oe, exp, mc, ec])

# start running
while True:
rr.update()
time.sleep(0.25)

-=-=-=-=-=-=-=-

Definitely not realistic... My "Orient Express" (Paris to Beijing and
back, passing through Moscow both ways) takes 42 "hours" for the
round-trip.

0.125 WorldTour Train World Tour departing Edinburgh for
London
0.125 Orient Express Train Orient Express departing Paris for
Athens
0.125 Europe Train Morning Express departing Paris for
Madrid
0.125 Europe Train Morning Commute departing Paris for
Madrid
0.125 Europe Train Evening Commute departing Athens for
Berlin
1.125 Europe Train Morning Express arriving Madrid
1.375 Europe Train Morning Express departing Madrid for
Rome
4.125 Orient Express Train Orient Express arriving Athens
4.625 Orient Express Train Orient Express departing Athens for
Moscow
5.125 Europe Train Morning Commute arriving Madrid
5.375 Europe Train Morning Commute departing Madrid for
Rome
6.125 WorldTour Train World Tour arriving London
6.125 Europe Train Evening Commute arriving Berlin
6.375 Europe Train Morning Express arriving Rome
6.5 Europe Train Evening Commute departing Berlin for
Paris
6.625 WorldTour Train World Tour departing London for Madrid
6.625 Europe Train Morning Express departing Rome for
Athens
9.5 Europe Train Evening Commute arriving Paris
9.875 Europe Train Evening Commute departing Paris for
Madrid
10.625 Orient Express Train Orient Express arriving Moscow
11.625 Europe Train Morning Express arriving Athens
12.125 Europe Train Morning Express departing Athens for
Berlin
12.25 Orient Express Train Orient Express departing Moscow for
Mumbai
14.125 Europe Train Morning Express arriving Berlin
14.5 Europe Train Morning Express departing Berlin for
Paris
14.875 Europe Train Evening Commute arriving Madrid
15.125 Europe Train Evening Commute departing Madrid for
Rome
15.5 Europe Train Morning Express arriving Paris
15.875 Europe Train Morning Express departing Paris for
Madrid
16.625 WorldTour Train World Tour arriving Madrid
16.875 WorldTour Train World Tour departing Madrid for Rome
16.875 Europe Train Morning Express arriving Madrid
17.125 Europe Train Morning Express departing Madrid for
Rome
18.25 Orient Express Train Orient Express arriving Mumbai
18.75 Orient Express Train Orient Express departing Mumbai for
Beijing
20.375 Europe Train Morning Commute arriving Rome
20.625 Europe Train Morning Commute departing Rome for
Athens
22.125 Europe Train Morning Express arriving Rome
22.375 Europe Train Morning Express departing Rome for
Athens
 
M

Mag Gam

Oh wow. You went beyond :)

Let me rewrite the example. I only want to calculate the wait time
which is basically the depart time minus the arrival time for multiple
days.

This is all on 1 station.

June 26, 2010:
Trian A, Arrived at 6:00AM, Depart at 9:00AM
Trian B, Arrived at 2:00AM, Depart at 2:30AM
Trian C, Arrived at 4:00AM, Depart at 4:30AM
Trian D, Arrived at 7:00AM, Depart at 9:00AM

June 27, 2010:
Trian A, Arrived at 6:00AM, Depart at 9:15AM
Trian B, Arrived at 2:00AM, Depart at 2:35AM
Trian C, Arrived at 4:00AM, Depart at 4:35AM
Trian D, Arrived at 6:40AM, Depart at 9:03AM


Let say I want to just display wait time (Depart-Arrived):
June 26, 2010
TrianA: 3:00:00
TrianB: 0:30:00
TrianC: 0:30:00
TrianD: 2:00:00

Total=6:00:00

and the same for June 27.

I have already built out the functions and the dictionaries, just
wondering how and where I can do it in OOP.






Thanks everyone for your responses. They were very useful and I am
glad I asked the question.

I think having a concrete example would help me better, lets say I have this.


Trian A, Arrived at 6:00AM Jun 25, Left at 8:00AM Jun 25
Trian B, Arrived at 2:00AM Jun 26, Left at 12:00AM Jun 26
Trian C, Arrived at 4:00AM Jun 2, Left at 11:00AM Jun 2
Trian D, Arrived at 7:00AM Jun 11, Left at 3:00AM Jun 11
       Arrived where? Left where? Especially as "Trian D" "left" four hours
before it "arrived"... said:
Does that look right? Lets say I want to figure out how long each
train waited on the platfor
       I'd probably model that as an attribute of a station/platform

       This doesn't quite answer your specific "how long" question (in
truth, I've got the reverse here -- each Station has a fixed "wait"
time, but the time is different for different stations).

       It also isn't a very well thought out example, I wrote it on the
fly. A better simulation would use callbacks into each train, and time
ordered queue of events. That way the main loop would basically consist
of pulling off the first (lowest time value) event -- set that time as
"now", invoke the callback passing "now" (which would activate the
method in the train that defined that event); the train would then put
out its status, compute its next event time, insert that new event onto
the queue (being a time-ordered priority queue, the new event is
inserted at the proper time place, not just at the end). Instead, I'm
using a simple incrementing time and invoking each train with "now",
letting each train compute if the event time has been reached.


-=-=-=-=-=-=-=-
import time

class Station(object):
   def __init__(self, name, waitTime):
       #waitTime is in hours
       self.name = name
       self.waitTime = waitTime

class Route(object):
   def __init__(self, name):
       self.name = name
       self.stations = []
   def next(self, current):
       to = (current + 1) % len(self.stations)
       return to
   def addStation(self, station):
       self.stations.append(station)

class Train(object):
   def __init__(self, name, speed, route, currentStation):
       #speed is in distance-units per hour
       self.name = name
       self.speed = speed
       self.route = route
       self.station = currentStation
       self.nextEventTime = 0
       self.enroute = False
   def update(self, time):
       if (self.enroute
           and (time >= self.nextEventTime)):
           self.enroute = False
           self.nextEventTime = (time
                                 + self.route.stations[
                                     self.station].waitTime)
           print ("%8s\t%-15s\tTrain %s arriving %s"
                  % (time,
                     self.route.name,
                     self.name,
                     self.route.stations[self.station].name))
       elif (not self.enroute
             and (time >= self.nextEventTime)):
           self.enroute = True
           currentStation = self.station
           self.station = self.route.next(currentStation)
           self.nextEventTime = (time
                                 + (globalMap[
 (self.route.stations[currentStation],
 self.route.stations[self.station]) ]
                                    / self.speed))
           print ("%8s\t%-15s\tTrain %s departing %s for %s"
                  % (time,
                     self.route.name,
                     self.name,
                     self.route.stations[currentStation].name,
                     self.route.stations[self.station].name))
       else:
           pass

class Railroad(object):
   def __init__(self, trains, time=0):
       self.trains = trains
       self.time = time
       for train in self.trains:
           train.time = self.time
   def update(self, timeDelta=0.125):
       #timeDelta is in hours.
       self.time += timeDelta
       for train in self.trains:
           train.update(self.time)

############
# create a few stations

london = Station("London", 0.5)
paris = Station("Paris", 0.33)
moscow = Station("Moscow", 1.51)
athens = Station("Athens", 0.5)
rome = Station("Rome", 0.25)
madrid = Station("Madrid", 0.25)
beijing = Station("Beijing", 0.2)
mumbai = Station("Mumbai", 0.45)
berlin = Station("Berlin", 0.33)
edinburgh = Station("Edinburgh", 0.33)

# define world map (distance table); highly fictional data
globalMap = {   (london, paris) : 500,      (london, moscow) : 1250,
               (london, athens) : 1000,    (london, rome) : 750,
               (london, madrid) : 750,     (london, beijing) : 2500,
               (london, mumbai) : 2000,    (london, berlin) : 675,
               (london, edinburgh) : 450,
               (paris, moscow) : 750,      (paris, athens) : 500,
               (paris, rome) : 250,        (paris, madrid): 250,
               (paris, beijing) : 2000,    (paris, mumbai) : 1500,
               (paris, berlin) : 175,      (paris, edinburgh) : 950,
               (moscow, athens) : 750,     (moscow, rome) : 1000,
               (moscow, madrid) : 1500,    (moscow, beijing) : 1250,
               (moscow, mumbai) : 750,     (moscow, berlin) : 750,
               (moscow, edinburgh) : 1700,
               (athens, rome) : 750,       (athens, madrid) : 1000,
               (athens, beijing) : 2000,   (athens, mumbai) : 1000,
               (athens, berlin) : 325,     (athens, edinburgh) : 1450,
               (rome, madrid) : 750,       (rome, beijing) : 2250,
               (rome, mumbai) : 1750,      (rome, berlin) : 500,
               (rome, edinburgh) : 1200,
               (madrid, beijing) : 2500,   (madrid, mumbai) : 1750,
               (madrid, berlin) : 500,     (madrid, edinburgh) : 1200,
               (beijing, mumbai) : 800,    (beijing, berlin) : 2250,
               (beijing, edinburgh) : 2950,
               (mumbai, berlin) : 1250,    (mumbai, edinburgh) : 2450,
               (berlin, edinburgh) : 1125  }

# create reverse mappings
for (frm, to) in globalMap.keys():
   globalMap[ (to, frm) ] = globalMap[ (frm, to) ]

# create some routes; remember routes are cycles, the last city connects
to
# the first
orient = Route("Orient Express")
worldTour = Route("WorldTour")
euroZone = Route("Europe")

orient.addStation(paris)
orient.addStation(athens)
orient.addStation(moscow)
orient.addStation(mumbai)
orient.addStation(beijing)
orient.addStation(moscow)

worldTour.addStation(edinburgh)
worldTour.addStation(london)
worldTour.addStation(madrid)
worldTour.addStation(rome)
worldTour.addStation(athens)
worldTour.addStation(mumbai)
worldTour.addStation(beijing)
worldTour.addStation(moscow)
worldTour.addStation(berlin)
worldTour.addStation(paris)

euroZone.addStation(paris)
euroZone.addStation(madrid)
euroZone.addStation(rome)
euroZone.addStation(athens)
euroZone.addStation(berlin)

#create trains
wt = Train("World Tour", 75, worldTour, 0)
oe = Train("Orient Express", 125, orient, 0)
exp = Train("Morning Express", 150, euroZone, 0)
mc = Train("Morning Commute", 50, euroZone, 0)
ec = Train("Evening Commute", 50, euroZone, 3)

#create railroad
rr = Railroad([wt, oe, exp, mc, ec])

# start running
while True:
   rr.update()
   time.sleep(0.25)

-=-=-=-=-=-=-=-

Definitely not realistic... My "Orient Express" (Paris to Beijing and
back, passing through Moscow both ways) takes 42 "hours" for the
round-trip.

   0.125       WorldTour       Train World Tour departing Edinburgh for
London
  0.125        Orient Express  Train Orient Express departing Paris for
Athens
  0.125        Europe          Train Morning Express departing Paris for
Madrid
  0.125        Europe          Train Morning Commute departing Paris for
Madrid
  0.125        Europe          Train Evening Commute departing Athens for
Berlin
  1.125        Europe          Train Morning Express arriving Madrid
  1.375        Europe          Train Morning Express departing Madrid for
Rome
  4.125        Orient Express  Train Orient Express arriving Athens
  4.625        Orient Express  Train Orient Express departing Athens for
Moscow
  5.125        Europe          Train Morning Commute arriving Madrid
  5.375        Europe          Train Morning Commute departing Madrid for
Rome
  6.125        WorldTour       Train World Tour arriving London
  6.125        Europe          Train Evening Commute arriving Berlin
  6.375        Europe          Train Morning Express arriving Rome
    6.5        Europe          Train Evening Commute departing Berlin for
Paris
  6.625        WorldTour       Train World Tour departing London for Madrid
  6.625        Europe          Train Morning Express departing Rome for
Athens
    9.5        Europe          Train Evening Commute arriving Paris
  9.875        Europe          Train Evening Commute departing Paris for
Madrid
 10.625        Orient Express  Train Orient Express arriving Moscow
 11.625        Europe          Train Morning Express arriving Athens
 12.125        Europe          Train Morning Express departing Athens for
Berlin
  12.25        Orient Express  Train Orient Express departing Moscow for
Mumbai
 14.125        Europe          Train Morning Express arriving Berlin
   14.5        Europe          Train Morning Express departing Berlin for
Paris
 14.875        Europe          Train Evening Commute arriving Madrid
 15.125        Europe          Train Evening Commute departing Madrid for
Rome
   15.5        Europe          Train Morning Express arriving Paris
 15.875        Europe          Train Morning Express departing Paris for
Madrid
 16.625        WorldTour       Train World Tour arriving Madrid
 16.875        WorldTour       Train World Tour departing Madrid for Rome
 16.875        Europe          Train Morning Express arriving Madrid
 17.125        Europe          Train Morning Express departing Madrid for
Rome
  18.25        Orient Express  Train Orient Express arriving Mumbai
  18.75        Orient Express  Train Orient Express departing Mumbai for
Beijing
 20.375        Europe          Train Morning Commute arriving Rome
 20.625        Europe          Train Morning Commute departing Rome for
Athens
 22.125        Europe          Train Morning Express arriving Rome
 22.375        Europe          Train Morning Express departing Rome for
Athens
 
D

Dennis Lee Bieber

Oh wow. You went beyond :)

Let me rewrite the example. I only want to calculate the wait time
which is basically the depart time minus the arrival time for multiple
days.

This is all on 1 station.

June 26, 2010:
Trian A, Arrived at 6:00AM, Depart at 9:00AM
Trian B, Arrived at 2:00AM, Depart at 2:30AM
Trian C, Arrived at 4:00AM, Depart at 4:30AM
Trian D, Arrived at 7:00AM, Depart at 9:00AM

June 27, 2010:
Trian A, Arrived at 6:00AM, Depart at 9:15AM
Trian B, Arrived at 2:00AM, Depart at 2:35AM
Trian C, Arrived at 4:00AM, Depart at 4:35AM
Trian D, Arrived at 6:40AM, Depart at 9:03AM


Let say I want to just display wait time (Depart-Arrived):
June 26, 2010
TrianA: 3:00:00
TrianB: 0:30:00
TrianC: 0:30:00
TrianD: 2:00:00

Total=6:00:00

and the same for June 27.

I have already built out the functions and the dictionaries, just
wondering how and where I can do it in OOP.

Sounds more like a database problem to me... Not really conducive to
OO.

Assumption: "Train" identifies ONE scheduled run per day (even if the
physical engine/car set makes multiple runs -- just like airline
"flights" have unique numbers even if the plane is just jumping back and
forth between two close-by cities).

Note: this will make the /end points/ difficult to work with, as the
"Train" changes when it turns the other way unless you track by, say,
engine number too, or instead of run (but then have to isolate multiple
runs); let's try by engine number...

Simple single table schema (Date Time used as an Engine may arrive
at 23:50, and depart 00:20 the next day){warning, I'm doing this off the
top of my head -- without bringing up SQLite to test}:

create table PlatformTimes
(
ID integer autoincrement primary key,
Station whatevertype not null,
Engine whatevertype not null,
ArrivalDateTime datetime not null,
DepartureDateTime datetime default null
)

On arrival SQL (insert new record recording the arrival time of this
engine):

insert into PlatformTimes (Station, Engine, ArrivalDateTime)
values (<whatever>, <whatever>, now() )

On departure SQL (find the most recent incomplete [no departure]
record for this engine, then set the departure time for that record):

update PlatformTimes set
DepartureDateTime = now()
where ID in (select ID from PlatformTimes
where Station = <whatever>
and Engine = <whatever>
and DepartureDateTime is null
order by ArrivalDateTime desc
limit 1)

{the order by and limit clauses may not be needed, if only the most
recent arrival record has a null departure time}

Wait times SQL (extract station/engine/departure time, and the
difference between departure and arrival times):

select Station, Engine, DepartureDateTime,
(DepartureDateTime - ArrivalDateTime) as "WaitTime"
from PlatformTimes
where DepartureDateTime is not null
order by Station, Engine, DepartureDateTime

Now, if one were to use some framework -- SQLAlchemy, SQL Object,
maybe Dabo (I don't recall if it wraps SQLAlchemy/Object or uses its own
methods) -- those frameworks will treat each record as an instance, in
which the table definition is the "class".

Given just your requirements, the nearest thing to an object/class
is the platform time record for a train -- not the train itself.

class PlatformTrain(object): #I'm still on v2.5
def __init__(self, station, engine):
self.station = station
self.engine = engine
self.arrival = datetime.datetime.now() #untested
self.departure = None
def departed(self):
if self.departure is not None:
raise "Usage Error -- this train has already departed"
else:
self.departure = datetime.datetime.now()
def platformWait(self):
if self.departure is None:
raise "Usage Error -- this train has not departed"
else:
return self.departure - self.arrival

When a train arrives:

newarrival = PlatformTrain(somestation, trainID)

Now -- you will have to figure out what structure to save the list of
records in, and how to search it for the record when a train departs...
All things the SQL database took care of.

newarrival.departed() #sets the departure time (the record probably
won't be "newarrival" in this part of the application

timeatplatform = newarrival.platformWait() #similar comment
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,226
Members
46,815
Latest member
treekmostly22

Latest Threads

Top