4 from xml.dom import minidom
8 class Optional(object):
11 Even you don't have to worry about knowing when to perform None checks
12 When the NULL object pattern just isn't good enough
17 >>> a.get_nothrow("Blacksheep")
22 >>> a.get_nothrow("Blacksheep"), a.get(), a()
23 ('Lamb', 'Lamb', 'Lamb')
27 >>> a.get_nothrow("Blacksheep")
30 >>> b = Optional("Lamb")
34 >>> a.get_nothrow("Blacksheep"), a.get(), a()
35 ('Lamb', 'Lamb', 'Lamb')
39 >>> a.get_nothrow("Blacksheep")
43 class NonExistent(object):
46 def __init__(self, value = NonExistent):
53 self._value = self.NonExistent
56 return self._value is not self.NonExistent
58 def get_nothrow(self, default = None):
59 return self._value if self.is_good() else default
62 if not self.is_good():
63 raise ReferenceError("Optional not initialized")
67 # Implemented to imitate weakref
71 return str(self.get_nothrow(""))
74 return "<Optional at %x; to %r>" % (
75 id(self), self.get_nothrow("Nothing")
79 def open_anything(source, alternative=None):
80 """URI, filename, or string --> stream
82 This function lets you define parsers that take any input source
83 (URL, pathname to local or network file, or actual data as a string)
84 and deal with it in a uniform manner. Returned object is guaranteed
85 to have all the basic stdio read methods (read, readline, readlines).
86 Just .close() the object when you're done with it.
88 if hasattr(source, "read"):
94 # try to open with urllib (if source is http, ftp, or file URL)
96 return urllib.urlopen(source)
97 except (IOError, OSError):
99 print "ERROR with URL ("+source+")!\n"
101 # try to open with native open function (if source is pathname)
104 except (IOError, OSError):
106 print "ERROR with file!\n"
108 # treat source as string
109 if alternative == None:
110 print 'LAST RESORT. String is "'+source+'"\n'
111 return StringIO.StringIO(str(source))
113 print 'LAST RESORT. String is "'+alternative+'"\n'
114 return StringIO.StringIO(str(alternative))
117 def load_xml(source, alternative=None):
118 """load XML input source, return parsed XML document
120 - a URL of a remote XML file ("http://diveintopython.org/kant.xml")
121 - a filename of a local XML file ("~/diveintopython/common/py/kant.xml")
122 - standard input ("-")
123 - the actual XML document, as a string
125 sock = open_anything(source, alternative)
127 xmldoc = minidom.parse(sock).documentElement
128 except (IOError, OSError):
129 print "ERROR with data"
131 sock = open_anything('<response method="getProjects"><project projName="ERROR!"/></response>')
132 xmldoc = minidom.parse(sock).documentElement
137 def is_same_year(targetDate, todaysDate = datetime.datetime.today()):
138 return targetDate.year == todaysDate.year
141 def is_same_month(targetDate, todaysDate = datetime.datetime.today()):
142 return targetDate.month == todaysDate.month
145 def is_same_day(targetDate, todaysDate = datetime.datetime.today()):
146 return targetDate.day == todaysDate.day
149 def to_fuzzy_date(targetDate, todaysDate = datetime.datetime.today()):
151 Conert a date/time/datetime object to a fuzzy date
153 >>> todaysDate = datetime.date(2009, 4, 16)
154 >>> to_fuzzy_date(datetime.date(1, 4, 6), todaysDate)
156 >>> to_fuzzy_date(datetime.date(2008, 4, 13), todaysDate)
158 >>> to_fuzzy_date(datetime.date(2009, 4, 13), todaysDate)
160 >>> to_fuzzy_date(datetime.date(2009, 4, 20), todaysDate)
162 >>> to_fuzzy_date(datetime.date(2010, 4, 13), todaysDate)
164 >>> to_fuzzy_date(datetime.date(2012, 12, 12), todaysDate)
167 delta = targetDate - todaysDate
168 days = abs(delta.days)
169 noDifference = datetime.timedelta()
170 isFuture = noDifference < delta
171 directionBy1 = "Next" if isFuture else "Last"
172 directionByN = "Later" if isFuture else "Earlier"
174 yearDelta = abs(targetDate.year - todaysDate.year)
176 directionByInf = "from now" if isFuture else "ago"
177 return "Forever %s" % directionByInf
179 return "%s year" % directionBy1
181 monthDelta = abs(targetDate.month - todaysDate.month)
183 return "%s this year" % directionByN
184 elif 1 == monthDelta:
185 return "%s month" % directionBy1
187 dayDelta = abs(targetDate.day - todaysDate.day)
189 return "%s this month" % directionByN
191 directionInWeek = "This" if isFuture else "Last"
192 days = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]
193 return "%s %s" % (directionInWeek, days[targetDate.weekday()])
195 return "%s day" % directionBy1