溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

如何使用Jupyter改善時(shí)間管理

發(fā)布時(shí)間:2021-10-15 14:23:38 來(lái)源:億速云 閱讀:130 作者:iii 欄目:編程語(yǔ)言

本篇內(nèi)容介紹了“如何使用Jupyter改善時(shí)間管理”的有關(guān)知識(shí),在實(shí)際案例的操作過(guò)程中,不少人都會(huì)遇到這樣的困境,接下來(lái)就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

Python 在探索數(shù)據(jù)方面具有令人難以置信的可擴(kuò)展性。利用 Pandas 或 Dask,你可以將 Jupyter 擴(kuò)展到大數(shù)據(jù)領(lǐng)域。但是小數(shù)據(jù)、個(gè)人資料、私人數(shù)據(jù)呢?

JupyterLab 和 Jupyter Notebook 為我提供了一個(gè)絕佳的環(huán)境,可以讓我審視我的筆記本電腦生活。

我的探索是基于以下事實(shí):我使用的幾乎每個(gè)服務(wù)都有一個(gè) Web API。我使用了諸多此類服務(wù):待辦事項(xiàng)列表、時(shí)間跟蹤器、習(xí)慣跟蹤器等。還有一個(gè)幾乎每個(gè)人都會(huì)使用到:日歷。相同的思路也可以應(yīng)用于其他服務(wù),但是日歷具有一個(gè)很酷的功能:幾乎所有 Web 日歷都支持的開放標(biāo)準(zhǔn) —— CalDAV。

在 Jupyter 中使用 Python 解析日歷

大多數(shù)日歷提供了導(dǎo)出為 CalDAV 格式的方法。你可能需要某種身份驗(yàn)證才能訪問(wèn)這些私有數(shù)據(jù)。按照你的服務(wù)說(shuō)明進(jìn)行操作即可。如何獲得憑據(jù)取決于你的服務(wù),但是最終,你應(yīng)該能夠?qū)⑦@些憑據(jù)存儲(chǔ)在文件中。我將我的憑據(jù)存儲(chǔ)在根目錄下的一個(gè)名為 .caldav 的文件中:

import oswith open(os.path.expanduser("~/.caldav")) as fpin:    username, password = fpin.read().split()

切勿將用戶名和密碼直接放在 Jupyter Notebook 的筆記本中!它們可能會(huì)很容易因 git push 的錯(cuò)誤而導(dǎo)致泄漏。

下一步是使用方便的 PyPI caldav 庫(kù)。我找到了我的電子郵件服務(wù)的 CalDAV 服務(wù)器(你可能有所不同):

import caldavclient = caldav.DAVClient(url="https://caldav.fastmail.com/dav/", username=username, password=password)

CalDAV 有一個(gè)稱為 principal(主鍵)的概念。它是什么并不重要,只要知道它是你用來(lái)訪問(wèn)日歷的東西就行了:

principal = client.principal()calendars = principal.calendars()

從字面上講,日歷就是關(guān)于時(shí)間的。訪問(wèn)事件之前,你需要確定一個(gè)時(shí)間范圍。默認(rèn)一星期就好:

from dateutil import tzimport datetimenow = datetime.datetime.now(tz.tzutc())since = now - datetime.timedelta(days=7)

大多數(shù)人使用的日歷不止一個(gè),并且希望所有事件都在一起出現(xiàn)。itertools.chain.from_iterable 方法使這一過(guò)程變得簡(jiǎn)單:

import itertools raw_events = list(    itertools.chain.from_iterable(        calendar.date_search(start=since, end=now, expand=True)        for calendar in calendars    ))

將所有事件讀入內(nèi)存很重要,以 API 原始的本地格式進(jìn)行操作是重要的實(shí)踐。這意味著在調(diào)整解析、分析和顯示代碼時(shí),無(wú)需返回到 API 服務(wù)刷新數(shù)據(jù)。

但 “原始” 真的是原始,事件是以特定格式的字符串出現(xiàn)的:

print(raw_events[12].data)
    BEGIN:VCALENDAR    VERSION:2.0    PRODID:-//CyrusIMAP.org/Cyrus     3.3.0-232-g4bdb081-fm-20200825.002-g4bdb081a//EN    BEGIN:VEVENT    DTEND:20200825T230000Z    DTSTAMP:20200825T181915Z    DTSTART:20200825T220000Z    SUMMARY:Busy    UID:     1302728i-040000008200E00074C5B7101A82E00800000000D939773EA578D601000000000     000000010000000CD71CC3393651B419E9458134FE840F5    END:VEVENT    END:VCALENDAR

幸運(yùn)的是,PyPI 可以再次使用另一個(gè)輔助庫(kù) vobject 解圍:

import ioimport vobject def parse_event(raw_event):    data = raw_event.data    parsed = vobject.readOne(io.StringIO(data))    contents = parsed.vevent.contents    return contents
parse_event(raw_events[12])
    {'dtend': [<DTEND{}2020-08-25 23:00:00+00:00>],     'dtstamp': [<DTSTAMP{}2020-08-25 18:19:15+00:00>],     'dtstart': [<DTSTART{}2020-08-25 22:00:00+00:00>],     'summary': [<SUMMARY{}Busy>],     'uid': [<UID{}1302728i-040000008200E00074C5B7101A82E00800000000D939773EA578D601000000000000000010000000CD71CC3393651B419E9458134FE840F5>]}

好吧,至少好一點(diǎn)了。

仍有一些工作要做,將其轉(zhuǎn)換為合理的 Python 對(duì)象。第一步是 擁有 一個(gè)合理的 Python 對(duì)象。attrs 庫(kù)提供了一個(gè)不錯(cuò)的開始:

import attrfrom __future__ import annotations@attr.s(auto_attribs=True, frozen=True)class Event:    start: datetime.datetime    end: datetime.datetime    timezone: Any    summary: str

是時(shí)候編寫轉(zhuǎn)換代碼了!

第一個(gè)抽象從解析后的字典中獲取值,不需要所有的裝飾:

def get_piece(contents, name):    return contents[name][0].valueget_piece(_, "dtstart")    datetime.datetime(2020, 8, 25, 22, 0, tzinfo=tzutc())

日歷事件總有一個(gè)“開始”、有一個(gè)“結(jié)束”、有一個(gè) “持續(xù)時(shí)間”。一些謹(jǐn)慎的解析邏輯可以將兩者協(xié)調(diào)為同一個(gè) Python 對(duì)象:

def from_calendar_event_and_timezone(event, timezone):    contents = parse_event(event)    start = get_piece(contents, "dtstart")    summary = get_piece(contents, "summary")    try:        end = get_piece(contents, "dtend")    except KeyError:        end = start + get_piece(contents, "duration")    return Event(start=start, end=end, summary=summary, timezone=timezone)

將事件放在 本地 時(shí)區(qū)而不是 UTC 中很有用,因此使用本地時(shí)區(qū):

my_timezone = tz.gettz()from_calendar_event_and_timezone(raw_events[12], my_timezone)    Event(start=datetime.datetime(2020, 8, 25, 22, 0, tzinfo=tzutc()), end=datetime.datetime(2020, 8, 25, 23, 0, tzinfo=tzutc()), timezone=tzfile('/etc/localtime'), summary='Busy')

既然事件是真實(shí)的 Python 對(duì)象,那么它們實(shí)際上應(yīng)該具有附加信息。幸運(yùn)的是,可以將方法添加到類中。

但是要弄清楚哪個(gè)事件發(fā)生在哪一天不是很直接。你需要在 本地 時(shí)區(qū)中選擇一天:

def day(self):    offset = self.timezone.utcoffset(self.start)    fixed = self.start + offset    return fixed.date()Event.day = property(day)
print(_.day)    2020-08-25

事件在內(nèi)部始終是以“開始”/“結(jié)束”的方式表示的,但是持續(xù)時(shí)間是有用的屬性。持續(xù)時(shí)間也可以添加到現(xiàn)有類中:

def duration(self):    return self.end - self.startEvent.duration = property(duration)
print(_.duration)    1:00:00

現(xiàn)在到了將所有事件轉(zhuǎn)換為有用的 Python 對(duì)象了:

all_events = [from_calendar_event_and_timezone(raw_event, my_timezone)              for raw_event in raw_events]

全天事件是一種特例,可能對(duì)分析生活沒(méi)有多大用處。現(xiàn)在,你可以忽略它們:

# ignore all-day eventsall_events = [event for event in all_events if not type(event.start) == datetime.date]

事件具有自然順序 &mdash;&mdash; 知道哪個(gè)事件最先發(fā)生可能有助于分析:

all_events.sort(key=lambda ev: ev.start)

現(xiàn)在,事件已排序,可以將它們加載到每天:

import collectionsevents_by_day = collections.defaultdict(list)for event in all_events:    events_by_day[event.day].append(event)

有了這些,你就有了作為 Python 對(duì)象的帶有日期、持續(xù)時(shí)間和序列的日歷事件。

用 Python 報(bào)到你的生活

現(xiàn)在是時(shí)候編寫報(bào)告代碼了!帶有適當(dāng)?shù)臉?biāo)題、列表、重要內(nèi)容以粗體顯示等等,有醒目的格式是很意義。

這就是一些 HTML 和 HTML 模板。我喜歡使用 Chameleon:

template_content = """<html><body><div tal:repeat="item items"><h3 tal:content="item[0]">Day</h3><ul>    <li tal:repeat="event item[1]"><span tal:replace="event">Thing</span></li></ul></div></body></html>"""

Chameleon 的一個(gè)很酷的功能是使用它的 html 方法渲染對(duì)象。我將以兩種方式使用它:

  • 摘要將以粗體顯示

  • 對(duì)于大多數(shù)活動(dòng),我都會(huì)刪除摘要(因?yàn)檫@是我的個(gè)人信息)

def __html__(self):    offset = my_timezone.utcoffset(self.start)    fixed = self.start + offset    start_str = str(fixed).split("+")[0]    summary = self.summary    if summary != "Busy":        summary = "&lt;REDACTED&gt;"    return f"<b>{summary[:30]}</b> -- {start_str} ({self.duration})"Event.__html__ = __html__

為了簡(jiǎn)潔起見(jiàn),將該報(bào)告切成每天的:

import chameleonfrom IPython.display import HTMLtemplate = chameleon.PageTemplate(template_content)html = template(items=itertools.islice(events_by_day.items(), 3, 4))HTML(html)

渲染后,它將看起來(lái)像這樣:

2020-08-25

  • <REDACTED> -- 2020-08-25 08:30:00 (0:45:00)

  • <REDACTED> -- 2020-08-25 10:00:00 (1:00:00)

  • <REDACTED> -- 2020-08-25 11:30:00 (0:30:00)

  • <REDACTED> -- 2020-08-25 13:00:00 (0:25:00)

  • Busy -- 2020-08-25 15:00:00 (1:00:00)

  • <REDACTED> -- 2020-08-25 15:00:00 (1:00:00)

  • <REDACTED> -- 2020-08-25 19:00:00 (1:00:00)

  • <REDACTED> -- 2020-08-25 19:00:12 (1:00:00)

“如何使用Jupyter改善時(shí)間管理”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI