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 return not self.is_good()
81 def __eq__(self, rhs):
82 return self._value == rhs._value
84 def __ne__(self, rhs):
85 return self._value != rhs._value
87 def __lt__(self, rhs):
88 return self._value < rhs._value
90 def __le__(self, rhs):
91 return self._value <= rhs._value
93 def __gt__(self, rhs):
94 return self._value > rhs._value
96 def __ge__(self, rhs):
97 return self._value >= rhs._value
100 def open_anything(source, alternative=None):
101 """URI, filename, or string --> stream
103 This function lets you define parsers that take any input source
104 (URL, pathname to local or network file, or actual data as a string)
105 and deal with it in a uniform manner. Returned object is guaranteed
106 to have all the basic stdio read methods (read, readline, readlines).
107 Just .close() the object when you're done with it.
109 if hasattr(source, "read"):
115 # try to open with urllib (if source is http, ftp, or file URL)
117 return urllib.urlopen(source)
118 except (IOError, OSError):
120 print "ERROR with URL ("+source+")!\n"
122 # try to open with native open function (if source is pathname)
125 except (IOError, OSError):
127 print "ERROR with file!\n"
129 # treat source as string
130 if alternative == None:
131 print 'LAST RESORT. String is "'+source+'"\n'
132 return StringIO.StringIO(str(source))
134 print 'LAST RESORT. String is "'+alternative+'"\n'
135 return StringIO.StringIO(str(alternative))
138 def load_xml(source, alternative=None):
139 """load XML input source, return parsed XML document
141 - a URL of a remote XML file ("http://diveintopython.org/kant.xml")
142 - a filename of a local XML file ("~/diveintopython/common/py/kant.xml")
143 - standard input ("-")
144 - the actual XML document, as a string
146 sock = open_anything(source, alternative)
148 xmldoc = minidom.parse(sock).documentElement
149 except (IOError, OSError):
150 print "ERROR with data"
152 sock = open_anything('<response method="getProjects"><project projName="ERROR!"/></response>')
153 xmldoc = minidom.parse(sock).documentElement
158 def is_same_year(targetDate, todaysDate = datetime.datetime.today()):
159 return targetDate.year == todaysDate.year
162 def is_same_month(targetDate, todaysDate = datetime.datetime.today()):
163 return targetDate.month == todaysDate.month
166 def is_same_day(targetDate, todaysDate = datetime.datetime.today()):
167 return targetDate.day == todaysDate.day
170 def to_fuzzy_date(targetDate, todaysDate = datetime.datetime.today()):
172 Conert a date/time/datetime object to a fuzzy date
174 >>> todaysDate = datetime.date(2009, 4, 16)
175 >>> to_fuzzy_date(datetime.date(1, 4, 6), todaysDate)
177 >>> to_fuzzy_date(datetime.date(2008, 4, 13), todaysDate)
179 >>> to_fuzzy_date(datetime.date(2009, 4, 13), todaysDate)
181 >>> to_fuzzy_date(datetime.date(2009, 4, 20), todaysDate)
183 >>> to_fuzzy_date(datetime.date(2010, 4, 13), todaysDate)
185 >>> to_fuzzy_date(datetime.date(2012, 12, 12), todaysDate)
188 delta = targetDate - todaysDate
189 days = abs(delta.days)
190 noDifference = datetime.timedelta()
191 isFuture = noDifference < delta
192 directionBy1 = "Next" if isFuture else "Last"
193 directionByN = "Later" if isFuture else "Earlier"
195 yearDelta = abs(targetDate.year - todaysDate.year)
197 directionByInf = "from now" if isFuture else "ago"
198 return "Forever %s" % directionByInf
200 return "%s year" % directionBy1
202 monthDelta = abs(targetDate.month - todaysDate.month)
204 return "%s this year" % directionByN
205 elif 1 == monthDelta:
206 return "%s month" % directionBy1
208 dayDelta = abs(targetDate.day - todaysDate.day)
210 return "%s this month" % directionByN
212 directionInWeek = "This" if isFuture else "Last"
213 days = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]
214 return "%s %s" % (directionInWeek, days[targetDate.weekday()])
216 return "%s day" % directionBy1