From 1cba94114d1ef58e149dfde9a11864e46491fc1c Mon Sep 17 00:00:00 2001 From: David Arcos Date: Thu, 15 Oct 2026 10:01:15 +0200 Subject: [PATCH 1/7] Read the schedule from a grid and a list of talks, not from one list An event page used to carry one list, events, with every fact of a session in each row: the time, the room, the colour, the title, the speaker as free text, the description, and the links. It now carries three: rooms (id and name), talks (the content: title, speakers, description, language, topic, duration_minutes, links) and agenda (the grid: start, track_length, room, and a talk id or its own label and type). They are separate because one talk can take more than one slot, and because a photo or a page can point at a talk by id, which a row of a grid cannot give it. partials/agenda_entry.html is the join, in one place, so the block of the grid and the modal behind it cannot disagree. It also computes what the page used to store: the colour, one per room of the day from the palette agenda.scss defines, and the end of a slot, from its start and the length of what fills it. speakers is a list of person ids and the name printed is the one the record holds; the free-text speaker field is gone. language is a code, en, es or ca, or a list of them written in that order. Also in this change: partials/event_types.html gains keynote and panel, and the singular and plural noun of each type; partials/event_type_icon.html can draw a named icon, with the label as its accessible name, for a row that prints nothing else about the type; partials/video_link.html prints a link to a video with the mark of its host in front, and the modal behind a block of the grid prints the video of a session through it. The block itself prints no link: a link belongs on a row and a player on a page about one talk, and a block of the grid is neither. partials/people_names.html and partials/speaker_names.html resolve person ids to names once per build. The modal lists the repositories of a talk as a list of links, no longer one string with raw HTML in it. partials/link_mark.html is the one mark per link destination the site prints. The host of the URL picks the glyph: YouTube, GitHub, GitLab, Bitbucket, SlideShare, Speaker Deck, Flickr, Google Drive, LinkedIn, Meetup, X, or a generic arrow for any other host. It is grey at rest like every other icon of the site (.link_mark in main.scss) and hidden from a screen reader, because the words beside it name the destination. video_link.html prints its mark through it, and so does the link render hook, layouts/_default/_markup/render-link.html, so an external link in the body of a page carries the same mark as one a template writes. --- layouts/_default/_markup/render-link.html | 10 +- themes/pybcn_theme/assets/scss/agenda.scss | 37 ++++ themes/pybcn_theme/assets/scss/main.scss | 23 ++ .../pybcn_theme/layouts/partials/agenda.html | 95 +++++++-- .../layouts/partials/agenda_entry.html | 196 ++++++++++++++++++ .../layouts/partials/event_detail.html | 25 ++- .../layouts/partials/event_type_icon.html | 28 ++- .../layouts/partials/event_types.html | 28 +-- .../layouts/partials/link_mark.html | 64 ++++++ .../layouts/partials/people_names.html | 33 +++ .../layouts/partials/speaker_names.html | 25 +++ .../layouts/partials/video_link.html | 45 ++++ 12 files changed, 577 insertions(+), 32 deletions(-) create mode 100644 themes/pybcn_theme/layouts/partials/agenda_entry.html create mode 100644 themes/pybcn_theme/layouts/partials/link_mark.html create mode 100644 themes/pybcn_theme/layouts/partials/people_names.html create mode 100644 themes/pybcn_theme/layouts/partials/speaker_names.html create mode 100644 themes/pybcn_theme/layouts/partials/video_link.html diff --git a/layouts/_default/_markup/render-link.html b/layouts/_default/_markup/render-link.html index 6a2a249fe..981ea6bdb 100644 --- a/layouts/_default/_markup/render-link.html +++ b/layouts/_default/_markup/render-link.html @@ -23,4 +23,12 @@ escaping: a quote in a link title came back as \" , which closes the attribute early and leaves the rest of the title as stray attribute names. */ -}} -{{ .Text }} \ No newline at end of file +{{- /* + An external link in the body of a page carries the same mark as one a + template writes, through partials/link_mark.html: every link that leaves + this site says where it goes (David Arcos, 2026-10-15). He found the gap + on the page of PyData Barcelona 2017, whose body links a YouTube playlist + and a Flickr album, and neither had a mark: the marks had reached the + templates and not the prose. +*/ -}} +{{ if $external }}{{ partial "link_mark.html" .Destination }}{{ end }}{{ .Text }} \ No newline at end of file diff --git a/themes/pybcn_theme/assets/scss/agenda.scss b/themes/pybcn_theme/assets/scss/agenda.scss index 8c06ef0e6..a70d5f4fd 100644 --- a/themes/pybcn_theme/assets/scss/agenda.scss +++ b/themes/pybcn_theme/assets/scss/agenda.scss @@ -98,6 +98,31 @@ $blockTimes15: 700,715,730,745,800,815,830,845,900,915,930,945,1000,1015,1030,10 } } + /* + The title of a row that holds a talk goes to the page of that + talk. Underlined, so it reads as a link before the pointer + reaches it: colour alone cannot say it here, because the whole + block is one colour and the title takes the same white or dark + text as the rest of it. WCAG 1.4.1 asks for a second mark, and + the underline is the mark a link takes everywhere else on this + site (see .photo_source in photo_gallery.scss). + + The type icon sits inside the link and is made an + inline-block, so the underline is not drawn through it: a + propagated text decoration does not cross an atomic + inline-level box, which is the same mechanism that keeps the + rule off .icon_x in the gallery credit. text-decoration: none + on the glyph would do nothing, because the rule belongs to the + anchor and not to the child. + */ + .agenda_talk_link { + text-decoration: underline; + + i { + display: inline-block; + } + } + span { display: block; width: 100%; @@ -107,8 +132,20 @@ $blockTimes15: 700,715,730,745,800,815,830,845,900,915,930,945,1000,1015,1030,10 color: white; } + // The video of the session, through partials/video_link.html: the + // mark is inside the link, and made an inline-block so the + // underline of the link stops at the words, as .agenda_talk_link + // does with the type icon above. .event_video { margin-top: 5%; + + a { + text-decoration: underline; + } + + i { + display: inline-block; + } } /* diff --git a/themes/pybcn_theme/assets/scss/main.scss b/themes/pybcn_theme/assets/scss/main.scss index f3582d450..dfba25ace 100644 --- a/themes/pybcn_theme/assets/scss/main.scss +++ b/themes/pybcn_theme/assets/scss/main.scss @@ -32,6 +32,29 @@ $primary: $blue-pybcn; mask-size: contain; } +// The mark of a link that leaves the site, printed by +// partials/link_mark.html in front of the words of the link: the YouTube +// mark, the GitHub mark, the X mark above, or the generic arrow. Grey at +// rest, the $icon-grey of every icon of the site, and the colour of the +// link under the pointer or the keyboard, which is the rule the social +// glyphs of a person card follow. The YouTube mark took the blue of the +// link around it until 2026-10-15 while every other icon was grey; David +// Arcos asked for one colour. An inline-block, so the underline of the +// link stops at the words and is not drawn through the glyph. The gap is +// the one the credit of a gallery photo and the video line of a talk row +// already set. +.link_mark { + display: inline-block; + margin-right: 0.4rem; + color: $icon-grey; + transition: color 0.15s linear; +} + +a:hover .link_mark, +a:focus .link_mark { + color: inherit; +} + .semitransparent { background-color: rgba(0, 0, 0, 0.5); padding: 10px; diff --git a/themes/pybcn_theme/layouts/partials/agenda.html b/themes/pybcn_theme/layouts/partials/agenda.html index cd4223a8b..d7d3d03bc 100644 --- a/themes/pybcn_theme/layouts/partials/agenda.html +++ b/themes/pybcn_theme/layouts/partials/agenda.html @@ -21,6 +21,30 @@ {{ partial "agenda_legend.html" .legend }} +{{- /* The talks and the rooms of this page by id, so a slot of the agenda + finds its own and nothing else. Same join as photo_gallery.html. + + One colour per room as well, taken in the order the grid first names + them and kept for the whole day. See agenda_entry.html. */ -}} +{{- $talks := dict -}} +{{- range $talk := .talks -}} + {{- with $talk.id }}{{ $talks = merge $talks (dict . $talk) }}{{ end -}} +{{- end -}} +{{- /* The name of every person record, by id, so a talk that credits a + speaker by id prints the name the record holds. Same join as + photo_gallery.html and people-grid.html: the person files are read + from site.Pages, as they were when they built no page. Built once + per event page and passed down, rather than once per slot. */ -}} +{{- $people := dict -}} +{{- range $person := where .Site.Pages "Section" "people" -}} + {{- with $person.Params.id }}{{ $people = merge $people (dict . $person.Params.name) }}{{ end -}} +{{- end -}} +{{- $rooms := dict -}} +{{- $colors := dict -}} +{{- $palette := slice "purple" "blue" "yellow" "red" "orange" "grey" "green" "pink" -}} +{{- range $position, $room := .rooms -}} + {{- with $room.id }}{{ $rooms = merge $rooms (dict . $room) }}{{ $colors = merge $colors (dict . (index $palette (mod $position (len $palette)))) }}{{ end -}} +{{- end }}
@@ -28,31 +52,71 @@
{{$time}}
{{ end }} - {{ range $index, $event := .events }} + {{- $numTracks := int .numTracks -}} + {{ range $index, $slot := .agenda }} + {{- $event := partial "agenda_entry.html" (dict "slot" $slot "talks" $talks "rooms" $rooms "colors" $colors "people" $people "event_url" $.event_url) }} {{/* A title that is not in English gets a lang attribute, so a screen reader reads it with the right voice. The language field is the language of the talk, not of the title, so the attribute comes only from title_lang. See partials/title_lang.html. */}} {{ $title_lang := partial "title_lang.html" $event }} -
- + {{- /* A slot that spans every track is a banner: the registration, a + break, the lunch, or a closing session that fills the room. Its + text is centred. The retired "class: middle" said the same by + hand, on 46 of the 54 rows that span the full width, so the + other 8 sat left-aligned for no reason. Width is the rule, not + whether the row holds a talk: the closing session of 2025 is a + talk, spans every track, and was centred. */ -}} + {{- $banner := ge (int $event.track_length) $numTracks -}} +
+ + {{/* Two actions on one block, and each one does a different thing: + the plus icon opens the detail of this session in place, and the + title goes to the page of the talk. They are separated rather + than merged because they are not the same answer. The modal is + the quick look at the row the reader is standing on, and it is + the only place this site prints the fields that belong to the + slot and not to the talk: requirements, which 69 of the 179 + rows of the archive carry. The page of the talk is the record + itself, with a URL to share, the photo of the day, the links + the speaker published, and no script needed to read it. + + The title used to be a second trigger of the same modal, so the + block had one action written twice: that is why the plus icon + carried tabindex="-1" and sat outside the tab order. The title + is a link now, so the icon is the only way to the modal and + takes its place in the tab order back. Each control has its own + accessible name, "Details of " on the icon and the title + on the link, so a block of the grid is two tab stops that read + as two different destinations. + + A row with no talk keeps exactly what it had. No such row of + the archive carries a description today, so none of them opens + a modal, but the branch stays correct if one ever does. */}} {{ if $event.description }} - <button type="button" class="detail_link modal_trigger" tabindex="-1" data-toggle="modal" data-target="#modal_{{ $index }}" aria-label="Details of {{ $event.title }}"> + <button type="button" class="detail_link modal_trigger" data-toggle="modal" data-target="#modal_{{ $index }}" aria-label="Details of {{ $event.title }}"> <i class="fas fa-plus-square" aria-hidden="true"></i> </button> {{ end }} <h3> - {{/* The button opens before the icon, so the button box holds the - whole line and the title wraps as it did before. */}} - {{ if $event.description }} + {{/* The wrapper opens before the icon, so the box holds the + whole line and the title wraps as it did before. The link + wins over the button when the talk has a page: a reader who + follows the title gets the whole record, which is more than + the modal holds. */}} + {{ if $event.url }} + <a class="agenda_talk_link" href="{{ $event.url }}"> + {{ else if $event.description }} <button type="button" class="modal_trigger" data-toggle="modal" data-target="#modal_{{ $index }}"> {{ end }} {{ partial "event_type_icon.html" $event.type }} {{ with $title_lang }}<span lang="{{ . }}">{{ $event.title }}</span>{{ else }}{{ $event.title }}{{ end }} - {{ if $event.description }} + {{ if $event.url }} + </a> + {{ else if $event.description }} </button> {{ end }} </h3> @@ -68,10 +132,10 @@ <h3> {{ end }} - {{ with $event.location }} + {{ with $event.room }} <br/><span class="event_topic"><i class="fas fa-terminal"></i> {{ if or (in . "www") (in . "http") }} - <a class="event_location" href="{{ $event.location }}" target="_blank">{{ . }}</a> + <a class="event_location" href="{{ $event.room }}" target="_blank">{{ . }}</a> {{ else }} {{ . }} {{ end }} @@ -89,9 +153,14 @@ <h3> {{ with $event.topic_level }} <span class="event_level"><i class="fas fa-terminal" aria-hidden="true"></i> Topic level: {{ partial "level_badge.html" . }}</span> {{ end }} - {{ with $event.video }} - <span class="event_video"><i class="fas fa-film"></i> <a target="_blank" href="{{ . }}">Video</a></span> - {{ end }} + {{/* No video on the block. A player belongs on a page about one + talk and a link belongs on a row, and a block of the grid is + neither: the grid of PyDay BCN 2020 printed 20 video links, the + one schedule of the site that printed any (David Arcos, + 2026-10-15). The videos of the day are the Videos block of the + page, under the grid, one row per video, from + partials/event_videos.html; the modal behind this block keeps + the link, as the detail of one session. */}} </div> {{ if $event.description }} {{ partial "event_detail.html" (dict "event" $event "index" $index) }} diff --git a/themes/pybcn_theme/layouts/partials/agenda_entry.html b/themes/pybcn_theme/layouts/partials/agenda_entry.html new file mode 100644 index 000000000..73a461cc0 --- /dev/null +++ b/themes/pybcn_theme/layouts/partials/agenda_entry.html @@ -0,0 +1,196 @@ +{{- /* + agenda_entry: one row of the schedule, with its talk joined in. + + Argument: a dict with + slot one entry of the agenda list of the page + talks the talks of the page, keyed by id + rooms the rooms of the page, keyed by id + colors the colour of each room, keyed by room id + people the name of every person record, keyed by id + event_url the RelPermalink of the event page, or absent. It is half + the key of partials/talk_pages_index.html, so a caller + that passes it gets the url of the page of the talk back + + Returns a flat entry that agenda.html and event_detail.html render. The + join lives here, in one place, because a block of the grid and the modal + behind it print the same fields and must not disagree about them. + + The page carries two lists and not one. agenda is the grid: when, for how + long, in which room, over how many tracks. talks is the content: the + title, who gave it, what it was about. The two are separate because one + talk can take more than one slot (Hands-on Django with PyLadiesBCN is one + workshop in four) and because a photo of the gallery links to a talk by + id, which a row of a grid cannot give it. + + A slot with no talk is a row of the day and not a session: a break, the + group photo, the welcome. It carries its own label, its own type, and + whatever else the day gave it, because there is nothing else to read it + from. + + What this partial computes rather than reads from the page: + + - The colour. It used to be written on every entry, and it meant + nothing: across the eight editions 24 colour-and-room combinations + covered more than one room and only 20 mapped to a single room, and + the colour followed neither the type, nor the topic, nor the level. + Now every room of an event gets one colour of the palette below and + keeps it for the whole day, so a reader can follow a track down the + grid. A slot with no room gets grey. + + - The end of the slot, from its start and the duration of what fills it. + The end used to be written too, and 27 of the 157 entries of the + archive wrote it equal to the start. + + - The url of the page of the talk, looked up in + partials/talk_pages_index.html and empty when the slot holds no talk + or the caller passes no event_url. See the comment on it below. +*/ -}} +{{- $slot := .slot -}} +{{- $talk := "" -}} +{{- with $slot.talk -}} + {{- $talk = index $.talks . -}} + {{- if not $talk -}} + {{- warnf "agenda_entry: slot at %v names talk %q, which this page does not define." $slot.start . -}} + {{- end -}} +{{- end -}} + +{{- /* The talk is what a slot that holds one says; the slot itself is all + there is when it holds none. */ -}} +{{- $source := $slot -}} +{{- with $talk }}{{ $source = . }}{{ end -}} + +{{- $title := $slot.label -}} +{{- with $talk }}{{ $title = .title }}{{ end -}} + +{{- /* The palette agenda.scss defines, in the order a room takes it. */ -}} +{{- $palette := slice "purple" "blue" "yellow" "red" "orange" "grey" "green" "pink" -}} +{{- $color := "grey" -}} +{{- $room := "" -}} +{{- with $slot.room -}} + {{- with index $.rooms . }}{{ $room = .name }}{{ end -}} + {{- with index $.colors . }}{{ $color = . }}{{ end -}} +{{- end -}} + +{{- /* duration_minutes sits on the talk, and on the slot when no talk fills + it. A duration of zero is a real value in this archive, so the lookup + cannot use default: a 0 would fall through it. */ -}} +{{- $duration := 0 -}} +{{- with index $slot "duration_minutes" }}{{ $duration = . }}{{ end -}} +{{- with $talk }}{{ with index . "duration_minutes" }}{{ $duration = . }}{{ end }}{{ end -}} +{{- $parts := split $slot.start ":" -}} +{{- $end := add (add (mul 60 (int (index $parts 0))) (int (index $parts 1))) $duration -}} +{{- $end = printf "%d:%02d" (int (math.Floor (div $end 60))) (mod $end 60) -}} + +{{- /* language is a code, or a list of codes for a session given in two. + The field used to be free text and carried seven spellings of three + languages, so the page printed "Catalan" and "Català" for the same + language and three different joins of Spanish and English. + + The labels print in the order the list gives them, so the order of the + list is content and not formatting. A list is written en, es, ca, the + order of the table below, and bin/check-content rejects any other: + the archive held one [en, es] and three [es, en] for the same pair. */ -}} +{{- $names := dict "en" "English" "es" "Spanish" "ca" "Catalan" -}} +{{- $labels := slice -}} +{{- with $source.language -}} + {{- $codes := cond (reflect.IsSlice .) . (slice .) -}} + {{- range $codes -}} + {{- with index $names . -}} + {{- $labels = $labels | append . -}} + {{- else -}} + {{- warnf "agenda_entry: unknown language %q on %q. Use en, es or ca." . $title -}} + {{- end -}} + {{- end -}} +{{- end -}} + +{{- /* The speakers of a session are a list of person ids, and the name + printed is the one the person record holds. The field was free text, + one string per talk, and it carried three joins of two names ("A and + B", "A, B", "A & B"), an affiliation in parentheses, a first name + with no surname, and an accent missing from a name the person record + spells with it. None of that could be checked against anything: + bin/check-content validates talks[].speakers against the person + records, and a string is not an id, so none of the 101 talks that + carried one was ever checked against anything. + + An id with no record behind it prints as the id with its hyphens + taken out, the way photo_gallery.html does it, and warns. The check + is what fails the build for it; the page still reads. + + A slot with no talk reads its own speakers, and a slot that credits + no person carries none: the organising committee of an edition is not + a person and gets no record. */ -}} +{{- $names := slice -}} +{{- range $id := $source.speakers -}} + {{- $name := index $.people $id -}} + {{- if not $name -}} + {{- warnf "agenda_entry: %q credits speaker id %q, which no person record defines." $title $id -}} + {{- $name = $id | replaceRE "[-_]+" " " | title -}} + {{- end -}} + {{- $names = $names | append $name -}} +{{- end -}} + +{{- /* credited_as is the credit of something that is not a person, so it has + no record to point at: the organising committee of an edition runs the + registration, the breaks, and the closing. Moving speakers to person + ids dropped those eight credits, because a committee cannot have a + person record. A session never has both: speakers names people, and + credited_as names whoever else. */ -}} +{{- if and (not $names) $source.credited_as -}} + {{- $names = slice $source.credited_as -}} +{{- end -}} + +{{- /* The page of this talk, when the caller says which event page it is + reading. Every talk with an id gets a page of its own, built by + content/talks/_content.gotmpl, and partials/talk_pages_index.html + holds the page the adapter actually added, keyed by the event and the + id. The url is looked up and never spelled out: the adapter owns the + rule that makes the path, and a second copy of that rule here would + go on emitting a link after the rule changed. + + Empty when the slot holds no talk, when the slot names a talk this + page does not define, when the caller passes no event_url, and when + the index holds no page for the pair. A caller that gets no url + prints what it printed before, so a missing page costs the reader + nothing and never leaves a dead link on the page. + + partials/talk_record.html passes no event_url: it renders the page of + one talk, which does not link to itself. */ -}} +{{- $url := "" -}} + +{{- /* video and repositories were two fields and are now one list, because + a session can publish more than one address and one of them did it as + raw HTML inside the repositories string. The video keeps its own line + on the block and in the modal; everything else is listed under + Repository in the modal. */ -}} +{{- $video := "" -}} +{{- $repositories := slice -}} +{{- range $source.links -}} + {{- if eq .type "video" -}} + {{- if not $video }}{{ $video = .url }}{{ end -}} + {{- else -}} + {{- $repositories = $repositories | append . -}} + {{- end -}} +{{- end -}} + +{{- return dict + "title" $title + "title_lang" $source.title_lang + "type" $source.type + "speaker" (delimit $names ", " " and ") + "description" $source.description + "topic" $source.topic + "language" (delimit $labels " / ") + "python_level" $slot.python_level + "topic_level" $slot.topic_level + "requirements" $slot.requirements + "sponsor" $slot.sponsor + "room" $room + "color" $color + "start" $slot.start + "end" $end + "track_length" $slot.track_length + "url" $url + "video" $video + "repositories" $repositories +-}} diff --git a/themes/pybcn_theme/layouts/partials/event_detail.html b/themes/pybcn_theme/layouts/partials/event_detail.html index 297a411b2..3f79d39bb 100644 --- a/themes/pybcn_theme/layouts/partials/event_detail.html +++ b/themes/pybcn_theme/layouts/partials/event_detail.html @@ -2,6 +2,12 @@ reader reads it with the right voice. The language field is the language of the talk, not of the title, so the attribute comes only from title_lang. See partials/title_lang.html. */}} +{{/* repositories is a list of links now, and no longer one string. Two of + the strings it replaces held more than one address, with a label around + each in raw HTML. The label is data here and this template owns the + markup, so the <br> scaffolding those two carried is gone. A single + unlabelled address renders as it did: markdownify turns a bare URL into + a link. */ -}} {{ $title_lang := partial "title_lang.html" $.event }} <div class="modal fade" id="modal_{{ $.index }}" role="dialog" aria-labelledby="modal_{{ $.index }}_title" aria-hidden="true" tabindex="-1"> <div class="modal-dialog" role="document"> @@ -28,7 +34,7 @@ <h3 class="modal-title" id="modal_{{ $.index }}_title"> {{ end }} - {{ with $.event.location }} + {{ with $.event.room }} <br/><br/><span class="event_topic"><i class="fas fa-terminal"></i> {{ if or (in . "www") (in . "http") }} <a class="event_location" href="{{ . }}" target="_blank">{{ . }}</a><br/> @@ -49,8 +55,11 @@ <h3 class="modal-title" id="modal_{{ $.index }}_title"> {{ with $.event.topic_level }} <span class="event_level"><i class="fas fa-terminal" aria-hidden="true"></i> Topic level: {{ partial "level_badge.html" . }}</span><br/> {{ end }} + {{/* The same link the block of the grid prints, through the + same partial, so the modal and the block agree on the + words and the mark. */}} {{ with $.event.video }} - <span class="event_video"><i class="fas fa-film"></i> <a href="{{ . }}" target="_blank">Video</a></span> + <span class="event_video">{{ partial "video_link.html" (dict "url" . "blank" true) }}</span> {{ end }} {{/* markdownify wraps its result in a p of its own, so the p that used to be here nested one inside another, which no @@ -66,7 +75,17 @@ <h3 class="modal-title" id="modal_{{ $.index }}_title"> {{ end }} {{ with $.event.repositories }} <p><b>Repository:</b></p> - {{ . | markdownify }} + {{ range $position, $link := . }}{{ if $position }}<br>{{ end }}{{ with $link.label }}<b>{{ . }}</b>: {{ end }}{{ $link.url | markdownify }}{{ end }} + {{ end }} + {{/* The way out of the modal, last in the body. The modal is the + quick look at one row of the grid and the page of the talk + is the record, so a reader who opened the peek and wants + the rest should not have to close it and hunt for the + title. The url comes from partials/agenda_entry.html, which + looks it up in partials/talk_pages_index.html, so it is + empty for a row that has no page and no link is printed. */}} + {{ with $.event.url }} + <p class="modal_talk_link"><a href="{{ . }}">Read the page of this talk</a></p> {{ end }} </div> </div> diff --git a/themes/pybcn_theme/layouts/partials/event_type_icon.html b/themes/pybcn_theme/layouts/partials/event_type_icon.html index 5c9b9c4bd..92df04f28 100644 --- a/themes/pybcn_theme/layouts/partials/event_type_icon.html +++ b/themes/pybcn_theme/layouts/partials/event_type_icon.html @@ -1,14 +1,36 @@ {{- /* event_type_icon: render the icon of an agenda entry type. - Context: the type token as a string. See event_types.html for the list. - An unknown token renders nothing and logs a build warning. + Context: the type token as a string, or a dict with the token under + "type" and "named" set to true. See event_types.html for the list. An + unknown token renders nothing and logs a build warning. + + A bare token draws the icon as decoration, aria-hidden, which is right + where the label is printed next to it in words: the agenda legend, the + facts of a talk page. A named icon carries the label of its type as its + accessible name and as its hover, from the one field of + event_types.html, so the two cannot disagree. The rows of a listing + (/talks/, the programme of a meetup) want that: nothing else on the row + says that a talk was a workshop or a lightning talk. A title attribute + on a hidden icon would have been a hover for a mouse and nothing for a + screen reader, which is the reader the name is for, so the icon is an + image with a name instead. */ -}} -{{- $token := lower (trim (printf "%v" .) " ") -}} +{{- $named := false -}} +{{- $type := . -}} +{{- if reflect.IsMap . -}} + {{- $named = .named -}} + {{- $type = .type -}} +{{- end -}} +{{- $token := lower (trim (printf "%v" $type) " ") -}} {{- with $token -}} {{- $entry := index (partialCached "event_types.html" "event_types") . -}} {{- if $entry -}} + {{- if $named -}} + <i class="fas {{ $entry.icon }}" role="img" aria-label="{{ $entry.label }}" title="{{ $entry.label }}"></i> + {{- else -}} <i class="fas {{ $entry.icon }}" aria-hidden="true"></i> + {{- end -}} {{- else -}} {{- warnf "event_type_icon: unknown event type %q." . -}} {{- end -}} diff --git a/themes/pybcn_theme/layouts/partials/event_types.html b/themes/pybcn_theme/layouts/partials/event_types.html index ad18efbd9..b90f89294 100644 --- a/themes/pybcn_theme/layouts/partials/event_types.html +++ b/themes/pybcn_theme/layouts/partials/event_types.html @@ -1,9 +1,11 @@ {{- /* event_types: the controlled vocabulary of agenda entry types. - Returns a map of token to icon class and human label. It is the single - source of truth for the agenda grid, the event detail modal and the - agenda legend, so the three cannot drift apart. + Returns a map of token to icon class, human label, and the noun a + legend prints after a count, singular (one) and plural (many). It is + the single source of truth for the agenda grid, the event detail modal, + the agenda legend, the rows of /talks/, and the legend above them, so + none of them can drift apart. "sponsor" is not an entry type. It is listed here because the legend explains the same star icon that the agenda puts next to a sponsor name. @@ -12,13 +14,15 @@ never supplies markup. */ -}} {{- return dict - "talk" (dict "icon" "fa-comment" "label" "Talk") - "workshop" (dict "icon" "fa-laptop" "label" "Workshop") - "coffee" (dict "icon" "fa-mug-hot" "label" "Coffee break") - "lunch" (dict "icon" "fa-utensils" "label" "Lunch") - "photo" (dict "icon" "fa-camera" "label" "Group photo") - "group" (dict "icon" "fa-users" "label" "Plenary session") - "qa" (dict "icon" "fa-question-circle" "label" "Questions and answers") - "lightning" (dict "icon" "fa-bolt" "label" "Lightning talk") - "sponsor" (dict "icon" "fa-star gold" "label" "Sponsored event") + "talk" (dict "icon" "fa-comment" "label" "Talk" "one" "talk" "many" "talks") + "workshop" (dict "icon" "fa-laptop" "label" "Workshop" "one" "workshop" "many" "workshops") + "coffee" (dict "icon" "fa-mug-hot" "label" "Coffee break" "one" "coffee break" "many" "coffee breaks") + "lunch" (dict "icon" "fa-utensils" "label" "Lunch" "one" "lunch" "many" "lunches") + "photo" (dict "icon" "fa-camera" "label" "Group photo" "one" "group photo" "many" "group photos") + "group" (dict "icon" "fa-users" "label" "Plenary session" "one" "plenary session" "many" "plenary sessions") + "qa" (dict "icon" "fa-question-circle" "label" "Questions and answers" "one" "questions and answers session" "many" "questions and answers sessions") + "lightning" (dict "icon" "fa-bolt" "label" "Lightning talk" "one" "lightning talk" "many" "lightning talks") + "keynote" (dict "icon" "fa-microphone" "label" "Keynote" "one" "keynote" "many" "keynotes") + "panel" (dict "icon" "fa-comments" "label" "Panel" "one" "panel" "many" "panels") + "sponsor" (dict "icon" "fa-star gold" "label" "Sponsored event" "one" "sponsored event" "many" "sponsored events") -}} diff --git a/themes/pybcn_theme/layouts/partials/link_mark.html b/themes/pybcn_theme/layouts/partials/link_mark.html new file mode 100644 index 000000000..89d38676a --- /dev/null +++ b/themes/pybcn_theme/layouts/partials/link_mark.html @@ -0,0 +1,64 @@ +{{- /* + The mark of a link that leaves the site: one glyph per destination, in + front of the words of the link, grey like every other icon of the site. + + [YouTube mark] Watch on YouTube + [GitHub mark] Code on GitHub + [arrow mark] Read more + + Argument: the URL of the link, as a string. The host decides the glyph, + with a leading "www." taken off first, so one row of the table below + covers www.github.com and github.com: + + youtube.com, m.youtube.com, youtu.be fab fa-youtube + github.com, gist.github.com fab fa-github + gitlab.com fab fa-gitlab + bitbucket.org fab fa-bitbucket + slideshare.net, es.slideshare.net fab fa-slideshare + speakerdeck.com fab fa-speaker-deck + flickr.com fab fa-flickr + drive.google.com, docs.google.com fab fa-google-drive + linkedin.com fab fa-linkedin + meetup.com fab fa-meetup + x.com, twitter.com icon_x (the mask of main.scss) + any other host fas fa-external-link-alt + + Measured over the links of the talk records on 2026-10-15, outside the + header and the footer: youtube.com 114, github.com 32, slideshare.net + 5, drive.google.com and docs.google.com 4 between them, then gitlab, + bitbucket, speakerdeck, and slides.com once each, and about 45 hosts + with one link. Every brand above has a glyph in the vendored Font + Awesome 5.8.2 except X, which came after the Twitter rename and is the + CSS mask of main.scss. slides.com has no glyph and takes the generic + mark with the long tail. + + Before this partial only YouTube and x.com carried a mark, each printed + where it was used, and the YouTube mark took the colour of the link + around it while every other icon of the site is grey. David Arcos asked + for one mark per destination, grey like the rest (2026-10-15). The grey + is .link_mark in main.scss, and a caller that needs a different gap or + size writes a rule on that class, as the facts box does on dt i. + + The glyph is aria-hidden: the words of the link name the destination + ("Watch on YouTube", "Code on GitHub"), or the label beside it does + (the Source row of the facts box, the X row of a person page). A caller + whose words do not say where the link goes writes them; the mark never + stands in for them. +*/ -}} +{{- $host := "" -}} +{{- with urls.Parse . }}{{ $host = strings.TrimPrefix "www." (lower .Host) }}{{ end -}} +{{- $class := "fas fa-external-link-alt" -}} +{{- if in (slice "youtube.com" "m.youtube.com" "youtu.be") $host }}{{ $class = "fab fa-youtube" -}} +{{- else if in (slice "github.com" "gist.github.com") $host }}{{ $class = "fab fa-github" -}} +{{- else if eq $host "gitlab.com" }}{{ $class = "fab fa-gitlab" -}} +{{- else if eq $host "bitbucket.org" }}{{ $class = "fab fa-bitbucket" -}} +{{- else if in (slice "slideshare.net" "es.slideshare.net") $host }}{{ $class = "fab fa-slideshare" -}} +{{- else if eq $host "speakerdeck.com" }}{{ $class = "fab fa-speaker-deck" -}} +{{- else if in (slice "flickr.com" "flic.kr") $host }}{{ $class = "fab fa-flickr" -}} +{{- else if in (slice "drive.google.com" "docs.google.com") $host }}{{ $class = "fab fa-google-drive" -}} +{{- else if eq $host "linkedin.com" }}{{ $class = "fab fa-linkedin" -}} +{{- else if eq $host "meetup.com" }}{{ $class = "fab fa-meetup" -}} +{{- else if in (slice "x.com" "twitter.com") $host }}{{ $class = "icon_x" -}} +{{- end -}} +<i class="{{ $class }} link_mark" aria-hidden="true"></i> +{{- /* No trailing newline: the mark sits inline in front of the words. */ -}} diff --git a/themes/pybcn_theme/layouts/partials/people_names.html b/themes/pybcn_theme/layouts/partials/people_names.html new file mode 100644 index 000000000..5d43f55e3 --- /dev/null +++ b/themes/pybcn_theme/layouts/partials/people_names.html @@ -0,0 +1,33 @@ +{{- /* + The name of every person record, by id. + + No argument is read: the data comes from the files under + content/people/. Call it through partialCached with a constant variant, + so the 378 person files are read once per build: + + partialCached "people_names.html" site "people-names" + + The person files are read from site.Pages, which is how + partials/people-grid.html joins a person to an event. Same join here. + They built no page of their own until the Archive brought the pages + back (config.toml has the history); the join did not change. + + An id with no name behind it is left out, and partials/speaker_names.html + is what turns a missing id into something readable. + + partials/agenda.html builds the same dict inline, once per event page, + because it needs it for the page it is rendering (so did + partials/gallery_content.html, until the gallery started linking its + speakers through this dict on 2026-10-14). This partial exists for the + talk pages, which are 607 pages that each need one name or two: a dict + built per page there would read the 378 person files 607 times. +*/ -}} +{{- $names := dict -}} +{{- range $person := where site.Pages "Section" "people" -}} + {{- with $person.Params.id -}} + {{- with $person.Params.name -}} + {{- $names = merge $names (dict $person.Params.id .) -}} + {{- end -}} + {{- end -}} +{{- end -}} +{{- return $names -}} diff --git a/themes/pybcn_theme/layouts/partials/speaker_names.html b/themes/pybcn_theme/layouts/partials/speaker_names.html new file mode 100644 index 000000000..fd4e7dff7 --- /dev/null +++ b/themes/pybcn_theme/layouts/partials/speaker_names.html @@ -0,0 +1,25 @@ +{{- /* + The names of a list of person ids, in the order the list gives them. + + Arguments: + names a dict of person id to the name the record holds + ids the person ids to resolve + + Returns a slice of names. An id with no record behind it becomes the id + with its hyphens and underscores taken out, which is what + partials/agenda_entry.html prints for the same case. + + The caller passes the dict, built once per page, because the join reads + every person file: see the $people dict in partials/agenda.html. A + partial that built the dict itself would walk the site once per talk. +*/ -}} +{{- $names := .names -}} +{{- $out := slice -}} +{{- range $id := .ids -}} + {{- $name := index $names $id -}} + {{- if not $name -}} + {{- $name = $id | replaceRE "[-_]+" " " | title -}} + {{- end -}} + {{- $out = $out | append $name -}} +{{- end -}} +{{- return $out -}} diff --git a/themes/pybcn_theme/layouts/partials/video_link.html b/themes/pybcn_theme/layouts/partials/video_link.html new file mode 100644 index 000000000..1000e3f26 --- /dev/null +++ b/themes/pybcn_theme/layouts/partials/video_link.html @@ -0,0 +1,45 @@ +{{- /* + The link to the video of a talk or of a session, with the mark of its + host in front. + + [YouTube mark] Watch on YouTube + [YouTube mark] Ready, Set, Go with Numba on YouTube + + Argument: a dict with + url the address of the video + title optional. With a title the link reads "<title> on YouTube", + which is David Arcos' rule of 2026-10-14 for a video + printed on its own: the title of the video is the link to + YouTube, with the YouTube mark in front of it. Without one + the link reads "Watch on YouTube", for a row that prints + the title just above it and would say it twice. + blank optional. true opens the video in a new tab, for the block + of the programme grid and its modal, which did so before. + + One partial, so the row of a meetup page, the block of the programme + grid, the modal behind it, the page of the talk, and the recording of + a whole session print the same link in the same words. The mark is + partials/link_mark.html, the one mark per destination the whole site + prints, hidden from a screen reader because the words beside it name + the host. A host other than YouTube gets the generic mark of that + partial and other words: "Watch the video", or "<title> (video)". The + host list is the one the Videos block of the gallery read while + partials/gallery_content.html built it (its header has the history). Every + link of the archive goes to www.youtube.com today, 117 of them, + measured on 2026-10-14; the other branch is for the next one. + + The words say where the link goes before the reader follows it. The + player itself is on the page of the talk and nowhere else: see + layouts/talks/single.html. +*/ -}} +{{- $host := "" -}} +{{- with urls.Parse .url }}{{ $host = lower .Host }}{{ end -}} +{{- $youtube := in (slice "youtube.com" "www.youtube.com" "m.youtube.com" "youtu.be") $host -}} +<a class="video_link" href="{{ .url }}"{{ if .blank }} target="_blank" rel="noopener"{{ end }}> + {{- partial "link_mark.html" .url -}} + {{- with .title -}} + {{- . }}{{ if $youtube }} on YouTube{{ else }} (video){{ end -}} + {{- else -}} + {{- if $youtube }}Watch on YouTube{{ else }}Watch the video{{ end -}} + {{- end -}} +</a> From 3578ce817c321a2643442d992754aeaef45007a9 Mon Sep 17 00:00:00 2001 From: David Arcos <david.arcos@gmail.com> Date: Thu, 15 Oct 2026 10:01:16 +0200 Subject: [PATCH 2/7] Print the day of an edition on its page, and list the talks of one with no grid The hero of an edition page prints the title and the description and no date, so until now the page said its day nowhere a reader or a machine could find it. partials/event_date.html formats an event date, and a range when end_date is set, as one time element per day, and the page prints it as the first line of its column: "19 to 21 May 2017" for PyData Barcelona 2017, "29 November 2025" for PyDay BCN 2025. Every edition page carries date and venue now, and the two that ran more than one day carry end_date. partials/talk_rows.html lists the talks of a page as rows, one per talk, with the icon of the type, the title, who gave it, and the video when the talk has one. event.html draws them where the grid would be for a page that has talks and no agenda: PyData Barcelona 2017 holds 32 talks and no record of the room or the hour of any of them, so there is no grid to draw. PyDay BCN 2018 and 2019 carry an agenda with no eventTimes on purpose and publish the frozen programme in their body, so they get no rows either. --- themes/pybcn_theme/assets/scss/event.scss | 9 ++ .../pybcn_theme/layouts/_default/event.html | 69 +++++++--- .../layouts/partials/event_date.html | 124 ++++++++++++++++++ .../layouts/partials/talk_rows.html | 51 +++++++ 4 files changed, 238 insertions(+), 15 deletions(-) create mode 100644 themes/pybcn_theme/layouts/partials/event_date.html create mode 100644 themes/pybcn_theme/layouts/partials/talk_rows.html diff --git a/themes/pybcn_theme/assets/scss/event.scss b/themes/pybcn_theme/assets/scss/event.scss index e9138421f..7ec152865 100644 --- a/themes/pybcn_theme/assets/scss/event.scss +++ b/themes/pybcn_theme/assets/scss/event.scss @@ -2,6 +2,15 @@ margin-bottom: 2em; + // The day of the edition, the first line of the column, muted like the + // day line of a meetup page (.meetup_when in meetup.scss) and a step + // larger than the body text, because it is the first fact of the page. + .event_when { + font-size: 1.15rem; + color: #51616e; + margin-bottom: 1.2rem; + } + #index_sections { top:100px; } diff --git a/themes/pybcn_theme/layouts/_default/event.html b/themes/pybcn_theme/layouts/_default/event.html index 379a55cf0..ab1e511cf 100644 --- a/themes/pybcn_theme/layouts/_default/event.html +++ b/themes/pybcn_theme/layouts/_default/event.html @@ -12,17 +12,30 @@ {{ if .Params.important_dates }}<a class="list-group-item list-group-item-action" href="#important_dates_section">Important dates</a>{{ end }} {{ if .Params.call_for_proposals }}<a class="list-group-item list-group-item-action" href="#call_for_proposals_section">Call for proposals</a>{{ end }} {{ if .Params.registration }}<a class="list-group-item list-group-item-action" href="#registration_section">Registration</a>{{ end }} - {{ if .Params.events }}<a class="list-group-item list-group-item-action" href="#agenda_section">Schedule</a>{{ end }} + {{ if and .Params.agenda .Params.eventTimes }}<a class="list-group-item list-group-item-action" href="#agenda_section">Schedule</a>{{ end }} + {{ if and .Params.talks (not .Params.agenda) }}<a class="list-group-item list-group-item-action" href="#talks_section">Talks</a>{{ end }} {{ if .Params.call_for_sponsors }}<a class="list-group-item list-group-item-action" href="#call_for_sponsors_section">Call for sponsors</a>{{ end }} {{ if .Params.sponsor_levels }}<a class="list-group-item list-group-item-action" href="#sponsors_section">Sponsors</a>{{ end }} {{ range $section := .Params.people_sections }} <a class="list-group-item list-group-item-action" href="#{{ $section.id }}">{{ $section.title }}</a> {{ end }} - {{ if .Params.previous_editions }}<a class="list-group-item list-group-item-action" href="#previous_editions_section">Previous editions</a>{{ end }} </div> </div> <div class="col-md-9"> + {{- /* The day, or the days, as the first line of the column. The + hero above prints the title and the description and no + date, and until this line an edition page said its day + nowhere a reader or a machine could find it: the row of + /events/ had it and the page did not. The range comes + from partials/event_date.html, one time element per day, + so PyData Barcelona 2017 reads "19 to 21 May 2017" and + PyDay BCN 2016 "15 to 17 September 2016". Hacktoberfest + 2018 carries no date and prints no line. */ -}} + {{- $when := partial "event_date.html" (dict "date" .Params.date "end_date" .Params.end_date) -}} + {{- with $when.html }} + <p class="event_when">{{ . }}</p> + {{- end }} <div class="row" id="content"> {{ if .Params.content_columns }} <div class="col col-md-{{.Params.content_columns}}"> @@ -48,10 +61,47 @@ <h2 class="h1">{{ $section.title }}</h2> </div> {{ end }} - {{ if .Params.events }} + {{/* The grid needs both lists and the rows to draw them on. + eventTimes is what partials/agenda.html turns into the rows of + the CSS grid, so a page with an agenda and no eventTimes has + no grid to draw: it would emit grid-template-rows: repeat(0) + and stack every block of the day on one line. The two pre-Hugo + programmes, PyDay BCN 2018 and 2019, are in that state on + purpose. They carry agenda, talks and rooms because a photo of + the gallery joins to a talk by id, and they publish the + programme the association froze in their own body: the pasted + agenda table of 2018 and the calendar embed of 2019. Give + either one eventTimes and numTracks and its grid appears. */ -}} + {{ if and .Params.agenda .Params.eventTimes }} <div class="link_anchor" id="agenda_section"> <h2 class="h1">Schedule</h2> - {{ partial "agenda.html" (dict "Site" .Site "legend" .Params.legend "spansDuration" .Params.spansDuration "numTracks" .Params.numTracks "eventTimes" .Params.eventTimes "events" .Params.events)}} + {{/* event_url is the RelPermalink of this page, which is half the + key of partials/talk_pages_index.html: it is how a row of + the grid finds the page of its own talk. The grid takes a + dict of the fields it reads and not the page, so the page + has to hand it over. */}} + {{ partial "agenda.html" (dict "Site" .Site "event_url" .RelPermalink "legend" .Params.legend "spansDuration" .Params.spansDuration "numTracks" .Params.numTracks "eventTimes" .Params.eventTimes "agenda" .Params.agenda "talks" .Params.talks "rooms" .Params.rooms)}} + </div> + {{ end }} + + {{/* The talks of an edition that has them and has no programme + grid, as rows, where the grid would be: the rows of + partials/talk_rows.html, the ones a meetup page draws, so + the two read alike. Each row links to the page of its talk, + where its video, its slides, and its photograph are. PyData + Barcelona 2017 is the one page in that state: 32 talks + from the archive, 29 with a video and 17 with slides, and + no record of the room or the hour of any of them, so no + grid to draw. The gate is the absence of agenda and not of + eventTimes: PyDay BCN 2018 and 2019 carry an agenda with no + eventTimes on purpose (see above) and publish the programme + in their body, and a list of rows under it would print the + programme twice. */ -}} + {{ if and .Params.talks (not .Params.agenda) }} + <div class="link_anchor" id="talks_section"> + <h2 class="h1">Talks ({{ len .Params.talks }})</h2> + {{ partial "talk_rows.html" . }} + <br/><br/><br/> </div> {{ end }} @@ -77,17 +127,6 @@ <h2 class="h1">{{ $section.title }}</h2> </div> {{ end }} - {{ if .Params.previous_editions }} - <div class="link_anchor" id="previous_editions_section"> - <h2 class="h1">Previous editions</h2> - <ul> - {{ range $edition := .Params.previous_editions }} - <li><a href="{{ $edition.url }}">{{ $edition.name }}</a></li> - {{ end }} - </ul> - </div> - {{ end }} - </div> </div> </div> diff --git a/themes/pybcn_theme/layouts/partials/event_date.html b/themes/pybcn_theme/layouts/partials/event_date.html new file mode 100644 index 000000000..b8fb7df43 --- /dev/null +++ b/themes/pybcn_theme/layouts/partials/event_date.html @@ -0,0 +1,124 @@ +{{- /* + The date of an event, answered once for every page that prints one. + + Argument: a dict with date, the first day, and end_date, the last day, + which an edition carries only when it ran more than one day. Pass the + two params of the event page: + + partial "event_date.html" (dict "date" .Params.date "end_date" .Params.end_date) + + plus "weekday" true to put the weekday in front of each day, which the + page of a meetup wants. Both keys go through time.AsTime, so a YAML date + and a quoted string both work. + + Returns a dict, empty when there is no date (Hacktoberfest 2018 carries + none, so a caller tests what it gets and prints nothing): + + start, end the two days as times. end is nil for a one day + event, and also when end_date is not after + date: the page then prints one day, and + bin/check-content reports the mistake. + year, month, day the first day in parts, as strings: "2016", + "Sep", "15". One per column of a listing that + sets the date in columns. + end_year, end_month, end_day + the last day in the same parts, empty strings + for a one day event. + short "15 Sep", "15 to 17 Sep", "30 Sep to 2 Oct", for + a line under a heading that says the year. + text "15 September 2016", "15 to 17 September 2016", + for prose. + html text, with each day inside its own time element. + + Why the format is what it is. The order is day, month, year, the one + the site prints already ("Monday, 2 January 2006" on a meetup page) and + the one a reader in Barcelona says. A range collapses what its two ends + share, the way a person says it: "15 to 17 September 2016", never + "15 September 2016 to 17 September 2016". A range inside one month + repeats neither the month nor the year, a range inside one year repeats + the month and not the year, and a range across two years prints both + ends whole. The word between the ends is "to" and not a dash: a screen + reader skips a dash between two numbers or reads it as "minus", and the + site uses no em dash. + + The machine readable form. The datetime attribute of a time element + holds one valid date string, so a range is two time elements, one per + end, and never one element whose datetime holds two dates: + bin/check-rendered and axe-core run over the result. The collapse is in + the text only: the first element reads "15" and the second "17 + September 2016", and each one carries its whole date in datetime. + + safeHTML, once, on html: every character of it comes from time.Format + of a parsed date, so no content field reaches it (AGENTS.md: never add + a field that reaches a template through safeHTML). A date that does not + parse stops the build in time.AsTime. +*/ -}} +{{- $start := "" -}} +{{- with .date }}{{ $start = time.AsTime . }}{{ end -}} +{{- $end := "" -}} +{{- with .end_date }}{{ $end = time.AsTime . }}{{ end -}} +{{- if and $start $end -}} + {{- if not ($end.After $start) }}{{ $end = "" }}{{ end -}} +{{- end -}} + +{{- $out := dict -}} +{{- if $start -}} + {{- $iso := "2006-01-02" -}} + {{- $short := "" -}} + {{- $text := "" -}} + {{- $html := "" -}} + {{- $end_year := "" -}} + {{- $end_month := "" -}} + {{- $end_day := "" -}} + {{- if $end -}} + {{- /* How much of the first day is printed is how much the two + ends do not share: the day alone inside one month, the day + and the month inside one year, the whole date across two. + The last day is always whole, less the year when both ends + share it in the short form. */ -}} + {{- $first_long := "2 January 2006" -}} + {{- $first_short := "2 Jan 2006" -}} + {{- $last_short := "2 Jan 2006" -}} + {{- if eq $start.Year $end.Year -}} + {{- $first_long = "2 January" -}} + {{- $first_short = "2 Jan" -}} + {{- $last_short = "2 Jan" -}} + {{- if eq $start.Month $end.Month -}} + {{- $first_long = "2" -}} + {{- $first_short = "2" -}} + {{- end -}} + {{- end -}} + {{- $last_long := "2 January 2006" -}} + {{- if .weekday -}} + {{- $first_long = printf "Monday %s" $first_long -}} + {{- $last_long = printf "Monday %s" $last_long -}} + {{- end -}} + {{- $first := time.Format $first_long $start -}} + {{- $last := time.Format $last_long $end -}} + {{- $end_year = time.Format "2006" $end -}} + {{- $end_month = time.Format "Jan" $end -}} + {{- $end_day = time.Format "2" $end -}} + {{- $short = printf "%s to %s" (time.Format $first_short $start) (time.Format $last_short $end) -}} + {{- $text = printf "%s to %s" $first $last -}} + {{- $html = printf "<time datetime=\"%s\">%s</time> to <time datetime=\"%s\">%s</time>" (time.Format $iso $start) $first (time.Format $iso $end) $last -}} + {{- else -}} + {{- $long := "2 January 2006" -}} + {{- if .weekday }}{{ $long = "Monday, 2 January 2006" }}{{ end -}} + {{- $short = time.Format "2 Jan" $start -}} + {{- $text = time.Format $long $start -}} + {{- $html = printf "<time datetime=\"%s\">%s</time>" (time.Format $iso $start) $text -}} + {{- end -}} + {{- $out = dict + "start" $start + "end" $end + "year" (time.Format "2006" $start) + "month" (time.Format "Jan" $start) + "day" (time.Format "2" $start) + "end_year" $end_year + "end_month" $end_month + "end_day" $end_day + "short" $short + "text" $text + "html" ($html | safeHTML) -}} +{{- end -}} +{{- return $out -}} diff --git a/themes/pybcn_theme/layouts/partials/talk_rows.html b/themes/pybcn_theme/layouts/partials/talk_rows.html new file mode 100644 index 000000000..67c6eea88 --- /dev/null +++ b/themes/pybcn_theme/layouts/partials/talk_rows.html @@ -0,0 +1,51 @@ +{{- /* + The talks of one event page, one row per talk, in the order of the + talks list of the page. + + Argument: the page. Its Params.talks is the list; the caller checks + that the list is not empty and writes the heading and the wrapper, so + the rows sit inside whatever block the page draws around them: the + section of layouts/_default/meetup.html, the link_anchor of + layouts/_default/event.html. + + A row has the icon of the type, named so that its label is its + accessible name and its hover, the title as the link to the page of + the talk, and who gave it under the title. A talk with no page of its + own, which happens when it has no id, is printed as text rather than + dropped. The first link of type video of the talk is the Watch line, + the rule partials/agenda_entry.html applies for the block of the grid; + no talk of the archive carries two. The slides and the photograph of + the talk are on its page, which the title links to, so a row does not + repeat them. + + The markup is the one the meetup page carried until the edition page + needed the same rows: PyData Barcelona 2017 holds 32 talks and no + programme grid, and listed its slides in its body as a numbered list + with the speaker names typed in, a worse copy of its own talk records. + One partial, so the two pages read alike and a change reaches both. + The styles are .talk_rows of talks.scss, which the person page uses as + well. +*/ -}} +{{- $names := partialCached "people_names.html" site "people-names" -}} +<ul class="talk_rows"> + {{- range $talk := .Params.talks }} + {{- $url := "" -}} + {{- $speakers := partial "speaker_names.html" (dict "names" $names "ids" $talk.speakers) -}} + {{- $title_lang := partial "title_lang.html" (dict "title_lang" $talk.title_lang "title" $talk.title) -}} + {{- $video := "" -}} + {{- range $link := $talk.links -}} + {{- if and (not $video) (eq (default "" $link.type) "video") }}{{ $video = $link.url }}{{ end -}} + {{- end -}} + <li class="talk_row"> + <h3 class="talk_title">{{ with $talk.type }}<span class="talk_icon">{{ partial "event_type_icon.html" (dict "type" . "named" true) }}</span>{{ end }} + {{- if $url }}<a href="{{ $url }}"{{ with $title_lang }} lang="{{ . }}"{{ end }}>{{ $talk.title }}</a> + {{- else }}<span{{ with $title_lang }} lang="{{ . }}"{{ end }}>{{ $talk.title }}</span>{{ end }}</h3> + {{- with $speakers }} + <p class="talk_meta">{{ delimit . ", " }}</p> + {{- end }} + {{- with $video }} + <p class="talk_video">{{ partial "video_link.html" (dict "url" .) }}</p> + {{- end }} + </li> + {{- end }} +</ul> From c4b887c0438921c08f505c98f3a452efe5d3aa28 Mon Sep 17 00:00:00 2001 From: David Arcos <david.arcos@gmail.com> Date: Thu, 15 Oct 2026 10:01:16 +0200 Subject: [PATCH 3/7] Add the person records the programmes credit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A talk credits its speakers by person id, so every speaker of the eleven programmes needs a record under content/people/. 38 records are new, most of them a name and an id, which is what the source gives: the printed agenda of a PyDay names a person and nothing else about them. One of them, Giorgio Polvara, is an organizer and not a speaker: the frozen site of Hacktoberfest 2018 names him with three people who already have a record. Five records are corrected rather than added. Four names get the accent their owner writes (Daniel Mesejo León, Daniel Sánchez Santolaya, Eva Martín del Pico, Julio Martínez) and one loses the leading space it carried (Noé Casas). The import that follows resolves a speaker name to a record by the same name ignoring accents and case, so a record with the wrong spelling would still resolve, and then print it. The portrait of Jordi Bosch is replaced with the one David Arcos sent on 2026-10-14, cut square by bin/square-photos. --- content/people/anna-fedotova.md | 4 ++++ content/people/artur-mindiyarov.md | 4 ++++ content/people/bartek-skorulski.md | 4 ++++ content/people/camilo-cardona.md | 4 ++++ content/people/carles-illa.md | 4 ++++ content/people/claudia-guirao.md | 4 ++++ content/people/claudia-millan.md | 4 ++++ content/people/constant-bridon.md | 4 ++++ content/people/daniel-mesejo-leon.md | 2 +- content/people/daniel-sanchez-santolaya.md | 2 +- content/people/diego-hueltes.md | 4 ++++ content/people/eduard-goma.md | 4 ++++ content/people/egor-bulychev.md | 4 ++++ content/people/erik-tordera.md | 4 ++++ content/people/eva-martin-del-pico.md | 2 +- content/people/francesc-alted.md | 4 ++++ content/people/giorgio-polvara.md | 4 ++++ content/people/guillem-borrell-nogueras.md | 4 ++++ content/people/guillem-duran-ballester.md | 4 ++++ content/people/hector-canto.md | 5 +++++ content/people/holden-karau.md | 4 ++++ content/people/ismael-benito.md | 5 +++++ content/people/jaime-fernandez-del-rio.md | 4 ++++ content/people/javier-martinez-alcantara.md | 4 ++++ content/people/joaquin-pais.md | 4 ++++ content/people/jordi-deu-pons.md | 4 ++++ content/people/jordi-guix.md | 4 ++++ content/people/jordi-torrents.md | 4 ++++ content/people/jorge-cimentada.md | 4 ++++ content/people/julio-martinez.md | 2 +- content/people/maciej-siwek.md | 4 ++++ content/people/margriet-groenendijk.md | 4 ++++ content/people/massimo-domenico-sammito.md | 4 ++++ content/people/miguel-zavala-ake.md | 4 ++++ content/people/nicholas-a-del-grosso.md | 4 ++++ content/people/noe-casas.md | 2 +- content/people/oscar-gallardo-roman.md | 4 ++++ content/people/pablo-fernandez.md | 4 ++++ content/people/pascal-van-kooten.md | 4 ++++ content/people/ramon-navarro-bosch.md | 5 +++++ content/people/travis-oliphant.md | 4 ++++ content/people/yang-liu.md | 4 ++++ content/people/yufeng-guo.md | 4 ++++ .../assets/images/people/jordi-bosch.jpg | Bin 96394 -> 121786 bytes 44 files changed, 160 insertions(+), 5 deletions(-) create mode 100644 content/people/anna-fedotova.md create mode 100644 content/people/artur-mindiyarov.md create mode 100644 content/people/bartek-skorulski.md create mode 100644 content/people/camilo-cardona.md create mode 100644 content/people/carles-illa.md create mode 100644 content/people/claudia-guirao.md create mode 100644 content/people/claudia-millan.md create mode 100644 content/people/constant-bridon.md create mode 100644 content/people/diego-hueltes.md create mode 100644 content/people/eduard-goma.md create mode 100644 content/people/egor-bulychev.md create mode 100644 content/people/erik-tordera.md create mode 100644 content/people/francesc-alted.md create mode 100644 content/people/giorgio-polvara.md create mode 100644 content/people/guillem-borrell-nogueras.md create mode 100644 content/people/guillem-duran-ballester.md create mode 100644 content/people/hector-canto.md create mode 100644 content/people/holden-karau.md create mode 100644 content/people/ismael-benito.md create mode 100644 content/people/jaime-fernandez-del-rio.md create mode 100644 content/people/javier-martinez-alcantara.md create mode 100644 content/people/joaquin-pais.md create mode 100644 content/people/jordi-deu-pons.md create mode 100644 content/people/jordi-guix.md create mode 100644 content/people/jordi-torrents.md create mode 100644 content/people/jorge-cimentada.md create mode 100644 content/people/maciej-siwek.md create mode 100644 content/people/margriet-groenendijk.md create mode 100644 content/people/massimo-domenico-sammito.md create mode 100644 content/people/miguel-zavala-ake.md create mode 100644 content/people/nicholas-a-del-grosso.md create mode 100644 content/people/oscar-gallardo-roman.md create mode 100644 content/people/pablo-fernandez.md create mode 100644 content/people/pascal-van-kooten.md create mode 100644 content/people/ramon-navarro-bosch.md create mode 100644 content/people/travis-oliphant.md create mode 100644 content/people/yang-liu.md create mode 100644 content/people/yufeng-guo.md diff --git a/content/people/anna-fedotova.md b/content/people/anna-fedotova.md new file mode 100644 index 000000000..7a4b3f427 --- /dev/null +++ b/content/people/anna-fedotova.md @@ -0,0 +1,4 @@ +--- +id: anna-fedotova +name: "Anna Fedotova" +--- diff --git a/content/people/artur-mindiyarov.md b/content/people/artur-mindiyarov.md new file mode 100644 index 000000000..76f3ff1e0 --- /dev/null +++ b/content/people/artur-mindiyarov.md @@ -0,0 +1,4 @@ +--- +id: artur-mindiyarov +name: "Artur Mindiyarov" +--- diff --git a/content/people/bartek-skorulski.md b/content/people/bartek-skorulski.md new file mode 100644 index 000000000..c74751c68 --- /dev/null +++ b/content/people/bartek-skorulski.md @@ -0,0 +1,4 @@ +--- +id: bartek-skorulski +name: "Bartek Skorulski" +--- diff --git a/content/people/camilo-cardona.md b/content/people/camilo-cardona.md new file mode 100644 index 000000000..169fe06fc --- /dev/null +++ b/content/people/camilo-cardona.md @@ -0,0 +1,4 @@ +--- +id: camilo-cardona +name: "Camilo Cardona" +--- diff --git a/content/people/carles-illa.md b/content/people/carles-illa.md new file mode 100644 index 000000000..59cd2ad46 --- /dev/null +++ b/content/people/carles-illa.md @@ -0,0 +1,4 @@ +--- +id: carles-illa +name: "Carles Illa" +--- diff --git a/content/people/claudia-guirao.md b/content/people/claudia-guirao.md new file mode 100644 index 000000000..1fcfbada2 --- /dev/null +++ b/content/people/claudia-guirao.md @@ -0,0 +1,4 @@ +--- +id: claudia-guirao +name: "Claudia Guirao" +--- diff --git a/content/people/claudia-millan.md b/content/people/claudia-millan.md new file mode 100644 index 000000000..a9b75be33 --- /dev/null +++ b/content/people/claudia-millan.md @@ -0,0 +1,4 @@ +--- +id: claudia-millan +name: "Claudia Millán" +--- diff --git a/content/people/constant-bridon.md b/content/people/constant-bridon.md new file mode 100644 index 000000000..49ae0aa12 --- /dev/null +++ b/content/people/constant-bridon.md @@ -0,0 +1,4 @@ +--- +id: constant-bridon +name: "Constant Bridon" +--- diff --git a/content/people/daniel-mesejo-leon.md b/content/people/daniel-mesejo-leon.md index 341e94c58..029f8834a 100644 --- a/content/people/daniel-mesejo-leon.md +++ b/content/people/daniel-mesejo-leon.md @@ -1,6 +1,6 @@ --- id: daniel-mesejo-leon -name: "Daniel Mesejo Leon" +name: "Daniel Mesejo León" linkedin: https://www.linkedin.com/in/daniel-alejandro-mesejo-leon github: https://github.com/mesejo diff --git a/content/people/daniel-sanchez-santolaya.md b/content/people/daniel-sanchez-santolaya.md index cff6146d6..c083195c3 100644 --- a/content/people/daniel-sanchez-santolaya.md +++ b/content/people/daniel-sanchez-santolaya.md @@ -1,6 +1,6 @@ --- id: daniel-sanchez-santolaya -name: Daniel Sanchez Santolaya +name: "Daniel Sánchez Santolaya" photo: daniel-sanchez-santolaya.jpg twitter: https://x.com/danisbd89 linkedin: https://www.linkedin.com/in/daniel-sanchez-santolaya diff --git a/content/people/diego-hueltes.md b/content/people/diego-hueltes.md new file mode 100644 index 000000000..a9429a8c0 --- /dev/null +++ b/content/people/diego-hueltes.md @@ -0,0 +1,4 @@ +--- +id: diego-hueltes +name: "Diego Hueltes" +--- diff --git a/content/people/eduard-goma.md b/content/people/eduard-goma.md new file mode 100644 index 000000000..378afd65d --- /dev/null +++ b/content/people/eduard-goma.md @@ -0,0 +1,4 @@ +--- +id: eduard-goma +name: "Eduard Goma" +--- diff --git a/content/people/egor-bulychev.md b/content/people/egor-bulychev.md new file mode 100644 index 000000000..249ff9979 --- /dev/null +++ b/content/people/egor-bulychev.md @@ -0,0 +1,4 @@ +--- +id: egor-bulychev +name: "Egor Bulychev" +--- diff --git a/content/people/erik-tordera.md b/content/people/erik-tordera.md new file mode 100644 index 000000000..114c3622a --- /dev/null +++ b/content/people/erik-tordera.md @@ -0,0 +1,4 @@ +--- +id: erik-tordera +name: "Erik Tordera" +--- diff --git a/content/people/eva-martin-del-pico.md b/content/people/eva-martin-del-pico.md index 2ef2e24a3..8e5779f24 100644 --- a/content/people/eva-martin-del-pico.md +++ b/content/people/eva-martin-del-pico.md @@ -1,6 +1,6 @@ --- id: eva-martin-del-pico -name: "Eva Martin del Pico" +name: "Eva Martín del Pico" photo: "eva-martin-del-pico.png" linkedin: "https://www.linkedin.com/in/eva-martín-del-pico-4095b988" github: "https://github.com/EvaMart" diff --git a/content/people/francesc-alted.md b/content/people/francesc-alted.md new file mode 100644 index 000000000..7070afbbf --- /dev/null +++ b/content/people/francesc-alted.md @@ -0,0 +1,4 @@ +--- +id: francesc-alted +name: "Francesc Alted" +--- diff --git a/content/people/giorgio-polvara.md b/content/people/giorgio-polvara.md new file mode 100644 index 000000000..edffb1706 --- /dev/null +++ b/content/people/giorgio-polvara.md @@ -0,0 +1,4 @@ +--- +id: giorgio-polvara +name: "Giorgio Polvara" +--- diff --git a/content/people/guillem-borrell-nogueras.md b/content/people/guillem-borrell-nogueras.md new file mode 100644 index 000000000..13782de7b --- /dev/null +++ b/content/people/guillem-borrell-nogueras.md @@ -0,0 +1,4 @@ +--- +id: guillem-borrell-nogueras +name: "Guillem Borrell Nogueras" +--- diff --git a/content/people/guillem-duran-ballester.md b/content/people/guillem-duran-ballester.md new file mode 100644 index 000000000..31a85aa36 --- /dev/null +++ b/content/people/guillem-duran-ballester.md @@ -0,0 +1,4 @@ +--- +id: guillem-duran-ballester +name: "Guillem Duran Ballester" +--- diff --git a/content/people/hector-canto.md b/content/people/hector-canto.md new file mode 100644 index 000000000..b885fb1e7 --- /dev/null +++ b/content/people/hector-canto.md @@ -0,0 +1,5 @@ +--- +id: hector-canto +name: "Héctor Canto" +twitter: "https://x.com/hectorcanto_dev" +--- diff --git a/content/people/holden-karau.md b/content/people/holden-karau.md new file mode 100644 index 000000000..5cc1b9c39 --- /dev/null +++ b/content/people/holden-karau.md @@ -0,0 +1,4 @@ +--- +id: holden-karau +name: "Holden Karau" +--- diff --git a/content/people/ismael-benito.md b/content/people/ismael-benito.md new file mode 100644 index 000000000..9a92e7249 --- /dev/null +++ b/content/people/ismael-benito.md @@ -0,0 +1,5 @@ +--- +id: ismael-benito +name: "Ismael Benito" +twitter: "https://x.com/ismansiete" +--- diff --git a/content/people/jaime-fernandez-del-rio.md b/content/people/jaime-fernandez-del-rio.md new file mode 100644 index 000000000..25ede1981 --- /dev/null +++ b/content/people/jaime-fernandez-del-rio.md @@ -0,0 +1,4 @@ +--- +id: jaime-fernandez-del-rio +name: "Jaime Fernandez del Rio" +--- diff --git a/content/people/javier-martinez-alcantara.md b/content/people/javier-martinez-alcantara.md new file mode 100644 index 000000000..21a717da4 --- /dev/null +++ b/content/people/javier-martinez-alcantara.md @@ -0,0 +1,4 @@ +--- +id: javier-martinez-alcantara +name: "Javier Martinez Alcantara" +--- diff --git a/content/people/joaquin-pais.md b/content/people/joaquin-pais.md new file mode 100644 index 000000000..3b9a77d61 --- /dev/null +++ b/content/people/joaquin-pais.md @@ -0,0 +1,4 @@ +--- +id: joaquin-pais +name: "Joaquin Pais" +--- diff --git a/content/people/jordi-deu-pons.md b/content/people/jordi-deu-pons.md new file mode 100644 index 000000000..830cc5807 --- /dev/null +++ b/content/people/jordi-deu-pons.md @@ -0,0 +1,4 @@ +--- +id: jordi-deu-pons +name: "Jordi Deu-Pons" +--- diff --git a/content/people/jordi-guix.md b/content/people/jordi-guix.md new file mode 100644 index 000000000..cac877b4c --- /dev/null +++ b/content/people/jordi-guix.md @@ -0,0 +1,4 @@ +--- +id: jordi-guix +name: "Jordi Guix" +--- diff --git a/content/people/jordi-torrents.md b/content/people/jordi-torrents.md new file mode 100644 index 000000000..6d368b7dc --- /dev/null +++ b/content/people/jordi-torrents.md @@ -0,0 +1,4 @@ +--- +id: jordi-torrents +name: "Jordi Torrents" +--- diff --git a/content/people/jorge-cimentada.md b/content/people/jorge-cimentada.md new file mode 100644 index 000000000..47d671cee --- /dev/null +++ b/content/people/jorge-cimentada.md @@ -0,0 +1,4 @@ +--- +id: jorge-cimentada +name: "Jorge Cimentada" +--- diff --git a/content/people/julio-martinez.md b/content/people/julio-martinez.md index 8ae5f7aaf..bfce5562c 100644 --- a/content/people/julio-martinez.md +++ b/content/people/julio-martinez.md @@ -1,6 +1,6 @@ --- id: julio-martinez -name: Julio Martinez +name: "Julio Martínez" photo: julio-martinez.jpg twitter: https://x.com/liopic diff --git a/content/people/maciej-siwek.md b/content/people/maciej-siwek.md new file mode 100644 index 000000000..8a7a02510 --- /dev/null +++ b/content/people/maciej-siwek.md @@ -0,0 +1,4 @@ +--- +id: maciej-siwek +name: "Maciej Siwek" +--- diff --git a/content/people/margriet-groenendijk.md b/content/people/margriet-groenendijk.md new file mode 100644 index 000000000..4f1a4c0ea --- /dev/null +++ b/content/people/margriet-groenendijk.md @@ -0,0 +1,4 @@ +--- +id: margriet-groenendijk +name: "Margriet Groenendijk" +--- diff --git a/content/people/massimo-domenico-sammito.md b/content/people/massimo-domenico-sammito.md new file mode 100644 index 000000000..170c932dc --- /dev/null +++ b/content/people/massimo-domenico-sammito.md @@ -0,0 +1,4 @@ +--- +id: massimo-domenico-sammito +name: "Massimo Domenico Sammito" +--- diff --git a/content/people/miguel-zavala-ake.md b/content/people/miguel-zavala-ake.md new file mode 100644 index 000000000..8a8ca6a20 --- /dev/null +++ b/content/people/miguel-zavala-ake.md @@ -0,0 +1,4 @@ +--- +id: miguel-zavala-ake +name: "Miguel Zavala-Ake" +--- diff --git a/content/people/nicholas-a-del-grosso.md b/content/people/nicholas-a-del-grosso.md new file mode 100644 index 000000000..621db9419 --- /dev/null +++ b/content/people/nicholas-a-del-grosso.md @@ -0,0 +1,4 @@ +--- +id: nicholas-a-del-grosso +name: "Nicholas A. Del Grosso" +--- diff --git a/content/people/noe-casas.md b/content/people/noe-casas.md index de28e0062..2952af8b6 100644 --- a/content/people/noe-casas.md +++ b/content/people/noe-casas.md @@ -1,6 +1,6 @@ --- id: noe-casas -name: " Noé Casas" +name: "Noé Casas" photo: noe-casas.png linkedin: "https://www.linkedin.com/in/noecasas" twitter: "https://x.com/noecasas" diff --git a/content/people/oscar-gallardo-roman.md b/content/people/oscar-gallardo-roman.md new file mode 100644 index 000000000..df451195b --- /dev/null +++ b/content/people/oscar-gallardo-roman.md @@ -0,0 +1,4 @@ +--- +id: oscar-gallardo-roman +name: "Óscar Gallardo Román" +--- diff --git a/content/people/pablo-fernandez.md b/content/people/pablo-fernandez.md new file mode 100644 index 000000000..e348f4989 --- /dev/null +++ b/content/people/pablo-fernandez.md @@ -0,0 +1,4 @@ +--- +id: pablo-fernandez +name: "Pablo Fernández" +--- diff --git a/content/people/pascal-van-kooten.md b/content/people/pascal-van-kooten.md new file mode 100644 index 000000000..d8d988907 --- /dev/null +++ b/content/people/pascal-van-kooten.md @@ -0,0 +1,4 @@ +--- +id: pascal-van-kooten +name: "Pascal van Kooten" +--- diff --git a/content/people/ramon-navarro-bosch.md b/content/people/ramon-navarro-bosch.md new file mode 100644 index 000000000..edfe507f9 --- /dev/null +++ b/content/people/ramon-navarro-bosch.md @@ -0,0 +1,5 @@ +--- +id: ramon-navarro-bosch +name: "Ramon Navarro Bosch" +twitter: "https://x.com/bloodbare" +--- diff --git a/content/people/travis-oliphant.md b/content/people/travis-oliphant.md new file mode 100644 index 000000000..e7d854eb4 --- /dev/null +++ b/content/people/travis-oliphant.md @@ -0,0 +1,4 @@ +--- +id: travis-oliphant +name: "Travis Oliphant" +--- diff --git a/content/people/yang-liu.md b/content/people/yang-liu.md new file mode 100644 index 000000000..d077bb210 --- /dev/null +++ b/content/people/yang-liu.md @@ -0,0 +1,4 @@ +--- +id: yang-liu +name: "Yang Liu" +--- diff --git a/content/people/yufeng-guo.md b/content/people/yufeng-guo.md new file mode 100644 index 000000000..c86008e8b --- /dev/null +++ b/content/people/yufeng-guo.md @@ -0,0 +1,4 @@ +--- +id: yufeng-guo +name: "Yufeng Guo" +--- diff --git a/themes/pybcn_theme/assets/images/people/jordi-bosch.jpg b/themes/pybcn_theme/assets/images/people/jordi-bosch.jpg index 6c55534b5f0f11cae85437e1cd1a9e0f40b0ed6a..5a59703ee0a84a0839e3d241e3f76dd001796089 100644 GIT binary patch literal 121786 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 E+43?T$N&HU literal 96394 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 From 4b1ec9d06452c00058909af88d6a9b1b30316f9a Mon Sep 17 00:00:00 2001 From: David Arcos <david.arcos@gmail.com> Date: Thu, 15 Oct 2026 10:01:16 +0200 Subject: [PATCH 4/7] Convert the eight programmes to rooms, talks, and agenda The eight pages that carried an events list carry the three lists now: Django Girls with PyLadies BCN 2022 (2 talks over 10 slots, one workshop in four parts), PyDataBCN 2023 (13 talks, 19 slots, 5 rooms), and PyDay BCN 2020 to 2025 (20, 17, 14, 14, 16, and 17 talks). Every speaker is a person id, every language a code, every time a quoted string, and the colour of a block is gone from the content: across the eight editions 24 colour-and-room combinations covered more than one room and only 20 mapped to a single room, so it meant nothing. The rows a slot used to carry that belong to the day and not to the talk stay on the slot: the start, the room, the python level, the topic level, the requirements, and the sponsor. Each page also carries its date and its venue, and the previous_editions list, which no template read, is gone. The 20 video links of PyDay BCN 2020 are kept on the talks they belong to, as links of type video, which is where the grid reads them. --- .../other_events/django_pyladies_2022.md | 187 +++-- content/events/pydatabcn/pydatabcn_2023.md | 512 +++++++------ content/events/pyday_bcn/pyday_bcn_2020.md | 650 +++++++++------- content/events/pyday_bcn/pyday_bcn_2021.md | 627 +++++++-------- content/events/pyday_bcn/pyday_bcn_2022.md | 503 ++++++------ content/events/pyday_bcn/pyday_bcn_2023.md | 522 ++++++------- content/events/pyday_bcn/pyday_bcn_2024.md | 643 +++++++--------- content/events/pyday_bcn/pyday_bcn_2025.md | 724 +++++++++--------- 8 files changed, 2131 insertions(+), 2237 deletions(-) diff --git a/content/events/other_events/django_pyladies_2022.md b/content/events/other_events/django_pyladies_2022.md index 3aaa8f9a1..5c9d80e40 100644 --- a/content/events/other_events/django_pyladies_2022.md +++ b/content/events/other_events/django_pyladies_2022.md @@ -1,6 +1,11 @@ --- title: "Hands-on Django with PyLadiesBCN (2022)" year: 2022 +# The day of this edition. It is not in the Meetup export: the date comes +# from the X thread of the day, which the posts place on the 11th. +date: 2022-06-11 +# The venue of this edition, from the prose of this page: this day was never a Meetup event of either group. +venue: "Canòdrom" description: "From zero to hero 🤘 Learn how to code your own web application!" menu: main: @@ -46,8 +51,7 @@ free_text_sections: - title: Call for Sponsors id: call_for_sponsors - content: "<center><h3>HELP US CREATE AN UNFORGETTABLE EXPERIENCE!!</h3><br/> - Contact us in pyladies-bcn@googlegroups.com</center>" + content: "<center><h3>HELP US CREATE AN UNFORGETTABLE EXPERIENCE!!</h3><br/></center>" - title: Registration id: registration @@ -121,102 +125,93 @@ people_sections: - mireia-alvarez-dominguez -previous_editions: - - name: DjangoGirls workshop in PyDay BCN 2019 - url: https://djangogirls.org/en/barcelona/ - spansDuration: 30 numTracks: 1 -eventTimes: [9:00, 9:30, 10:00, 10:30, 11:00, 11:30, 12:00, 12:30, 13:00, 13:30, 14:00, 14:30, 15:00, 15:30, 16:00, 16:30, 17:00, 17:30, 18:00] -events: - - start_time_slot: 9:00 - end_time_slot: 9:00 - track_length: 1 - color: purple - title: "Registration & Welcome" - type: group - location: Room Actes - class: middle - - - title: "Hands-on Django" - start_time_slot: 9:30 - end_time_slot: 10:30 - color: blue - track_length: 1 - type: workshop - location: Room Actes - - - - start_time_slot: 11:00 - end_time_slot: 11:00 - track_length: 1 - color: yellow - title: "Coffee Break" - type: coffee - location: Open-air terrace - class: middle - - - title: "Hands-on Django" - start_time_slot: 11:30 - end_time_slot: 12:30 - color: blue - track_length: 1 - type: workshop - location: Room Actes - - - start_time_slot: 13:00 - end_time_slot: 13:00 - track_length: 1 - color: red - title: "Lightning talks" - type: talk - location: Room Actes - class: middle - - - start_time_slot: 13:30 - end_time_slot: 14:00 - track_length: 1 - color: yellow - title: "Lunch" - type: lunch - location: Open-air terrace - class: middle - - - title: "Hands-on Django" - start_time_slot: 14:30 - end_time_slot: 15:30 - color: blue - track_length: 1 - type: workshop - location: Room Actes - - - start_time_slot: 16:00 - end_time_slot: 16:00 - track_length: 1 - color: yellow - title: "Coffee Break" - type: coffee - location: Open-air terrace - class: middle - - - title: "Hands-on Django" - start_time_slot: 16:30 - end_time_slot: 17:30 - color: blue - track_length: 1 - type: workshop - location: Room Actes - - - start_time_slot: 18:00 - end_time_slot: 18:00 - track_length: 1 - color: purple - title: "Closing session & Kahoot" - type: group - location: Room Actes - class: middle - - +eventTimes: ["9:00", "9:30", "10:00", "10:30", "11:00", "11:30", "12:00", "12:30", "13:00", "13:30", "14:00", "14:30", "15:00", "15:30", "16:00", "16:30", "17:00", "17:30", "18:00"] + +# The rooms of this edition, in the order the grid first names them. A room is +# a record with an id because the colour of a block now comes from it: the +# template gives every room of an event one colour of the agenda palette and +# keeps it for the whole day. See partials/agenda_entry.html. +rooms: + - id: room-actes + name: "Room Actes" + - id: open-air-terrace + name: "Open-air terrace" + +# The talks of this edition: what was said, by whom, in which language. A talk +# carries no time and no room, because it is the content and not the slot. +# agenda below is what places it on the grid, and one talk can take more than +# one slot. The id is derived from the title and is the anchor a photo of the +# gallery links to, so it must not change. +talks: + - id: hands-on-django + title: "Hands-on Django" + type: workshop + duration_minutes: 60 + - id: lightning-talks + title: "Lightning talks" + type: talk + duration_minutes: 0 + +# The grid, one row per slot of the day, in the order it is printed. A slot +# names the talk it holds, or carries its own label and type when it holds +# none: a break, the group photo, the welcome. The level and the requirements +# sit here and not on the talk, because they are what the slot asks of whoever +# walks into it. A start is always quoted: YAML 1.1 reads an unquoted 9:00 as +# the integer 540. +agenda: + - start: "9:00" + track_length: 1 + room: room-actes + type: group + label: "Registration & Welcome" + duration_minutes: 0 + - start: "9:30" + track_length: 1 + room: room-actes + talk: hands-on-django + - start: "11:00" + track_length: 1 + room: open-air-terrace + type: coffee + label: "Coffee Break" + duration_minutes: 0 + - start: "11:30" + track_length: 1 + room: room-actes + talk: hands-on-django + - start: "13:00" + track_length: 1 + room: room-actes + talk: lightning-talks + - start: "13:30" + track_length: 1 + room: open-air-terrace + type: lunch + label: "Lunch" + duration_minutes: 30 + - start: "14:30" + track_length: 1 + room: room-actes + talk: hands-on-django + - start: "16:00" + track_length: 1 + room: open-air-terrace + type: coffee + label: "Coffee Break" + duration_minutes: 0 + - start: "16:30" + track_length: 1 + room: room-actes + talk: hands-on-django + - start: "18:00" + track_length: 1 + room: room-actes + type: group + label: "Closing session & Kahoot" + duration_minutes: 0 + --- Do you want to learn how to code your own web application? In this workshop for non-experienced women and LGBTIQ+ people, organised by PyLadiesBCN, **we'll learn how to code our own blog with Django** using HTML, CSS and Python. diff --git a/content/events/pydatabcn/pydatabcn_2023.md b/content/events/pydatabcn/pydatabcn_2023.md index 7e1b23902..9fb60105b 100644 --- a/content/events/pydatabcn/pydatabcn_2023.md +++ b/content/events/pydatabcn/pydatabcn_2023.md @@ -1,6 +1,10 @@ --- title: "PyDataBCN (2023)" year: 2023 +# The day of this edition, from the Meetup export, which records it per event. +date: 2023-06-10 +# The venue of this edition, from the Meetup export, which records it per event. +venue: "Canòdrom" description: "The annual gathering for Pythonists in love with data!" menu: main: @@ -21,14 +25,10 @@ free_text_sections: <b>26th May,10AM</b>: Early registration open for speakers, sponsors and PyLadiesBCN members<br/> <b>29th May, 9AM</b>: General registration open through <a target='_blank' href='https://www.eventbrite.com/e/entradas-pydatabcn-2023-643559583037'>Eventbrite</a><br/> <b>10th June</b>: PyDataBCN 2023" - - title: Call for Sponsors - id: call_for_sponsors - content: "<p>Attention all potential sponsors! PyDataBCN is an exciting new event that brings together the Data Science and Data Engineering community working with Python in Barcelona. This event provides a unique opportunity for sponsors to showcase their products and services, connect with industry experts and thought leaders, and demonstrate their commitment to the data science and engineering community.</p><p>As a sponsor of PyDataBCN, you will be able to reach a diverse and engaged audience of data scientists, engineers, and enthusiasts. Our <code>sponsorship packages</code> are tailored to meet the needs of different organizations and budgets. We offer various sponsorship levels that provide a range of benefits, including branding opportunities and speaking slots.</p><p>In addition to the benefits of sponsorship, your support will also help us make PyDataBCN a huge success. As a non-profit event, we rely on the generosity of our sponsors to cover the costs of organizing the event and ensure that it is accessible to everyone in the data science and engineering community.</p><p>Don't miss this unique opportunity to showcase your brand and support the data science and engineering community in Barcelona. Contact us today at <a href='mailto:pydatabcn2023@googlegroups.com'>pydatabcn2023@googlegroups.com</a> to learn more about our sponsorship packages and how you can get involved in PyDataBCN.</p>" - title: Registration id: registration content: "General registration will open on Monday 29th of May, at 9AM through <a target='_blank' href='https://www.eventbrite.com/e/entradas-pydatabcn-2023-643559583037'>Eventbrite</a>." -sponsors_text: "Would you like to sponsor this event? Please take a look at our [Call for Sponsors](#call_for_sponsors)" sponsor_levels: - sponsors_per_line: 2 @@ -90,7 +90,7 @@ people_sections: spansDuration: 15 numTracks: 4 -eventTimes: [9:00, 9:15, 9:30, 9:45, 10:00, 10:15, 10:30, 10:45, 11:00, 11:15, 11:30, 11:45, 12:00, 12:15, 12:30, 12:45, 13:00, 13:15, 13:30, 13:45, 14:00, 14:15, 14:30, 14:45, 15:00, 15:15, 15:30, 15:45, 16:00, 16:15, 16:30, 16:45, 17:00, 17:15, 17:30, 17:45] +eventTimes: ["9:00", "9:15", "9:30", "9:45", "10:00", "10:15", "10:30", "10:45", "11:00", "11:15", "11:30", "11:45", "12:00", "12:15", "12:30", "12:45", "13:00", "13:15", "13:30", "13:45", "14:00", "14:15", "14:30", "14:45", "15:00", "15:15", "15:30", "15:45", "16:00", "16:15", "16:30", "16:45", "17:00", "17:15", "17:30", "17:45"] legend: - type: workshop - type: talk @@ -100,253 +100,269 @@ legend: - level: advanced - separator: true - type: sponsor -events: - - start_time_slot: 9:00 - end_time_slot: 9:15 - track_length: 4 - color: blue - title: "Registration & Welcome" - speaker: "PyDataBCN Organising Committee" - type: group - location: Open-air terrace - class: middle - - speaker: "Juan Luis Cano Rodríguez" - title: "Convierte tus notebooks de Jupyter en código mantenible con Kedro" - description: "Los notebooks han sido fundamentales para el surgimiento de la ciencia de datos como campo, ya que brindan una interfaz fácil de usar, ofrecen un feedback rápido, y constituyen tanto un entorno de desarrollo como un formato de intercambio. Sin embargo, también se reconoce ampliamente que a menudo plantean problemas de reproducibilidad y mantenibilidad: el 90 % de los notebooks de Jupyter publicados no indican explícitamente las dependencias de los paquetes (Wang et al, 2021), y el 96 % de ellos contener errores o estado oculto que impidió obtener los mismos resultados después de volver a ejecutar (Pimentel et al, 2019). Se han propuesto varias herramientas y enfoques para mitigar los problemas de los notebooks para datos de producción. ciencia. En este taller, los autores proponen un flujo de trabajo que consiste en la refactorización iterativa de notebooks de Jupyter: mediante la extracción incremental de referencias de datos y lógica de negocio en módulos reutilizables de Python, los participantes serán capaces de explotar las capacidades dinámicas de los notebooks manteniendo su complejidad bajo control. Estos módulos de Python harán uso de Kedro, un framework Python para crear pipelines de datos reproducibles, mantenibles y modulares." - start_time_slot: 9:30 - end_time_slot: 10:45 - track_length: 1 - color: orange - python_level: intermediate - topic_level: beginner - type: workshop - topic: "(Maintainable) Data Science" - location: Sala d'actes Ada Lovelace - requirements: "Experiencia con Python, conocimiento básico de Jupyter y pandas" - language: "Spanish" - title_lang: Spanish - - speaker: "Amalia Vradi" - title: "Jupyter Notebooks 101" - description: "This will be an interactive workshop on Jupyter Notebooks, the popular web application that enables you to create and share documents that contain live code, equations, visualizations and narrative text. In this beginner-friendly session, you'll discover what Jupyter Notebooks are and what you can do with them. We'll also introduce you to Google Colab and Kaggle, two platforms that offer free, cloud-based versions of Notebooks. You'll get hands-on experience with installing and using them, as well as experimenting with the features offered by the platforms. Bring your laptop and your curiosity and learn how to take your data science projects to the next level using Jupyter Notebooks!" - start_time_slot: 9:30 - end_time_slot: 10:45 - track_length: 1 - color: grey - python_level: beginner - topic_level: beginner - type: workshop - topic: "Data Analysis" - location: Aula Hedy Lamarr - requirements: "" - language: "English" - - speaker: "Fiorella Piriz Sapio" - title: "Data orchestration with Airflow" - description: "Introduction to the Python-based data orchestration tool, Airflow. We will learn about airflow components and create the first Dags using some of its main operators and connectors. Finally, we will learn how to connect Airflow with Kubernetes and Spark." - start_time_slot: 9:30 - end_time_slot: 10:45 - track_length: 1 - color: grey - python_level: intermediate - topic_level: intermediate - type: workshop - topic: "Big Data Analysis" - location: Sala Margarita Salas - requirements: "Python, Airflow > 2.0.0 (can be easily installed with Pypi), optional: S3, Spark, Kubernetes. Please see: https://github.com/Fiorellaps/airflow_workshop_pybcn/tree/main" - language: "Spanish" - - speaker: "Ricardo Ander-Egg Aguilar" - title: "De los datos al modelo en producción" - description: "Comenzaremos con un conjunto de datos de imágenes sin procesar, entrenaremos un modelo de aprendizaje automático usando fastai/PyTorch y crearemos una aplicación web con FastAPI para permitir que los usuarios interactúen con el modelo." - start_time_slot: 9:30 - end_time_slot: 10:45 - track_length: 1 - color: purple - python_level: intermediate - topic_level: beginner - type: workshop - topic: "Machine Learning" - location: Aula Hipàtia d'Alexandria - requirements: "Solid knowledge of Python and some basic knowledge of web development (HTML). Virtual environment and editor already set up (https://github.com/polyrand/pydatabcn-imgapp-workshop1). Optional: Docker." - language: "Spanish" - title_lang: Spanish +# The rooms of this edition, in the order the grid first names them. A room is +# a record with an id because the colour of a block now comes from it: the +# template gives every room of an event one colour of the agenda palette and +# keeps it for the whole day. See partials/agenda_entry.html. +rooms: + - id: open-air-terrace + name: "Open-air terrace" + - id: sala-dactes-ada-lovelace + name: "Sala d'actes Ada Lovelace" + - id: aula-hedy-lamarr + name: "Aula Hedy Lamarr" + - id: sala-margarita-salas + name: "Sala Margarita Salas" + - id: aula-hipatia-dalexandria + name: "Aula Hipàtia d'Alexandria" - - start_time_slot: 11:00 - end_time_slot: 11:15 - track_length: 4 - color: blue - title: "Coffee break" - type: coffee - location: Open-air terrace - class: middle +# The talks of this edition: what was said, by whom, in which language. A talk +# carries no time and no room, because it is the content and not the slot. +# agenda below is what places it on the grid, and one talk can take more than +# one slot. The id is derived from the title and is the anchor a photo of the +# gallery links to, so it must not change. +talks: + - id: convierte-tus-notebooks-de-jupyter-en-codigo-mantenible-con + title: "Convierte tus notebooks de Jupyter en código mantenible con Kedro" + title_lang: Spanish + speakers: [juan-luis-cano-rodriguez] + type: workshop + language: es + topic: "(Maintainable) Data Science" + duration_minutes: 75 + description: "Los notebooks han sido fundamentales para el surgimiento de la ciencia de datos como campo, ya que brindan una interfaz fácil de usar, ofrecen un feedback rápido, y constituyen tanto un entorno de desarrollo como un formato de intercambio. Sin embargo, también se reconoce ampliamente que a menudo plantean problemas de reproducibilidad y mantenibilidad: el 90 % de los notebooks de Jupyter publicados no indican explícitamente las dependencias de los paquetes (Wang et al, 2021), y el 96 % de ellos contener errores o estado oculto que impidió obtener los mismos resultados después de volver a ejecutar (Pimentel et al, 2019). Se han propuesto varias herramientas y enfoques para mitigar los problemas de los notebooks para datos de producción. ciencia. En este taller, los autores proponen un flujo de trabajo que consiste en la refactorización iterativa de notebooks de Jupyter: mediante la extracción incremental de referencias de datos y lógica de negocio en módulos reutilizables de Python, los participantes serán capaces de explotar las capacidades dinámicas de los notebooks manteniendo su complejidad bajo control. Estos módulos de Python harán uso de Kedro, un framework Python para crear pipelines de datos reproducibles, mantenibles y modulares." + - id: jupyter-notebooks-101 + title: "Jupyter Notebooks 101" + speakers: [amalia-vradi] + type: workshop + language: en + topic: "Data Analysis" + duration_minutes: 75 + description: "This will be an interactive workshop on Jupyter Notebooks, the popular web application that enables you to create and share documents that contain live code, equations, visualizations and narrative text. In this beginner-friendly session, you'll discover what Jupyter Notebooks are and what you can do with them. We'll also introduce you to Google Colab and Kaggle, two platforms that offer free, cloud-based versions of Notebooks. You'll get hands-on experience with installing and using them, as well as experimenting with the features offered by the platforms. Bring your laptop and your curiosity and learn how to take your data science projects to the next level using Jupyter Notebooks!" + - id: data-orchestration-with-airflow + title: "Data orchestration with Airflow" + speakers: [fiorella-piriz-sapio] + type: workshop + language: es + topic: "Big Data Analysis" + duration_minutes: 75 + description: "Introduction to the Python-based data orchestration tool, Airflow. We will learn about airflow components and create the first Dags using some of its main operators and connectors. Finally, we will learn how to connect Airflow with Kubernetes and Spark." + - id: de-los-datos-al-modelo-en-produccion + title: "De los datos al modelo en producción" + title_lang: Spanish + speakers: [ricardo-ander-egg-aguilar] + type: workshop + language: es + topic: "Machine Learning" + duration_minutes: 75 + description: "Comenzaremos con un conjunto de datos de imágenes sin procesar, entrenaremos un modelo de aprendizaje automático usando fastai/PyTorch y crearemos una aplicación web con FastAPI para permitir que los usuarios interactúen con el modelo." + - id: data-analytics-with-python + title: "Data Analytics with Python" + speakers: [juan-bernardo-lince] + type: workshop + language: en + topic: "Data Analysis" + duration_minutes: 75 + description: "Introduction to Data Analytics with Python and Pandas, building a parallel with Excel on how to create columns, summarize information and retrieve quick statistics. Questions, such as \"how can we process data with code?\" and \"which issues should I be addressing with data?\" will be explored, through guided examples on a dataset, to answer business inquiries.<br/><br/>In the second part, examples on Pandas built-in quick plots will be provided. Additionally, we will use Seaborn to create charts and other visual information that enable us to show the answers from the analysis, in a clear and objective manner." + - id: train-your-own-image-classification-model-in-minutes + title: "Train Your Own Image Classification Model in Minutes" + speakers: [amalia-vradi] + type: workshop + language: en + topic: "Deep Learning, Artificial Intelligence" + duration_minutes: 75 + description: "Learn how to train your own image classification model with fastai in this hands-on workshop. You'll discover how easy it is to build a custom model to classify any type of image you want, without needing any special hardware or software. We'll use Google Colab and Kaggle's free GPU instances to train our models, so all you need is your laptop and a curious mindset. Join us to explore the exciting world of computer vision!" + - id: machine-learning-robustness-and-monitoring + title: "Machine Learning Robustness and Monitoring" + speakers: [daniel-sanchez-santolaya] + type: workshop + language: en + topic: "Machine Learning Robustness and Monitoring" + duration_minutes: 75 + description: "Mercury is a python library used in BBVA in data science projects. Recently, we open-sourced some parts of the library to the python and data science community.<br/><br/>In this workshop, we will introduce mercury.robust and mercury.monitoring. With mercury.robust we can perform dataset and model testing to detect undesirable conditions such as high level of noise in the labels, label leaking in the features of the dataset, or model excessive sensitivity to drift in certain features. Mercury.monitoring includes components that can help us detect data drift in our inference data and estimate the performance of our model when real labels are not available yet.<br/><br/>During the workshop we will use components of these libraries during different phases of a machine learning project: dataset generation, model training, and model inference.<br/><br/>The workshop is intended for data scientists and machine learning engineers interested in tools that can help improve the robustness and performance degradation detection of their machine learning models." + - id: indices-invertidos-desde-cero + title: "Índices invertidos desde cero" + title_lang: Spanish + speakers: [ricardo-ander-egg-aguilar] + type: workshop + language: es + topic: "Data Engineering" + duration_minutes: 75 + description: "Muchas bases de datos utilizan índices invertidos para permitir realizar búsquedas de texto completo (full-text search). Veremos cómo funciona un índice invertido y crearemos uno desde cero. También aprenderemos a clasificar los resultados de una búsqueda implementando TF-IDF." + - id: fine-tuning-of-llm-models-for-text-processing + title: "Fine-tuning of LLM models for text processing" + speakers: [ruben-afonso] + type: workshop + language: en + topic: "Artificial Intelligence" + duration_minutes: 75 + description: "In this workshop we will review how to leverage your Python skills to reuse and fine-tune some of the latest Generative LLM (Large Language Models) available and strategies to tackle specific use cases such as text summarisation and question-answering" + - id: foundations-of-machine-learning-exploring-use-cases-and + title: "Foundations of Machine Learning: exploring use cases and typical tasks" + speakers: [nikita-polovinkin] + type: workshop + language: en + topic: "Machine Learning" + duration_minutes: 75 + description: "In this workshop you will learn the logic and foundations behind Machine Learning, to better understand how it can be used and where not to. The Different use cases of Machine Learning, and practical exercises of the most typical Machine Learning tasks: regression and classification. Finally how to predict the gender pay gap based on some features such as job descriptions, age and other demographics." + - id: ask-your-data-build-a-full-pipeline-to-get-generative + title: "Ask your data! Build a full pipeline to get generative answers from a text dataset" + speakers: [carmen-iniesta-lopez] + type: workshop + language: en + topic: "Machine Learning, NLP, Semantic search, Generative AI" + duration_minutes: 75 + description: "The goal of this workshop is to teach attendees how to build a full pipeline to generate sentence embeddings from a given dataset, index them in a vector database for semantic search, and integrate search results as context for a LLM. " + - id: com-visualitzar-incertesa-i-models-probabilistics + title: "Com visualitzar incertesa i models probabilistics" + title_lang: Catalan + speakers: [oriol-abril-pla] + type: workshop + language: ca + topic: "Data Visualization" + duration_minutes: 75 + description: "Aprèn a visualitzar paràmetres i prediccions de models probabilístics emprant histogrames, estimadors nuclears de densitat (KDE), gràfics de punts per quantils i funcions de distribució empíriques" + - id: lightning-talks-session + title: "Lightning talks session" + speakers: [adrian-garcia-riber, albert-pujol-torras, alvaro-duran-barata, diego-quintana, edgar-sarria-tenes, miquel-sarrias, monica-dominguez, rajdeep-pal, ricardo-ander-egg-aguilar, sergi-baena-miret, thais-ruiz-de-alda] + type: talk + language: [en, es] + topic: "Multiple topics" + duration_minutes: 75 + description: "<p><b>How Data Scientists Can Be More Productive with the Power of Static Typing</b> - Alvaro Duran<br/>Data scientists frequently find themselves in situations where they need to verify that some intermediate step in a data pipeline works as expected, and tools such as Jupiter notebooks, where each step is explicitly shown to the user, are very useful at that. However, it can become quite cumbersome and time-consuming as the data pipeline grows more complex.<br/>That's where static typing comes in. By using types in our code, we can introduce our data into a structured pipeline and catch errors early on, before they have the chance to cause any real problems. This is particularly useful when working with large datasets, where a small error can have a significant impact on our results.<br/>But what exactly do we mean by 'types'? Essentially, types are a way of specifying the kind of data that a variable or function will handle. For example, we might specify that a certain variable should only contain integers, or that a certain function should only accept strings.<br/>By using types, we can catch errors early on in the development process, rather than having to wait until runtime to discover them. This can save us a lot of time and effort in the long run, as we can catch errors before they have a chance to cause any real damage.<br/>Now, you might be thinking, 'but doesn't introducing types make our code more complex?' And the answer is, not necessarily. In fact, Python has built-in support for types that makes it easy to incorporate them into our code.<br/>Of course, that is just the first part of the puzzle. Good type systems are analogous to test suites: they require some effort, but the payoff is immense.<br/>This talk will cover the very basics of how data scientists can benefit from using types, not only on their production code, but even on crude prototypes, giving some peace of mind by making illegal states unrepresentable.</p><p><b>Astronomical data Sonification</b> - Adrián García Riber<br/>The current development of massive astronomical archives and virtual observatory technology (VO) offers a wide range of data products and services that can be explored with a personal computer through interoperable technology. The use of sonification and musification in multimodal displays for the exploration of astronomical data offers an additional domain (complementary to visualization), that allows researchers to get immersed in their case studies, navigating the massive downloads of big data generated by space telescopes, and that makes stellar catalogs and databases more accessible for blind-visually impaired (BVI) users. In this talk I would like to introduce the collection of Python and TensorFlow Sonification prototypes developed in my PhD to generate multimodal representations of astronomical data using Deep Learning and Neural Networks.</p><p><b>Python models and alerts within dbt with dbt-fal and novu</b> - Diego Quintana<br/>How to trigger alarms and run python models within dbt with dbt-fal and novu. <br/>dbt is the T in the ELT pipe. Although dbt allows for python model since version 1.3, its support is limited. dbt-fal enables running python models and python code in general within a model. A simple demo will be shown, with a forecasting model is trained as part of a dbt pipeline and an alarm is triggered with novu, an open source notification infrastructure.</p><p><b>Serverless Machine Learning: Streamlining Deployment and Scaling of ML Services</b> - Rajdeep Pal<br/>The topic of deploying machine learning services using a serverless architecture is focused on leveraging cloud computing services to simplify the deployment and scaling of machine learning models. Using a serverless approach, developers can focus on writing code for their ML models without worrying about infrastructure setup and management. The serverless model also provides automatic scaling of resources to meet the demands of incoming requests, reducing the need for manual intervention and ensuring that services remain highly available. This talk would cover the benefits of using a serverless approach to deploy machine learning services and provide practical guidance on how to implement it effectively. It would also explore the challenges and trade-offs involved in using serverless architecture for ML services, such as performance considerations, security, and cost optimisation.</p><p><b>Practical considerations when using chatGPT in production for multilanguage processing</b> - Albert Pujol Torras<br/>We will describe the results of empirical measurements of the behavior of LLMs to automate NLP processes depending on both the language in which the prompt is written, the lenguage of the text to be analyzed as well as some practical considerations to take into account when considering putting in production this type of Models.</p><p><b>International Data Spaces: Implementing the European Strategy on Data</b> - Miquel Sarrias<br/>The International Data Spaces (IDS) initiative aims at cross-sectoral data sovereignty and data interoperability. It sets forth a Reference Architecture Model basing on open standards and contributing to global standards. By specifying data usage constraints, it defines the terms and conditions for the data economy. Data spaces are key to the global, digital economy. The European Commission is defining Europe's path forward into the digital economy of the future. A core element of their vision: international data spaces grounded in European values of trust and the self-determination of data usage by data providers, that we call data sovereignty.</p><p><b>Forecasting in the integral water cycle</b> - Sergi Baena-Miret<br/>Droughts can have severe impacts on water availability, demand, and quality, affecting water allocation, infrastructure planning, and environmental protection. Accurate forecasting of droughts is essential for mitigating their impacts by enabling effective water management strategies. Various techniques such as statistical models, machine learning, and remote sensing are used for drought forecasting in the integral water cycle. However, challenges such as data scarcity, non-stationarity, and uncertainty in climate change projections pose significant challenges for accurate forecasting.</p><p><b>MusicMetaData & algorithmic diversity perrspective</b> - Thais Ruiz de Alda<br/>We want to talk about the current challenge de music industry is facing around metadata and the challenges that including a gender perspective can imply. The talk will cover the story of music metadata and how Digitalfems is challenging the musical descriptive metadata status quo to develop an ADM system that will include gender diversity in a beta testing/lab environment with the support of different institutions such as FECYT, UPC and other relevant stakeholders</p><p><b>Free online Data Apps with Shimoku Library</b> - Edgar Sarria<br/>We will show how to use Shimoku instead of Streamlit to build Data Products in few lines of code</p><p><b>Data Science in Transport Modelling</b> - Monica Dominguez<br/>Transport modelling and traffic simulation have traditionally been branches of Civil Engineering and Applied Mathematics. In this talk, we will present how the field is embracing Data Science and Machine Learning methodologies for data processing, pattern analysis, forecasting and prediction of recurrent and non-recurrent events.</p><p><b>Bundling a Python app in a single file</b> - Ricardo Ander-Egg<br/>Live coding talk. This talk will show how to bundle a Python app and all of its dependencies in a single file. Then we will copy this file to a different machine and see how the script runs without having to deal with Docker or virtual environments.</p>" - - speaker: "Juan Bernardo Lince" - title: "Data Analytics with Python" - description: "Introduction to Data Analytics with Python and Pandas, building a parallel with Excel on how to create columns, summarize information and retrieve quick statistics. Questions, such as “how can we process data with code?” and “which issues should I be addressing with data?” will be explored, through guided examples on a dataset, to answer business inquiries.<br/><br/>In the second part, examples on Pandas built-in quick plots will be provided. Additionally, we will use Seaborn to create charts and other visual information that enable us to show the answers from the analysis, in a clear and objective manner." - start_time_slot: 11:30 - end_time_slot: 12:45 - track_length: 1 - color: grey - python_level: beginner - topic_level: beginner - type: workshop - topic: "Data Analysis" - location: Sala d'actes Ada Lovelace - requirements: "" - language: "English" - - speaker: "Amalia Vradi" - title: "Train Your Own Image Classification Model in Minutes" - description: "Learn how to train your own image classification model with fastai in this hands-on workshop. You'll discover how easy it is to build a custom model to classify any type of image you want, without needing any special hardware or software. We'll use Google Colab and Kaggle's free GPU instances to train our models, so all you need is your laptop and a curious mindset. Join us to explore the exciting world of computer vision!" - start_time_slot: 11:30 - end_time_slot: 12:45 - track_length: 1 - color: purple - python_level: beginner - topic_level: beginner - type: workshop - topic: "Deep Learning, Artificial Intelligence" - location: Aula Hedy Lamarr - requirements: "A google account (to be able to use Google Colab) or a Kaggle account, for using free GPU instances" - language: "English" - - speaker: "Daniel Sánchez Santolaya" - title: "Machine Learning Robustness and Monitoring" - description: "Mercury is a python library used in BBVA in data science projects. Recently, we open-sourced some parts of the library to the python and data science community.<br/><br/>In this workshop, we will introduce mercury.robust and mercury.monitoring. With mercury.robust we can perform dataset and model testing to detect undesirable conditions such as high level of noise in the labels, label leaking in the features of the dataset, or model excessive sensitivity to drift in certain features. Mercury.monitoring includes components that can help us detect data drift in our inference data and estimate the performance of our model when real labels are not available yet.<br/><br/>During the workshop we will use components of these libraries during different phases of a machine learning project: dataset generation, model training, and model inference.<br/><br/>The workshop is intended for data scientists and machine learning engineers interested in tools that can help improve the robustness and performance degradation detection of their machine learning models." - start_time_slot: 11:30 - end_time_slot: 12:45 - track_length: 1 - color: purple - python_level: intermediate - topic_level: intermediate - type: workshop - topic: "Machine Learning Robustness and Monitoring" - location: Sala Margarita Salas - requirements: "Laptop with python installed (or alternatively laptop with access to Google Colab can be used as well)" - language: "English" - - speaker: "Ricardo Ander-Egg Aguilar" - title: "Índices invertidos desde cero" - description: "Muchas bases de datos utilizan índices invertidos para permitir realizar búsquedas de texto completo (full-text search). Veremos cómo funciona un índice invertido y crearemos uno desde cero. También aprenderemos a clasificar los resultados de una búsqueda implementando TF-IDF." - start_time_slot: 11:30 - end_time_slot: 12:45 - track_length: 1 - color: orange - python_level: intermediate - topic_level: beginner - type: workshop - topic: "Data Engineering" - location: Aula Hipàtia d'Alexandria - requirements: "Conocimiento de elementos de Python como funciones, clases, bucles, comprensiones de listas, generadores, etc. Conocer las estructuras de datos principales de Python (listas, sets, tuples, diccionarios...). Habilidades básicas de procesamiento de texto (manipular cadenas de texto y conocimiento básico de expresiones regulares (regex)). Para el taller solamente utilizaremos la librería estándar de Python. Se recomienda usar Python 3.7 o superior." - language: "Spanish" - title_lang: Spanish +# The grid, one row per slot of the day, in the order it is printed. A slot +# names the talk it holds, or carries its own label and type when it holds +# none: a break, the group photo, the welcome. The level and the requirements +# sit here and not on the talk, because they are what the slot asks of whoever +# walks into it. A start is always quoted: YAML 1.1 reads an unquoted 9:00 as +# the integer 540. +agenda: + - start: "9:00" + credited_as: "PyDataBCN Organising Committee" + track_length: 4 + room: open-air-terrace + type: group + label: "Registration & Welcome" + duration_minutes: 15 + - start: "9:30" + track_length: 1 + room: sala-dactes-ada-lovelace + talk: convierte-tus-notebooks-de-jupyter-en-codigo-mantenible-con + python_level: intermediate + topic_level: beginner + requirements: "Experiencia con Python, conocimiento básico de Jupyter y pandas" + - start: "9:30" + track_length: 1 + room: aula-hedy-lamarr + talk: jupyter-notebooks-101 + python_level: beginner + topic_level: beginner + - start: "9:30" + track_length: 1 + room: sala-margarita-salas + talk: data-orchestration-with-airflow + python_level: intermediate + topic_level: intermediate + requirements: "Python, Airflow > 2.0.0 (can be easily installed with Pypi), optional: S3, Spark, Kubernetes. Please see: https://github.com/Fiorellaps/airflow_workshop_pybcn/tree/main" + - start: "9:30" + track_length: 1 + room: aula-hipatia-dalexandria + talk: de-los-datos-al-modelo-en-produccion + python_level: intermediate + topic_level: beginner + requirements: "Solid knowledge of Python and some basic knowledge of web development (HTML). Virtual environment and editor already set up (https://github.com/polyrand/pydatabcn-imgapp-workshop1). Optional: Docker." + - start: "11:00" + track_length: 4 + room: open-air-terrace + type: coffee + label: "Coffee break" + duration_minutes: 15 + - start: "11:30" + track_length: 1 + room: sala-dactes-ada-lovelace + talk: data-analytics-with-python + python_level: beginner + topic_level: beginner + - start: "11:30" + track_length: 1 + room: aula-hedy-lamarr + talk: train-your-own-image-classification-model-in-minutes + python_level: beginner + topic_level: beginner + requirements: "A google account (to be able to use Google Colab) or a Kaggle account, for using free GPU instances" + - start: "11:30" + track_length: 1 + room: sala-margarita-salas + talk: machine-learning-robustness-and-monitoring + python_level: intermediate + topic_level: intermediate + requirements: "Laptop with python installed (or alternatively laptop with access to Google Colab can be used as well)" + - start: "11:30" + track_length: 1 + room: aula-hipatia-dalexandria + talk: indices-invertidos-desde-cero + python_level: intermediate + topic_level: beginner + requirements: "Conocimiento de elementos de Python como funciones, clases, bucles, comprensiones de listas, generadores, etc. Conocer las estructuras de datos principales de Python (listas, sets, tuples, diccionarios...). Habilidades básicas de procesamiento de texto (manipular cadenas de texto y conocimiento básico de expresiones regulares (regex)). Para el taller solamente utilizaremos la librería estándar de Python. Se recomienda usar Python 3.7 o superior." + - start: "13:00" + track_length: 4 + room: open-air-terrace + type: photo + label: "Group photo" + duration_minutes: 0 + - start: "13:15" + track_length: 4 + room: open-air-terrace + type: lunch + label: "Lunch break" + duration_minutes: 30 + - start: "14:00" + track_length: 1 + room: sala-dactes-ada-lovelace + talk: fine-tuning-of-llm-models-for-text-processing + python_level: intermediate + topic_level: beginner + requirements: "https://gist.github.com/rubenafo/b91861b37f31d16ee7b8d86e707a9f9f" + - start: "14:00" + track_length: 1 + room: aula-hedy-lamarr + talk: foundations-of-machine-learning-exploring-use-cases-and + python_level: beginner + topic_level: beginner + - start: "14:00" + track_length: 1 + room: sala-margarita-salas + talk: ask-your-data-build-a-full-pipeline-to-get-generative + python_level: intermediate + topic_level: intermediate + requirements: "Intermediate knowledge of Python programming, understanding of natural language processing and semantic search concepts, enthusiasm and willingness to learn and collaborate.<br/>Technical requirements: Laptop with python >= 3.9 installed and HF’s SentenceTransformers. Nucliadb is optional, if not installed we’ll do it together during the workshop. A requirements.txt and more details will be provided prior to the event." + - start: "14:00" + track_length: 1 + room: aula-hipatia-dalexandria + talk: com-visualitzar-incertesa-i-models-probabilistics + python_level: intermediate + topic_level: beginner + requirements: "Cal certa comoditat a l'hora de treballar amb Python, NumPy i Matplotlib. Tots els gràfics seran introduïts abans d'utilitzar-se, però és recomanable tenir coneixements bàsics d'estadística." + - start: "15:30" + track_length: 4 + room: open-air-terrace + type: coffee + label: "Coffee break" + duration_minutes: 15 + - start: "16:00" + track_length: 4 + room: sala-dactes-ada-lovelace + talk: lightning-talks-session + - start: "17:30" + credited_as: "PyDataBCN Organising Committee" + track_length: 4 + room: sala-dactes-ada-lovelace + type: group + label: "Closing session & Kahoot" + duration_minutes: 15 - - start_time_slot: 13:00 - end_time_slot: 13:00 - track_length: 4 - color: blue - title: "Group photo" - type: photo - location: Open-air terrace - class: middle - - - start_time_slot: 13:15 - end_time_slot: 13:45 - track_length: 4 - color: blue - title: "Lunch break" - type: lunch - location: Open-air terrace - class: middle - - - speaker: "Ruben Afonso" - title: "Fine-tuning of LLM models for text processing" - description: "In this workshop we will review how to leverage your Python skills to reuse and fine-tune some of the latest Generative LLM (Large Language Models) available and strategies to tackle specific use cases such as text summarisation and question-answering" - start_time_slot: 14:00 - end_time_slot: 15:15 - track_length: 1 - color: purple - python_level: intermediate - topic_level: beginner - type: workshop - topic: "Artificial Intelligence" - location: Sala d'actes Ada Lovelace - requirements: "https://gist.github.com/rubenafo/b91861b37f31d16ee7b8d86e707a9f9f" - language: "English" - - speaker: "Nikita Polovinkin" - title: "Foundations of Machine Learning: exploring use cases and typical tasks" - description: "In this workshop you will learn the logic and foundations behind Machine Learning, to better understand how it can be used and where not to. The Different use cases of Machine Learning, and practical exercises of the most typical Machine Learning tasks: regression and classification. Finally how to predict the gender pay gap based on some features such as job descriptions, age and other demographics." - start_time_slot: 14:00 - end_time_slot: 15:15 - track_length: 1 - color: purple - python_level: beginner - topic_level: beginner - type: workshop - topic: "Machine Learning" - location: Aula Hedy Lamarr - requirements: "" - language: "English" - - speaker: "Carmen Iniesta López" - title: "Ask your data! Build a full pipeline to get generative answers from a text dataset" - description: "The goal of this workshop is to teach attendees how to build a full pipeline to generate sentence embeddings from a given dataset, index them in a vector database for semantic search, and integrate search results as context for a LLM. " - start_time_slot: 14:00 - end_time_slot: 15:15 - track_length: 1 - color: purple - python_level: intermediate - topic_level: intermediate - type: workshop - location: Sala Margarita Salas - requirements: "Intermediate knowledge of Python programming, understanding of natural language processing and semantic search concepts, enthusiasm and willingness to learn and collaborate.<br/>Technical requirements: Laptop with python >= 3.9 installed and HF’s SentenceTransformers. Nucliadb is optional, if not installed we’ll do it together during the workshop. A requirements.txt and more details will be provided prior to the event." - language: "English" - topic: "Machine Learning, NLP, Semantic search, Generative AI " - - speaker: "Oriol Abril Pla" - title: "Com visualitzar incertesa i models probabilistics" - description: "Aprèn a visualitzar paràmetres i prediccions de models probabilístics emprant histogrames, estimadors nuclears de densitat (KDE), gràfics de punts per quantils i funcions de distribució empíriques" - start_time_slot: 14:00 - end_time_slot: 15:15 - track_length: 1 - color: grey - python_level: intermediate - topic_level: beginner - type: workshop - location: Aula Hipàtia d'Alexandria - requirements: "Cal certa comoditat a l'hora de treballar amb Python, NumPy i Matplotlib. Tots els gràfics seran introduïts abans d'utilitzar-se, però és recomanable tenir coneixements bàsics d'estadística." - language: "Catalan" - title_lang: Catalan - topic: "Data Visualization" - - - start_time_slot: 15:30 - end_time_slot: 15:45 - track_length: 4 - color: blue - title: "Coffee break" - type: coffee - location: Open-air terrace - class: middle - - - speaker: "Adrián García Riber, Albert Pujol Torras, Alvaro Duran Barata, Diego Quintana, Edgar Sarria, Miquel Sàrrias, Monica Dominguez, Rajdeep Pal, Ricardo Ander-Egg Aguilar, Sergi Baena, Thais Ruiz de Alda" - title: "Lightning talks session" - description: "<p><b>How Data Scientists Can Be More Productive with the Power of Static Typing</b> - Alvaro Duran<br/>Data scientists frequently find themselves in situations where they need to verify that some intermediate step in a data pipeline works as expected, and tools such as Jupiter notebooks, where each step is explicitly shown to the user, are very useful at that. However, it can become quite cumbersome and time-consuming as the data pipeline grows more complex.<br/>That's where static typing comes in. By using types in our code, we can introduce our data into a structured pipeline and catch errors early on, before they have the chance to cause any real problems. This is particularly useful when working with large datasets, where a small error can have a significant impact on our results.<br/>But what exactly do we mean by 'types'? Essentially, types are a way of specifying the kind of data that a variable or function will handle. For example, we might specify that a certain variable should only contain integers, or that a certain function should only accept strings.<br/>By using types, we can catch errors early on in the development process, rather than having to wait until runtime to discover them. This can save us a lot of time and effort in the long run, as we can catch errors before they have a chance to cause any real damage.<br/>Now, you might be thinking, 'but doesn't introducing types make our code more complex?' And the answer is, not necessarily. In fact, Python has built-in support for types that makes it easy to incorporate them into our code.<br/>Of course, that is just the first part of the puzzle. Good type systems are analogous to test suites: they require some effort, but the payoff is immense.<br/>This talk will cover the very basics of how data scientists can benefit from using types, not only on their production code, but even on crude prototypes, giving some peace of mind by making illegal states unrepresentable.</p><p><b>Astronomical data Sonification</b> - Adrián García Riber<br/>The current development of massive astronomical archives and virtual observatory technology (VO) offers a wide range of data products and services that can be explored with a personal computer through interoperable technology. The use of sonification and musification in multimodal displays for the exploration of astronomical data offers an additional domain (complementary to visualization), that allows researchers to get immersed in their case studies, navigating the massive downloads of big data generated by space telescopes, and that makes stellar catalogs and databases more accessible for blind-visually impaired (BVI) users. In this talk I would like to introduce the collection of Python and TensorFlow Sonification prototypes developed in my PhD to generate multimodal representations of astronomical data using Deep Learning and Neural Networks.</p><p><b>Python models and alerts within dbt with dbt-fal and novu</b> - Diego Quintana<br/>How to trigger alarms and run python models within dbt with dbt-fal and novu. <br/>dbt is the T in the ELT pipe. Although dbt allows for python model since version 1.3, its support is limited. dbt-fal enables running python models and python code in general within a model. A simple demo will be shown, with a forecasting model is trained as part of a dbt pipeline and an alarm is triggered with novu, an open source notification infrastructure.</p><p><b>Serverless Machine Learning: Streamlining Deployment and Scaling of ML Services</b> - Rajdeep Pal<br/>The topic of deploying machine learning services using a serverless architecture is focused on leveraging cloud computing services to simplify the deployment and scaling of machine learning models. Using a serverless approach, developers can focus on writing code for their ML models without worrying about infrastructure setup and management. The serverless model also provides automatic scaling of resources to meet the demands of incoming requests, reducing the need for manual intervention and ensuring that services remain highly available. This talk would cover the benefits of using a serverless approach to deploy machine learning services and provide practical guidance on how to implement it effectively. It would also explore the challenges and trade-offs involved in using serverless architecture for ML services, such as performance considerations, security, and cost optimisation.</p><p><b>Practical considerations when using chatGPT in production for multilanguage processing</b> - Albert Pujol Torras<br/>We will describe the results of empirical measurements of the behavior of LLMs to automate NLP processes depending on both the language in which the prompt is written, the lenguage of the text to be analyzed as well as some practical considerations to take into account when considering putting in production this type of Models.</p><p><b>International Data Spaces: Implementing the European Strategy on Data</b> - Miquel Sarrias<br/>The International Data Spaces (IDS) initiative aims at cross-sectoral data sovereignty and data interoperability. It sets forth a Reference Architecture Model basing on open standards and contributing to global standards. By specifying data usage constraints, it defines the terms and conditions for the data economy. Data spaces are key to the global, digital economy. The European Commission is defining Europe’s path forward into the digital economy of the future. A core element of their vision: international data spaces grounded in European values of trust and the self-determination of data usage by data providers, that we call data sovereignty.</p><p><b>Forecasting in the integral water cycle</b> - Sergi Baena-Miret<br/>Droughts can have severe impacts on water availability, demand, and quality, affecting water allocation, infrastructure planning, and environmental protection. Accurate forecasting of droughts is essential for mitigating their impacts by enabling effective water management strategies. Various techniques such as statistical models, machine learning, and remote sensing are used for drought forecasting in the integral water cycle. However, challenges such as data scarcity, non-stationarity, and uncertainty in climate change projections pose significant challenges for accurate forecasting.</p><p><b>MusicMetaData & algorithmic diversity perrspective</b> - Thais Ruiz de Alda<br/>We want to talk about the current challenge de music industry is facing around metadata and the challenges that including a gender perspective can imply. The talk will cover the story of music metadata and how Digitalfems is challenging the musical descriptive metadata status quo to develop an ADM system that will include gender diversity in a beta testing/lab environment with the support of different institutions such as FECYT, UPC and other relevant stakeholders</p><p><b>Free online Data Apps with Shimoku Library</b> - Edgar Sarria<br/>We will show how to use Shimoku instead of Streamlit to build Data Products in few lines of code</p><p><b>Data Science in Transport Modelling</b> - Monica Dominguez<br/>Transport modelling and traffic simulation have traditionally been branches of Civil Engineering and Applied Mathematics. In this talk, we will present how the field is embracing Data Science and Machine Learning methodologies for data processing, pattern analysis, forecasting and prediction of recurrent and non-recurrent events.</p><p><b>Bundling a Python app in a single file</b> - Ricardo Ander-Egg<br/>Live coding talk. This talk will show how to bundle a Python app and all of its dependencies in a single file. Then we will copy this file to a different machine and see how the script runs without having to deal with Docker or virtual environments.</p>" - requirements: "" - language: "English / Spanish" - topic: "Multiple topics" - start_time_slot: 16:00 - end_time_slot: 17:15 - track_length: 4 - color: yellow - type: talk - location: Sala d'actes Ada Lovelace - - - - start_time_slot: 17:30 - end_time_slot: 17:45 - track_length: 4 - color: blue - title: "Closing session & Kahoot" - speaker: "PyDataBCN Organising Committee" - type: group - location: Sala d'actes Ada Lovelace - class: middle - - --- ## About PyDataBCN 2023 diff --git a/content/events/pyday_bcn/pyday_bcn_2020.md b/content/events/pyday_bcn/pyday_bcn_2020.md index 97aee18e1..229109a93 100644 --- a/content/events/pyday_bcn/pyday_bcn_2020.md +++ b/content/events/pyday_bcn/pyday_bcn_2020.md @@ -1,6 +1,10 @@ --- title: "PyDay BCN (2020)" year: 2020 +# The day of this edition, from the Meetup export, which records it per event. +date: 2020-12-12 +# The venue of this edition, from the Meetup export, which records it per event. +venue: "Online" description: "The fourth edition!" menu: main: @@ -63,297 +67,372 @@ people_sections: - nuria-pujol-vilanova - ruben-berenguel -previous_editions: - - name: PyDay BCN 2019 - url: /events/pyday_bcn/pyday_bcn_2019/ - - name: PyDay BCN 2018 - url: /events/pyday_bcn/pyday_bcn_2018/ - - name: PyDay BCN 2016 - url: /events/pyday_bcn/pyday_bcn_2016/ - spansDuration: 15 numTracks: 2 -eventTimes: [16:00, 16:15, 16:30, 16:45, 17:00, 17:15, 17:30, 17:45, 18:00, 18:15, 18:30, 18:45, 19:00, 19:15, 19:30, 19:45, 20:00, 20:15, 20:30] -events: - - start_time_slot: 16:00 - end_time_slot: 16:00 - track_length: 2 - video: https://www.youtube.com/watch?v=oLB0eo7tpj0 - color: purple - title: "Welcome Session" - speaker: "Laura Pérez-Mayos" - location: https://www.youtube.com - type: group - location: YouTube track1 and track2 - - - start_time_slot: 16:15 - end_time_slot: 16:30 - track_length: 1 - video: https://www.youtube.com/watch?v=w9cYczex79M - color: orange - title: "Ready, Set, Go with Numba" - description: "The prominent reasons for the wide adoption of Python is the ease of learning, usability and readability coupled with the powerful ecosystem of Python packages. This often makes Python an attractive language for researchers & scholars to undertake computational projects and thesis. The ease of prototyping and tinkering allows for higher number of iterations and customization, leading to an increase in research output. But, a major pain point of using Python is its speed when compared to languages like C++ or FORTRAN which are still widely used in research.<br/><br/>Developers, when hit by the performance bottleneck of python code, often come across some methods to increase their code performance like using PyMPI, Numpy or CPython. But, the learning curve is steep and APIs get less familiar. <br/><br/>If learning Python is so easy, why should increasing the performance of Python code be so difficult?<br/><br/>This talk will address this question and get us up and running with Numba, an open source JIT compiler that translates Python and NumPy code into fast machine code. We will delve into real world exercises which will demonstrate the core concepts, ease and effectiveness of using Numba and how it can be useful in lowering the barrier to achieve code performance in Python." - language: "English" - speaker: "Ankit Mahato" - type: talk - python_level: beginner - topic: Data Science, ML, DL - location: YouTube track1 - - start_time_slot: 16:45 - end_time_slot: 17:00 - track_length: 1 - video: https://www.youtube.com/watch?v=uzjlrbqq26M - color: orange - title: "Working with Text Data in Pandas" - description: "I'll will present some tips, tricks and libraries to speed up text processing with pandas." - language: "Spanish" - speaker: "Daniel Mesejo" - type: talk - python_level: intermediate - topic: Data Science, ML, DL - location: YouTube track1 - - start_time_slot: 17:15 - end_time_slot: 17:15 - track_length: 1 - video: https://www.youtube.com/watch?v=Hnr7MH9Pd5s - color: orange - title: "Lifebox: a virtual ecosystem" - description: "Lifebox is a project about a virtual ecosystem created using Python. Inside the Lifebox you can find two different kind of species, the ‘species’ and the ‘mana’. Each of the ‘species’ have a set of parameters that defines how they evolve inside the virtual ecosystem, and you can change all the parameter of species in real-time. The goal of the project is to offer the possibility to learn the basic concepts of biology through the experimentation, viewing the consequences of your actions and trying to find the way to balance the ecosystem through changing the Lifebox parameters." - language: "Catalan" - speaker: "Ferran Fábregas" - type: lightning - python_level: intermediate - topic: Data Science, ML, DL - location: YouTube track1 - - start_time_slot: 17:30 - end_time_slot: 17:30 - track_length: 1 - video: https://www.youtube.com/watch?v=4oc0OTkks0k - color: orange - title: "Transformers: the all-in-one tool for NLP" - description: "NLP has been evolving from classic bag of words to embedding methods. But in 2017 finally a new model that can be used for all kind of NLP tasks emerged: transformers. Let's review its general ideas, and a practical example of its use." - language: "English" - speaker: "Julio Martínez" - type: lightning - python_level: intermediate - topic: Data Science, ML, DL - location: YouTube track1 - - start_time_slot: 17:45 - end_time_slot: 17:45 - video: https://www.youtube.com/watch?v=4-OPxy4CLAw - track_length: 1 - color: blue - title: "A Day Has Only 24±1 Hours" - description: "On the last Sunday of October you may get “one more hour of sleep” but as well may spend much more time debugging code dealing with the time zones, daylight saving time shifts and datetime stuff in general. Two centuries of short-sighted propaganda and long-term chaos in ten minutes. Maybe that will make you want to avoid time zones in your code altogether!<br/><br/>El último domingo de octubre puedes obtener “una hora más de sueño”, pero también puedes pasar mucho más tiempo debugando el código tratando con las zonas horarias, los cambios de horario de verano y las cosas de fecha y hora en general. Dos siglos de propaganda miope y caos a largo plazo en diez minutos. ¡Quizás eso te haga querer evitar las zonas horarias en tu código por completo!" - language: "English" - speaker: "Miroslav Šedivý" - type: lightning - python_level: intermediate - topic: Python programming - location: YouTube track1 - - start_time_slot: 18:00 - end_time_slot: 18:00 - video: https://www.youtube.com/watch?v=B0YM3XkNkQs - track_length: 1 - color: blue - title: "Ho sento, no ets el meu tipus" - description: "Type Hints were introduced in Python 3 but you may have never used them, known that they exist, or seen code that uses them. Or you may have seen code with type hints and cringed because it didn't look like the Python you know. In this talk we will demistify type hints and show how they can actually help you find potential bugs." - language: "Catalan" - title_lang: Catalan - speaker: "Carles Barrobés" - type: lightning - python_level: intermediate - topic: Python programming - location: YouTube track1 - - - start_time_slot: 16:15 - end_time_slot: 16:30 - track_length: 1 - video: https://www.youtube.com/watch?v=8UjkfOKh6jA - color: yellow - title: "Alexa, te elijo a ti" - description: "Algunos de nosotros tenemos un aparatito en casa escuchándonos 24/7 que usamos para escuchar música, preguntarle la hora y pedirle un temporizador o un chiste malo. En esta charla os voy a enseñar como programar a Alexa usando Python para que os ayude en vuestras tareas usando dos ejemplos: una skill que nos calculará equivalencias para ayudarnos en las recetas de cocina (entre otras cosas) y otra que nos aconsejará sobre qué tipo de Pokémon elegir para enfrentarnos a un oponente." - language: "Spanish" - title_lang: Spanish - speaker: "Elisabeth Ortega Carrasco" - type: talk - python_level: beginner - topic: IOT - location: YouTube track2 - - start_time_slot: 16:45 - end_time_slot: 17:00 - video: https://www.youtube.com/watch?v=Se3FmYvn6sM - track_length: 1 - color: green - title: "Network automation using Python" - description: "I will share the status of network automation using Python, presenting and demoing some popular libraries such as Netmiko, Napalm and Nornir." - language: "English" - speaker: "Christian Adell" - type: talk - python_level: intermediate - topic: Network automation - location: YouTube track2 - - start_time_slot: 17:15 - end_time_slot: 17:15 - track_length: 1 - video: https://www.youtube.com/watch?v=kwa58dEhPNY - color: blue - title: "Retrying, a better way" - description: "Python have a lot of libraries, for multiple purposes, and among them there are a lot of hidden gems, such as the Backoff library (https://github.com/litl/backoff) which will make retrying operations based on exceptions or predicates an easy game.<br/>Handling retries have never been so simple." - language: "English" - speaker: "Christian Adell" - type: lightning - python_level: beginner - topic: Python programming - location: YouTube track2 - - start_time_slot: 17:30 - end_time_slot: 17:30 - video: https://www.youtube.com/watch?v=S3ebYJxXBRU - track_length: 1 - color: blue - title: "Antifragile Software: Code that gains from disorder" - description: "Joel Spolsky famously said that you should never rewrite your code from scratch. Still, many organizations see no other way out of their codebases. Why? In this talk we explore the concept of antifragility, and how it can be applied to software engineer to keep your codebase from getting \"rusty\"." - language: "English" - speaker: "Alvaro Duran" - type: lightning - python_level: beginner - topic: Python programming - location: YouTube track2 - - start_time_slot: 17:45 - end_time_slot: 18:00 - track_length: 1 - video: https://www.youtube.com/watch?v=cmi4B41oOd8 - color: green - title: "Efficiently share data on a true microservices architecture using django-cqrs (CloudBlue sponsored talk)" - type: talk - location: YouTube track2 - topic: Web development, microservices - language: "English" - python_level: intermediate - speaker: Francesco Faraone - - - start_time_slot: 18:15 - end_time_slot: 18:15 - track_length: 2 - color: purple - title: "Coffee Break" - type: coffee +eventTimes: ["16:00", "16:15", "16:30", "16:45", "17:00", "17:15", "17:30", "17:45", "18:00", "18:15", "18:30", "18:45", "19:00", "19:15", "19:30", "19:45", "20:00", "20:15", "20:30"] - - start_time_slot: 18:30 - end_time_slot: 18:45 - track_length: 1 - video: https://www.youtube.com/watch?v=v75bTfShH-M - color: orange - title: "Performing Sentiment Analysis on Video with Serverless Architectures" - description: "In this talk we will explain how to create video processing pipelines using an event-driven and fully Serverless Architecture in AWS. We will use AWS Chalice, a Python framework from AWS, for managing the serverless Lambda Functions and a range variety of AWS services for the video manipulation like AWS Elastic Transcoder, Amazon Transcribe, Amazon Comprehend. And of course the more common architectural and traditional services like S3, DynamoDB, Gateway, SQS, SNS and SES." - language: "English" - speaker: "Eduard Cespedes Borras" - type: talk - python_level: intermediate - topic: Data Science, ML, DL - location: YouTube track1 - - start_time_slot: 19:00 - end_time_slot: 19:15 - video: https://www.youtube.com/watch?v=KOpW86J56CU - track_length: 1 - color: orange - title: "Counting votes: analyzing a large dataset with Dask" - description: "We will explain how to switch from Pandas to Dask in order to analyze a large dataset that does not fit into single-machine memory.<br/><br/>Repository: <a href='https://github.com/ber2/pyday2020-counting-votes-with-dask' target='_blank'>https://github.com/ber2/pyday2020-counting-votes-with-dask</a>" - language: "English" - speaker: "Alberto Camara" - type: talk - python_level: intermediate - topic: Data Science, ML, DL - location: YouTube track1 - - start_time_slot: 19:30 - end_time_slot: 19:45 - track_length: 1 - video: https://www.youtube.com/watch?v=uUwmknHAIhU - color: orange - title: "Kornia: differentiable Computer Vision with Pytorch" - description: "The talk is an introduction to Kornia which is a library that implements classical Computer Vision algorithms in PyTorch that got a lot of attention within the open source community during the last year. The core of the library is written from scratch using pure PyTorch operators and uses the auto-reverse differentiable engine to allow to the user to plug any function within neural networks with a transparent API for high performance devices such as GPUs and TPUs. During the talk I'll go through the different principle designs and the functionalities found in each of the modules, practical examples, basic usage of the library and more. Information about the project in the website: www.kornia.org" - language: "English" - speaker: "Edgar Riba" - type: talk - python_level: intermediate - topic: Data Science, ML, DL - location: YouTube track1 - - start_time_slot: 20:00 - end_time_slot: 20:15 - track_length: 1 - video: https://www.youtube.com/watch?v=UtK-npeVsH0 - color: orange - title: "JINA AI: An Open Source Neural Search Framework" - description: "What is neural or semantic search? How is it different from traditional symbolic search? Jina AI is an open source framework for AI-powered search." - language: "English" - speaker: "Joan Fontanals Martinez" - type: talk - python_level: beginner - topic: Data Science, ML, DL - location: YouTube track1 +# The rooms of this edition, in the order the grid first names them. A room is +# a record with an id because the colour of a block now comes from it: the +# template gives every room of an event one colour of the agenda palette and +# keeps it for the whole day. See partials/agenda_entry.html. +rooms: + - id: youtube-track1-and-track2 + name: "YouTube track1 and track2" + - id: youtube-track1 + name: "YouTube track1" + - id: youtube-track2 + name: "YouTube track2" + - id: zoom + name: "Zoom" - - start_time_slot: 18:30 - end_time_slot: 18:45 - track_length: 1 - video: https://www.youtube.com/watch?v=nWVJ7HfFC5E - color: yellow - title: "Building My First Python IoT Device with Containers (in 20 minutes)" - description: "This workshop is designed for developers who are coming from Web development and other technologies into the Internet of Things. This session will guide assistants how to connect an Arm-powered device such as a Raspberry Pi to the Internet with balena and open source tools." - language: "English" - speaker: "Marc Pous" - type: talk - python_level: beginner - topic: IOT - location: YouTube track2 - - start_time_slot: 19:00 - end_time_slot: 19:15 - track_length: 1 - video: https://www.youtube.com/watch?v=BoaGrcmfVH8 - color: green - title: "Documentation-driven development for Python web APIs" - description: "In this presentation, I want to show how developers can minimise the risk of API integration failures by using documentation-driven development. Documentation-driven development is an approach where we first write the API documentation, and then we validate the API implementation against the specification. This approach helps us create a more robust software delivery process for our APIs. I’ll show useful tools and frameworks, such as Dredd, that can help us automatically generate tests that validate our APIs. " - language: "English" - speaker: "Jose Haro Peralta" - type: talk - python_level: beginner - topic: Web - location: YouTube track2 - - start_time_slot: 19:30 - end_time_slot: 19:45 - video: https://www.youtube.com/watch?v=LvvwLYk9aIo - track_length: 1 - color: blue - title: "Alice in Pythonland: Object oriented programming in Lewis Carroll games" - description: "Tutorial regarding object oriented programming in Python. The applications that will be presented are some of the maths games hidden in the book Alice in Wonderland of Lewis Carroll. These games are algorimths pubblished by Lewis Carroll on scientific journals. My contribution would be to explain oop techniques (inheritance,decorators,dataclass, nametuple,...) for developing maths games and use some NLP techniques (i.e., finding the dialogs between charcaters in the books) for presenting the interactions between the playes involved in the game.<br/>I have been inspired by a repository from Anna-Lena Popkes<br/>(please see https://github.com/zotroneneis/magical_universe) on working on one programming topic per day. In this way, I have improved my coding skills day by day and I have created the a Wonderland Universe. The idea of coding the games created by Lewis Carroll is related to my maths background and has the intent of explain some joyful algorithms. My goal is to encourage other people to use the same learning technique and challege theiself with custom examples and applications." - language: "English" - speaker: "Maria Teresa Grifa" - type: talk - python_level: beginner - topic: Python programming - location: YouTube track2 - - start_time_slot: 20:00 - end_time_slot: 20:15 - track_length: 1 - video: https://www.youtube.com/watch?v=LAQY4ucheQA - color: green - title: "Investigating Digital Crimes using Python" - description: "A recent study by CheckPoint Research has recorded over 1,50,000 cyber-attacks every week during the COVID-19 pandemic. There has been an increase of 30% in cyber-attacks compared to previous weeks. The pandemic has been the main reason for job loss and pay cuts of people and has led to an increase in cybercrimes. Examples of cyber-attacks include phishing, ransomware, fake news, fake medicine, extortion, and insider frauds. Cyber forensics is a field that deals with the investigation of digital crimes by analyzing, examining, identifying, and recovering digital evidence from electronic devices and producing them in the court of law. Python has a great collection of built-in modules for digital forensics tasks. The talk begins with an introduction to digital crimes, digital forensics, the process of investigation, and the collection of evidence. Next, I will discuss report creation using CSV and Excel reports, investigation of acquisition media using the pyscreenshot module. Finally, I will conclude the talk with the investigation of embedded metadata, emails, and log files. In this talk, I will cover mutagen, mailbox, tqdm, argparser, yara python modules, and utilities which are used for the above-mentioned tasks.<br/><br/>In this talk, the audience will learn the procedure to be followed while investigating digital crimes and most importantly how to develop their own digital forensic tools using Python. I believe that the attendees will learn about the new exciting field where there are lots of opportunities with respect to their careers. Basic understanding of Python language or any other scripting language will be helpful in understanding the concepts.<br/><br/>Outline 1. Introduction to digital crimes, digital forensics, the process of investigation, and collection of evidence. [05 Minutes] 2. Report creation using CSV and Excel reports [04 Minutes] 3. Investigation of acquisition media using the pyscreenshot module [03 Minutes] 4. Investigation of embedded metadata [05 Minutes] 5. Investigation of emails [05 Minutes] 6. Investigation of log files [05 Minutes] 7. Conclusion and Questions [03 Minutes]" - language: "English" - speaker: "Gajendra Deshpande" - type: talk - python_level: beginner - topic: Security - location: YouTube track2 +# The talks of this edition: what was said, by whom, in which language. A talk +# carries no time and no room, because it is the content and not the slot. +# agenda below is what places it on the grid, and one talk can take more than +# one slot. The id is derived from the title and is the anchor a photo of the +# gallery links to, so it must not change. +talks: + - id: ready-set-go-with-numba + title: "Ready, Set, Go with Numba" + speakers: [ankit-mahato] + type: talk + language: en + topic: "Data Science, ML, DL" + duration_minutes: 15 + description: "The prominent reasons for the wide adoption of Python is the ease of learning, usability and readability coupled with the powerful ecosystem of Python packages. This often makes Python an attractive language for researchers & scholars to undertake computational projects and thesis. The ease of prototyping and tinkering allows for higher number of iterations and customization, leading to an increase in research output. But, a major pain point of using Python is its speed when compared to languages like C++ or FORTRAN which are still widely used in research.<br/><br/>Developers, when hit by the performance bottleneck of python code, often come across some methods to increase their code performance like using PyMPI, Numpy or CPython. But, the learning curve is steep and APIs get less familiar. <br/><br/>If learning Python is so easy, why should increasing the performance of Python code be so difficult?<br/><br/>This talk will address this question and get us up and running with Numba, an open source JIT compiler that translates Python and NumPy code into fast machine code. We will delve into real world exercises which will demonstrate the core concepts, ease and effectiveness of using Numba and how it can be useful in lowering the barrier to achieve code performance in Python." + links: + - type: video + url: "https://www.youtube.com/watch?v=w9cYczex79M" + - id: working-with-text-data-in-pandas + title: "Working with Text Data in Pandas" + speakers: [daniel-mesejo-leon] + type: talk + language: es + topic: "Data Science, ML, DL" + duration_minutes: 15 + description: "I'll will present some tips, tricks and libraries to speed up text processing with pandas." + links: + - type: video + url: "https://www.youtube.com/watch?v=uzjlrbqq26M" + - id: lifebox-a-virtual-ecosystem + title: "Lifebox: a virtual ecosystem" + speakers: [ferran-fabregas] + type: lightning + language: ca + topic: "Data Science, ML, DL" + duration_minutes: 0 + description: "Lifebox is a project about a virtual ecosystem created using Python. Inside the Lifebox you can find two different kind of species, the 'species' and the 'mana'. Each of the 'species' have a set of parameters that defines how they evolve inside the virtual ecosystem, and you can change all the parameter of species in real-time. The goal of the project is to offer the possibility to learn the basic concepts of biology through the experimentation, viewing the consequences of your actions and trying to find the way to balance the ecosystem through changing the Lifebox parameters." + links: + - type: video + url: "https://www.youtube.com/watch?v=Hnr7MH9Pd5s" + - id: transformers-the-all-in-one-tool-for-nlp + title: "Transformers: the all-in-one tool for NLP" + speakers: [julio-martinez] + type: lightning + language: en + topic: "Data Science, ML, DL" + duration_minutes: 0 + description: "NLP has been evolving from classic bag of words to embedding methods. But in 2017 finally a new model that can be used for all kind of NLP tasks emerged: transformers. Let's review its general ideas, and a practical example of its use." + links: + - type: video + url: "https://www.youtube.com/watch?v=4oc0OTkks0k" + - id: a-day-has-only-24-1-hours + title: "A Day Has Only 24±1 Hours" + speakers: [miroslav-sedivy] + type: lightning + language: en + topic: "Python programming" + duration_minutes: 0 + description: "On the last Sunday of October you may get \"one more hour of sleep\" but as well may spend much more time debugging code dealing with the time zones, daylight saving time shifts and datetime stuff in general. Two centuries of short-sighted propaganda and long-term chaos in ten minutes. Maybe that will make you want to avoid time zones in your code altogether!<br/><br/>El último domingo de octubre puedes obtener \"una hora más de sueño\", pero también puedes pasar mucho más tiempo debugando el código tratando con las zonas horarias, los cambios de horario de verano y las cosas de fecha y hora en general. Dos siglos de propaganda miope y caos a largo plazo en diez minutos. ¡Quizás eso te haga querer evitar las zonas horarias en tu código por completo!" + links: + - type: video + url: "https://www.youtube.com/watch?v=4-OPxy4CLAw" + - id: ho-sento-no-ets-el-meu-tipus + title: "Ho sento, no ets el meu tipus" + title_lang: Catalan + speakers: [carles-barrobes] + type: lightning + language: ca + topic: "Python programming" + duration_minutes: 0 + description: "Type Hints were introduced in Python 3 but you may have never used them, known that they exist, or seen code that uses them. Or you may have seen code with type hints and cringed because it didn't look like the Python you know. In this talk we will demistify type hints and show how they can actually help you find potential bugs." + links: + - type: video + url: "https://www.youtube.com/watch?v=B0YM3XkNkQs" + - id: alexa-te-elijo-a-ti + title: "Alexa, te elijo a ti" + title_lang: Spanish + speakers: [elisabeth-ortega-carrasco] + type: talk + language: es + topic: "IOT" + duration_minutes: 15 + description: "Algunos de nosotros tenemos un aparatito en casa escuchándonos 24/7 que usamos para escuchar música, preguntarle la hora y pedirle un temporizador o un chiste malo. En esta charla os voy a enseñar como programar a Alexa usando Python para que os ayude en vuestras tareas usando dos ejemplos: una skill que nos calculará equivalencias para ayudarnos en las recetas de cocina (entre otras cosas) y otra que nos aconsejará sobre qué tipo de Pokémon elegir para enfrentarnos a un oponente." + links: + - type: video + url: "https://www.youtube.com/watch?v=8UjkfOKh6jA" + - id: network-automation-using-python + title: "Network automation using Python" + speakers: [christian-adell] + type: talk + language: en + topic: "Network automation" + duration_minutes: 15 + description: "I will share the status of network automation using Python, presenting and demoing some popular libraries such as Netmiko, Napalm and Nornir." + links: + - type: video + url: "https://www.youtube.com/watch?v=Se3FmYvn6sM" + - id: retrying-a-better-way + title: "Retrying, a better way" + speakers: [christian-adell] + type: lightning + language: en + topic: "Python programming" + duration_minutes: 0 + description: "Python have a lot of libraries, for multiple purposes, and among them there are a lot of hidden gems, such as the Backoff library (https://github.com/litl/backoff) which will make retrying operations based on exceptions or predicates an easy game.<br/>Handling retries have never been so simple." + links: + - type: video + url: "https://www.youtube.com/watch?v=kwa58dEhPNY" + - id: antifragile-software-code-that-gains-from-disorder + title: "Antifragile Software: Code that gains from disorder" + speakers: [alvaro-duran-barata] + type: lightning + language: en + topic: "Python programming" + duration_minutes: 0 + description: "Joel Spolsky famously said that you should never rewrite your code from scratch. Still, many organizations see no other way out of their codebases. Why? In this talk we explore the concept of antifragility, and how it can be applied to software engineer to keep your codebase from getting \"rusty\"." + links: + - type: video + url: "https://www.youtube.com/watch?v=S3ebYJxXBRU" + - id: efficiently-share-data-on-a-true-microservices-architecture + title: "Efficiently share data on a true microservices architecture using django-cqrs (CloudBlue sponsored talk)" + speakers: [francesco-faraone] + type: talk + language: en + topic: "Web development, microservices" + duration_minutes: 15 + links: + - type: video + url: "https://www.youtube.com/watch?v=cmi4B41oOd8" + - id: performing-sentiment-analysis-on-video-with-serverless + title: "Performing Sentiment Analysis on Video with Serverless Architectures" + speakers: [eduard-cespedes-borras] + type: talk + language: en + topic: "Data Science, ML, DL" + duration_minutes: 15 + description: "In this talk we will explain how to create video processing pipelines using an event-driven and fully Serverless Architecture in AWS. We will use AWS Chalice, a Python framework from AWS, for managing the serverless Lambda Functions and a range variety of AWS services for the video manipulation like AWS Elastic Transcoder, Amazon Transcribe, Amazon Comprehend. And of course the more common architectural and traditional services like S3, DynamoDB, Gateway, SQS, SNS and SES." + links: + - type: video + url: "https://www.youtube.com/watch?v=v75bTfShH-M" + - id: counting-votes-analyzing-a-large-dataset-with-dask + title: "Counting votes: analyzing a large dataset with Dask" + speakers: [alberto-camara] + type: talk + language: en + topic: "Data Science, ML, DL" + duration_minutes: 15 + description: "We will explain how to switch from Pandas to Dask in order to analyze a large dataset that does not fit into single-machine memory.<br/><br/>Repository: <a href='https://github.com/ber2/pyday2020-counting-votes-with-dask' target='_blank'>https://github.com/ber2/pyday2020-counting-votes-with-dask</a>" + links: + - type: video + url: "https://www.youtube.com/watch?v=KOpW86J56CU" + - id: kornia-differentiable-computer-vision-with-pytorch + title: "Kornia: differentiable Computer Vision with Pytorch" + speakers: [edgar-riba] + type: talk + language: en + topic: "Data Science, ML, DL" + duration_minutes: 15 + description: "The talk is an introduction to Kornia which is a library that implements classical Computer Vision algorithms in PyTorch that got a lot of attention within the open source community during the last year. The core of the library is written from scratch using pure PyTorch operators and uses the auto-reverse differentiable engine to allow to the user to plug any function within neural networks with a transparent API for high performance devices such as GPUs and TPUs. During the talk I'll go through the different principle designs and the functionalities found in each of the modules, practical examples, basic usage of the library and more. Information about the project in the website: www.kornia.org" + links: + - type: video + url: "https://www.youtube.com/watch?v=uUwmknHAIhU" + - id: jina-ai-an-open-source-neural-search-framework + title: "JINA AI: An Open Source Neural Search Framework" + speakers: [joan-fontanals-martinez] + type: talk + language: en + topic: "Data Science, ML, DL" + duration_minutes: 15 + description: "What is neural or semantic search? How is it different from traditional symbolic search? Jina AI is an open source framework for AI-powered search." + links: + - type: video + url: "https://www.youtube.com/watch?v=UtK-npeVsH0" + - id: building-my-first-python-iot-device-with-containers-in-20 + title: "Building My First Python IoT Device with Containers (in 20 minutes)" + speakers: [marc-pous] + type: talk + language: en + topic: "IOT" + duration_minutes: 15 + description: "This workshop is designed for developers who are coming from Web development and other technologies into the Internet of Things. This session will guide assistants how to connect an Arm-powered device such as a Raspberry Pi to the Internet with balena and open source tools." + links: + - type: video + url: "https://www.youtube.com/watch?v=nWVJ7HfFC5E" + - id: documentation-driven-development-for-python-web-apis + title: "Documentation-driven development for Python web APIs" + speakers: [jose-haro-peralta] + type: talk + language: en + topic: "Web" + duration_minutes: 15 + description: "In this presentation, I want to show how developers can minimise the risk of API integration failures by using documentation-driven development. Documentation-driven development is an approach where we first write the API documentation, and then we validate the API implementation against the specification. This approach helps us create a more robust software delivery process for our APIs. I'll show useful tools and frameworks, such as Dredd, that can help us automatically generate tests that validate our APIs. " + links: + - type: video + url: "https://www.youtube.com/watch?v=BoaGrcmfVH8" + - id: alice-in-pythonland-object-oriented-programming-in-lewis + title: "Alice in Pythonland: Object oriented programming in Lewis Carroll games" + speakers: [maria-teresa-grifa] + type: talk + language: en + topic: "Python programming" + duration_minutes: 15 + description: "Tutorial regarding object oriented programming in Python. The applications that will be presented are some of the maths games hidden in the book Alice in Wonderland of Lewis Carroll. These games are algorimths pubblished by Lewis Carroll on scientific journals. My contribution would be to explain oop techniques (inheritance,decorators,dataclass, nametuple,...) for developing maths games and use some NLP techniques (i.e., finding the dialogs between charcaters in the books) for presenting the interactions between the playes involved in the game.<br/>I have been inspired by a repository from Anna-Lena Popkes<br/>(please see https://github.com/zotroneneis/magical_universe) on working on one programming topic per day. In this way, I have improved my coding skills day by day and I have created the a Wonderland Universe. The idea of coding the games created by Lewis Carroll is related to my maths background and has the intent of explain some joyful algorithms. My goal is to encourage other people to use the same learning technique and challege theiself with custom examples and applications." + links: + - type: video + url: "https://www.youtube.com/watch?v=LvvwLYk9aIo" + - id: investigating-digital-crimes-using-python + title: "Investigating Digital Crimes using Python" + speakers: [gajendra-deshpande] + type: talk + language: en + topic: "Security" + duration_minutes: 15 + description: "A recent study by CheckPoint Research has recorded over 1,50,000 cyber-attacks every week during the COVID-19 pandemic. There has been an increase of 30% in cyber-attacks compared to previous weeks. The pandemic has been the main reason for job loss and pay cuts of people and has led to an increase in cybercrimes. Examples of cyber-attacks include phishing, ransomware, fake news, fake medicine, extortion, and insider frauds. Cyber forensics is a field that deals with the investigation of digital crimes by analyzing, examining, identifying, and recovering digital evidence from electronic devices and producing them in the court of law. Python has a great collection of built-in modules for digital forensics tasks. The talk begins with an introduction to digital crimes, digital forensics, the process of investigation, and the collection of evidence. Next, I will discuss report creation using CSV and Excel reports, investigation of acquisition media using the pyscreenshot module. Finally, I will conclude the talk with the investigation of embedded metadata, emails, and log files. In this talk, I will cover mutagen, mailbox, tqdm, argparser, yara python modules, and utilities which are used for the above-mentioned tasks.<br/><br/>In this talk, the audience will learn the procedure to be followed while investigating digital crimes and most importantly how to develop their own digital forensic tools using Python. I believe that the attendees will learn about the new exciting field where there are lots of opportunities with respect to their careers. Basic understanding of Python language or any other scripting language will be helpful in understanding the concepts.<br/><br/>Outline 1. Introduction to digital crimes, digital forensics, the process of investigation, and collection of evidence. [05 Minutes] 2. Report creation using CSV and Excel reports [04 Minutes] 3. Investigation of acquisition media using the pyscreenshot module [03 Minutes] 4. Investigation of embedded metadata [05 Minutes] 5. Investigation of emails [05 Minutes] 6. Investigation of log files [05 Minutes] 7. Conclusion and Questions [03 Minutes]" + links: + - type: video + url: "https://www.youtube.com/watch?v=LAQY4ucheQA" + - id: kahoot-game-and-closing-remarks + title: "Kahoot game and closing remarks" + type: workshop + duration_minutes: 0 - - start_time_slot: 20:30 - end_time_slot: 20:30 - track_length: 2 - color: purple - title: "Kahoot game and closing remarks" - location: Zoom - type: workshop +# The grid, one row per slot of the day, in the order it is printed. A slot +# names the talk it holds, or carries its own label and type when it holds +# none: a break, the group photo, the welcome. The level and the requirements +# sit here and not on the talk, because they are what the slot asks of whoever +# walks into it. A start is always quoted: YAML 1.1 reads an unquoted 9:00 as +# the integer 540. +agenda: + - start: "16:00" + track_length: 2 + room: youtube-track1-and-track2 + type: group + label: "Welcome Session" + speakers: [laura-perez-mayos] + duration_minutes: 0 + links: + - type: video + url: "https://www.youtube.com/watch?v=oLB0eo7tpj0" + - start: "16:15" + track_length: 1 + room: youtube-track1 + talk: ready-set-go-with-numba + python_level: beginner + - start: "16:45" + track_length: 1 + room: youtube-track1 + talk: working-with-text-data-in-pandas + python_level: intermediate + - start: "17:15" + track_length: 1 + room: youtube-track1 + talk: lifebox-a-virtual-ecosystem + python_level: intermediate + - start: "17:30" + track_length: 1 + room: youtube-track1 + talk: transformers-the-all-in-one-tool-for-nlp + python_level: intermediate + - start: "17:45" + track_length: 1 + room: youtube-track1 + talk: a-day-has-only-24-1-hours + python_level: intermediate + - start: "18:00" + track_length: 1 + room: youtube-track1 + talk: ho-sento-no-ets-el-meu-tipus + python_level: intermediate + - start: "16:15" + track_length: 1 + room: youtube-track2 + talk: alexa-te-elijo-a-ti + python_level: beginner + - start: "16:45" + track_length: 1 + room: youtube-track2 + talk: network-automation-using-python + python_level: intermediate + - start: "17:15" + track_length: 1 + room: youtube-track2 + talk: retrying-a-better-way + python_level: beginner + - start: "17:30" + track_length: 1 + room: youtube-track2 + talk: antifragile-software-code-that-gains-from-disorder + python_level: beginner + - start: "17:45" + track_length: 1 + room: youtube-track2 + talk: efficiently-share-data-on-a-true-microservices-architecture + python_level: intermediate + - start: "18:15" + track_length: 2 + type: coffee + label: "Coffee Break" + duration_minutes: 0 + - start: "18:30" + track_length: 1 + room: youtube-track1 + talk: performing-sentiment-analysis-on-video-with-serverless + python_level: intermediate + - start: "19:00" + track_length: 1 + room: youtube-track1 + talk: counting-votes-analyzing-a-large-dataset-with-dask + python_level: intermediate + - start: "19:30" + track_length: 1 + room: youtube-track1 + talk: kornia-differentiable-computer-vision-with-pytorch + python_level: intermediate + - start: "20:00" + track_length: 1 + room: youtube-track1 + talk: jina-ai-an-open-source-neural-search-framework + python_level: beginner + - start: "18:30" + track_length: 1 + room: youtube-track2 + talk: building-my-first-python-iot-device-with-containers-in-20 + python_level: beginner + - start: "19:00" + track_length: 1 + room: youtube-track2 + talk: documentation-driven-development-for-python-web-apis + python_level: beginner + - start: "19:30" + track_length: 1 + room: youtube-track2 + talk: alice-in-pythonland-object-oriented-programming-in-lewis + python_level: beginner + - start: "20:00" + track_length: 1 + room: youtube-track2 + talk: investigating-digital-crimes-using-python + python_level: beginner + - start: "20:30" + track_length: 2 + room: zoom + talk: kahoot-game-and-closing-remarks - +# No photos. This edition was online, so the account posted no photo of a room +# and no photo of a speaker. The one picture it did post was a screen capture of +# the sponsors section of this very page, which printed the sponsors a second +# time, so the gallery is empty rather than padded with the page itself. The +# thread of the day is https://x.com/PyBCN/status/1337808647188066305. --- ## What is PyDay BCN 2020 about? @@ -370,4 +449,3 @@ PyDay BCN 2020 will have different **thematic tracks** --e.g. data science, web ### Sponsor us! -Would you like to sponsor PyDay BCN 2020? Have a look at the [sponsorship brochure](https://bit.ly/pydaybcn-2020-sponsoring)! diff --git a/content/events/pyday_bcn/pyday_bcn_2021.md b/content/events/pyday_bcn/pyday_bcn_2021.md index 781e7a0a5..f482f3831 100644 --- a/content/events/pyday_bcn/pyday_bcn_2021.md +++ b/content/events/pyday_bcn/pyday_bcn_2021.md @@ -1,6 +1,10 @@ --- title: "PyDay BCN (2021)" year: 2021 +# The day of this edition, from the Meetup export, which records it per event. +date: 2021-11-27 +# The venue of this edition, from the Meetup export, which records it per event. +venue: "Canòdrom" description: "Post-pandemic edition!" menu: main: @@ -75,19 +79,9 @@ people_sections: - eloi-puertas-prats - mireia-alvarez-dominguez -previous_editions: - - name: PyDay BCN 2020 - url: /events/pyday_bcn/pyday_bcn_2020/ - - name: PyDay BCN 2019 - url: /events/pyday_bcn/pyday_bcn_2019/ - - name: PyDay BCN 2018 - url: /events/pyday_bcn/pyday_bcn_2018/ - - name: PyDay BCN 2016 - url: /events/pyday_bcn/pyday_bcn_2016/ - spansDuration: 15 numTracks: 4 -eventTimes: [9:00, 9:15, 9:30, 9:45, 10:00, 10:15, 10:30, 10:45, 11:00, 11:15, 11:30, 11:45, 12:00, 12:15, 12:30, 12:45, 13:00, 13:15, 13:30, 13:45, 14:00, 14:15, 14:30, 14:45, 15:00, 15:15, 15:30, 15:45, 16:00, 16:15, 16:30, 16:45, 17:00, 17:15, 17:30, 17:45] +eventTimes: ["9:00", "9:15", "9:30", "9:45", "10:00", "10:15", "10:30", "10:45", "11:00", "11:15", "11:30", "11:45", "12:00", "12:15", "12:30", "12:45", "13:00", "13:15", "13:30", "13:45", "14:00", "14:15", "14:30", "14:45", "15:00", "15:15", "15:30", "15:45", "16:00", "16:15", "16:30", "16:45", "17:00", "17:15", "17:30", "17:45"] legend: - type: workshop - type: talk @@ -97,309 +91,334 @@ legend: - level: advanced - separator: true - type: sponsor -events: - - start_time_slot: 9:00 - end_time_slot: 9:15 - track_length: 4 - color: purple - title: "Registration & Welcome" - speaker: "PyDay BCN 2021 Organising Committee" - type: group - location: Open-air terrace - class: middle - - - speaker: "Sergi Ortiz" - title: "How to create Data apps with Python" - description: "Data products are the future of data. And Data Apps (and AI Apps) are an important chunk of this future. For Python coders there are many frictions to create Data Apps nowadays, we will try to address them all and create a Data App (FE - BE and DevOps) during the hands on session" - start_time_slot: 9:30 - end_time_slot: 10:45 - track_length: 1 - color: green - language: "Spanish" - type: workshop - topic: Data Apps - python_level: intermediate - topic_level: beginner - location: Room Actes - - speaker: "Diego Gonzalez" - sponsor: Preply - title: "Build a chat application that lets you speak multiple languages" - description: "Learn how to build a chat application that can translate messages across multiple languages using only a few technologies (Python among them, of course!)" - start_time_slot: 9:30 - end_time_slot: 10:45 - track_length: 1 - color: orange - language: "English" - type: workshop - topic: Web development - python_level: intermediate - topic_level: intermediate - location: Room Guinardó - - speaker: "Esperanza Buitrago" - title: "Implementing your API with FASTAPI" - description: "Implement your API with FastAPI from scratch and make it run in local." - start_time_slot: 9:30 - end_time_slot: 10:45 - track_length: 1 - color: green - language: "English" - type: workshop - topic: Software Engineering - python_level: beginner - topic_level: beginner - location: Room Gòtica - requirements: "<ul><li>Python3</li><li>Visual Studio Code</li><li>Pip3</li><li>Conda</li><li>We'll do everything from scratch: such as installing FastAPI, uvicorn and typing</li></ul>" - - - speaker: "Anton Caceres, Alexandre Savio" - title: "Building the Cloud with Python: getting started with AWS CDK" - description: "With emerging cloud technologies it is just a matter of time until most backends run in serverless or container-based environments. This workshop is showcasing a recently released open-source Cloud Development Kit by Amazon, which lets us control cloud resources just like we control our application logic - in pure Python. - CDK offers high-level abstraction to define AWS resources imperatively as customizable and reusable Python classes. Unfortunately, there are not many tutorials available yet and the documentation is limited. So we will be happy to share with you how to: 1) Break down AWS infrastructure into reusable constructs represented by Python classes; 2) Combine own and public constructs into Stack applications; 3) Deploy CDK apps to AWS cloud" - start_time_slot: 9:30 - end_time_slot: 10:45 - track_length: 1 - color: red - language: "English" - type: workshop - topic: Cloud-native Python applications - python_level: intermediate - topic_level: beginner - location: Room Raval - requirements: "Python 3.8+" - - - start_time_slot: 11:00 - end_time_slot: 11:15 - track_length: 4 - color: purple - title: "Coffee Break" - sponsor: Bling - type: coffee - location: Open-air terrace - class: middle - - - speaker: "Elisabeth Ortega" - title: "Creating cute user interfaces in python with Qt" - description: "Most of us learn to use python as a command line tool, asking information to the users and passing them to the code as arguments. Some of us later moved to Django and related web development tools, to have a better interaction with the user paying the cost of fighting against the web layout in different languages. Few of us faced tkinter to build our first user interfaces with more or less success, but almost none of us were happy with the result of the user interfaces created in pure python.<br/>In \"Creating cute user interfaces in python with Qt\" I will show you how to enjoy creating user interfaces interactively with some clicks and few lines of code using the PySide6 library with all the Qt potential behind it." - requirements: "PySide6 (https://pypi.org/project/PySide6/)<br/><br/>Course repo:<br/>Empty and private until some days before the meeting but it will be this: https://github.com/draentropia/pyside-pyday21" - start_time_slot: 11:30 - end_time_slot: 12:45 - track_length: 1 - color: green - language: "Spanish" - type: workshop - topic: User interfaces - python_level: intermediate - topic_level: beginner - location: Room Actes - - speaker: "Gabriel de Maeztu" - sponsor: IOMED - title: "Vector search engines with Python: from embeddings to similarity search" - description: "I would cover the following topics, providing to anyone familiar with Python an overall idea about embeddings and similarity search in addition to a tutorial with with a use cases:<br/><ul><li>What are Vector Embeddings?</li><li>What is a Vector Database?</li><li>What is Vector Similarity Search?</li><li>So what do I do with my vector embedding?</li><li>Efficient Filtering of Vectors</li><li>Use cases: text, image, video, audio, graph and relational data</li><li>Let's build a search engine: Semantic textual search with vector embeddings<ol><li>Get the data</li><li>Create the embeddings</li><li>Upload the embeddings</li> <li>Query the data</li></ol></li></ul>" - start_time_slot: 11:30 - end_time_slot: 12:45 - track_length: 1 - color: blue - language: "English" - type: workshop - topic: Data Science - python_level: intermediate - topic_level: intermediate - location: Room Guinardó - - speaker: "Vincent Choubard" - sponsor: Rover - title: "Introduction to Django" - description: "We are going to build a web app using Django to create a pet profile and store it." - start_time_slot: 11:30 - end_time_slot: 12:45 - track_length: 1 - color: orange - language: "English" - type: workshop - topic: Web Development - python_level: beginner - topic_level: beginner - location: Room Gòtica - requirements: "Ideally have python and django installed on your machine by following <a href=\"https://docs.djangoproject.com/en/3.2/intro/install/\">https://docs.djangoproject.com/en/3.2/intro/install/</a>" - - speaker: "Antonio Molina, Erik Tordera, Pablo Fernández" - sponsor: Qustodio - title: "Microservicios en la vida moderna. Un enfoque python-centrico." - description: "Las arquitecturas distribuidas y los microservicios están en boca de todos. Unos defienden que son la cura para todos los males mientras que otros advierten que la complejidad añadida puede desembocar en frustraciones y malos sueños. En este workshop, proponemos una reflexión sobre arquitecturas distribuidas a través de un ejercicio práctico. Aunque orientado a desarrollos basados en nuestro querido python, proponemos salir de nuestra zona de confort para profundizar juntos en eso que llamamos dev/ops y de cómo los equipos podemos operar nuestros servicios asi como un primer contacto con las herramientas que nos ayudarán a minimizar los riesgos y las complejidades (tales como Helm, MiniKubes, Istio, GRPC, Prometheus, etc). Acompañanos en este rato a pensar y entender algunos de los problemas, soluciones y buenas prácticas en este tipo de arquitecturas." - start_time_slot: 11:30 - end_time_slot: 12:45 - track_length: 1 - color: red - language: "Spanish" - title_lang: Spanish - type: workshop - topic: Architecture - python_level: beginner - topic_level: intermediate - location: Room Raval - - - start_time_slot: 13:00 - end_time_slot: 13:00 - track_length: 4 - color: pink - title: "Group photo" - type: photo - location: Open-air terrace - class: middle - - - start_time_slot: 13:15 - end_time_slot: 13:45 - track_length: 4 - color: purple - title: "Lunch" - type: lunch - location: Open-air terrace - class: middle - - - speaker: "David de la Iglesia Castro" - title: "Making MLOps uncool again" - description: "In this workshop we will learn how to build an \"MLOps workflow\" by extending the power of Git and GitHub. Using only open source tools and without the need of external platfforms or complicated infrastructure. <br/><br/>We will use [HuggingFace] (https://huggingface.co/) to train a model that automatically adds labels to GitHub issues and we will extend the power of Git with [DVC](https://dvc.org/) and [CML](https://cml.dev/) in order to build a living Data Registry and set up a Continuous Training and Deployment loop for our model." - start_time_slot: 14:00 - end_time_slot: 15:15 - track_length: 1 - color: blue - language: "Spanish" - type: workshop - topic: Data science - python_level: intermediate - topic_level: intermediate - location: Room Actes - requirements: "A browser (preferably Google Chrome)<br/>Github account." - - speaker: "Jordi Mur" - title: "Causal Data Science workshop" - description: "Causal data science is a hot topic in the business applications of machine learning that go beyond predicting a value to actually deciding the best intervention to take based on such a prediction. We will briefly provide the key concepts and methods of causal inference (the topic of this year's Nobel prize in economics!), and then move on to some hands-on practice with Jupyter notebooks based on business use cases. No prior knowledge of causal inference is required." - requirements: "Bring your own laptop<br/>Libraries: Jupyter notebooks will use DoWhy: https://microsoft.github.io/dowhy/index.html" - start_time_slot: 14:00 - end_time_slot: 15:15 - track_length: 1 - color: blue - language: "English" - type: workshop - topic: Data science - python_level: intermediate - topic_level: beginner - location: Room Guinardó - - speaker: "Matteo Bruno" - sponsor: Onna - title: "How to beat imposter syndrome: confessions of a developer" - description: "Do you feel like you don’t belong, you don’t deserve what you’ve achieved, everyone in your office is more talented than you? Do you have imposter syndrome… too?<br/><br/>Impostor syndrome is a psychological pattern in which people doubt their accomplishments or talents and have a persistent internalized fear of being exposed as a \"fraud\".<br/><br/>Imposter syndrome is common across all industries, but the increasing pressure to be successful in your professional career is taking its toll on employees, affecting more than half workers, including our speaker :)<br/><br/>After many years working in tech for a lot of companies, (from startups to big corporations) in many business fields, Matteo discovered a way to overcome self-doubt and turn this weird feeling into a booster for greater achievements.<br/><br/>He’d like to share all his experience with everyone, making you understand that feeling inadequate is quite common and that there are ways to approach it in a proactive way." - start_time_slot: 14:00 - end_time_slot: 15:15 - track_length: 1 - color: yellow - language: "English" - type: talk - location: Room Gòtica - - speaker: "Albert Franzi Cros" - sponsor: Typeform - title: "Building a DAG Factory" - description: "At Typeform there are several teams that interact with data. Machine learning engineers, data scientists, data analysts, insights teams. None of them should have to worry about Airflow operators, upstream tasks, downstream tasks and all the million ways that writing Airflow DAGs by hand makes you miserable.<br/><br/>This is where the Data Platform teams comes to save the day and create Chester, a DAG factory, powered by a set of API connectors handled by us. Other teams only need to worry about where the data comes from and where it goes to, and write some YAML that describes it. All the rest is handled by Chester's superpowers." - start_time_slot: 14:00 - end_time_slot: 14:30 - track_length: 1 - color: red - language: "English" - type: talk - location: Room Raval - - speaker: "Alejandro Nicolás" - sponsor: Hybrid Theory - title: "Burnout Paradise: buenas prácticas para evitar el burnout en desarrollo" - description: "Durante la conferencia se tratará la programación desde el punto de vista psicológico, tanto a nivel individual como a nivel de equipo. Se presentarán los posibles efectos de una rutina de trabajo mal llevada, se evaluarán las causas y se propondrán sistemas o hábitos que afectarían positivamente al bienestar de un desarrollador en un mundo en el que el trabajo en remoto se ha implantado de manera inesperada en nuestro día a día." - start_time_slot: 14:45 - end_time_slot: 15:15 - track_length: 1 - color: yellow - language: "Spanish" - title_lang: Spanish - type: talk - location: Room Raval - - start_time_slot: 15:30 - end_time_slot: 15:45 - track_length: 4 - color: purple - title: "Coffee Break" - sponsor: CloudBlue - type: coffee - location: Open-air terrace - class: middle +# The rooms of this edition, in the order the grid first names them. A room is +# a record with an id because the colour of a block now comes from it: the +# template gives every room of an event one colour of the agenda palette and +# keeps it for the whole day. See partials/agenda_entry.html. +rooms: + - id: open-air-terrace + name: "Open-air terrace" + - id: room-actes + name: "Room Actes" + - id: room-guinardo + name: "Room Guinardó" + - id: room-gotica + name: "Room Gòtica" + - id: room-raval + name: "Room Raval" + - id: all-rooms + name: "All rooms" - - speaker: "Marc Pous" - title: "Build a Machine Learning IoT Device running Python" - description: "Learn on this workshop how to create a fleet of edge AI devices in a simple way using Python, Edge Impulse and balena.<br/><br/>During the workshop attendants will learn how to create a Bird Watcher using a Raspberry Pi and a USB camera (or Pi Camera). Using Python we will get the feed from the camera, apply machine learning models from Edge Impulse and send telegram messages. Finally we will be able to deploy a fleet of Bird Watchers in a simple way all around the world.<br/><br/>The goal of this session is to introduce IoT and AI topics to Python developers. Topics such as the Internet of Things, Artificial Intelligence and citizen science are consistently united in a single project. " - requirements: "Bring your own Raspberry Pi (3 or 4) with camera (USB or Pi Camera) with your laptop to try to deploy together a ML edge device." - start_time_slot: 16:00 - end_time_slot: 17:15 - track_length: 1 - color: blue - language: "English" - type: workshop - topic: IOT, ML, Edge AI - python_level: intermediate - topic_level: beginner - location: Room Actes - - speaker: "Mariana Meireles, Laysa Uchoa" - title: "The moons of Jupyter: widgets ecosystem" - description: "Jupyter has much more to offer than an interface for notebooks, the widgets ecosystem can leverage your research, dashboards, data visualization and much more!<br/>In the moons of Jupyter workshop we aim to give an overview of the standard widget library as well the expanded ecosystem created by contributors." - start_time_slot: 16:00 - end_time_slot: 17:15 - track_length: 1 - color: blue - language: "English" - type: workshop - topic: Data science, scientific computing - python_level: intermediate - topic_level: beginner - location: Room Guinardó - requirements: "https://github.com/jupyter-widgets/tutorial#readme<br/><br/>But a link to a Binder project where you can run the workshop without installing anything on your machine will also be provided. It’s recommendable to install requirements locally, though." - - speaker: "Vivek Sharma" - title: "Signal Processing - From Neurons to Mars!" - description: "What we see around us with time as its one dimension is a Signal! and to comprehend we just need to analyze it. This workshop is all about the last pit. We'll begin by examining some brain impulses, then move on to our environment, and lastly, Mars! Let's see what's going on over there.<br/>You'll learn how to make a frequency-specific filter, how to use the Fourier transform, and how to visualize data. <br/>Don't forget to bring your sense of wonder." - start_time_slot: 16:00 - end_time_slot: 17:15 - track_length: 1 - color: blue - language: "English" - type: workshop - topic: Signal Processing - python_level: beginner - topic_level: beginner - location: Room Gòtica - - speaker: "Christian Adell" - title: "Keeping sync between datasets with Diffsync" - description: "Working with multiple data models (and data inventories) while keeping a common state is a problem that involves a diff calculation first and then a synchronisation in one direction or another, sometimes solving the mapping between the data models.<br/>Diffsync (https://github.com/networktocode/diffsync) library helps with this common problem by providing an easy data modeling and structured CRUD operations to update the state." - requirements: "Try to run Nautobot Lab (https://github.com/nautobot/nautobot-lab) in Docker, as we'll use it as support during the workshop." - start_time_slot: 16:00 - end_time_slot: 17:15 - track_length: 1 - color: green - language: "English" - type: workshop - topic: Data set synchronisation - python_level: intermediate - topic_level: beginner - location: Room Raval +# The talks of this edition: what was said, by whom, in which language. A talk +# carries no time and no room, because it is the content and not the slot. +# agenda below is what places it on the grid, and one talk can take more than +# one slot. The id is derived from the title and is the anchor a photo of the +# gallery links to, so it must not change. +talks: + - id: how-to-create-data-apps-with-python + title: "How to create Data apps with Python" + speakers: [sergi-ortiz] + type: workshop + language: es + topic: "Data Apps" + duration_minutes: 75 + description: "Data products are the future of data. And Data Apps (and AI Apps) are an important chunk of this future. For Python coders there are many frictions to create Data Apps nowadays, we will try to address them all and create a Data App (FE - BE and DevOps) during the hands on session" + - id: build-a-chat-application-that-lets-you-speak-multiple + title: "Build a chat application that lets you speak multiple languages" + speakers: [diego-gonzalez] + type: workshop + language: en + topic: "Web development" + duration_minutes: 75 + description: "Learn how to build a chat application that can translate messages across multiple languages using only a few technologies (Python among them, of course!)" + - id: implementing-your-api-with-fastapi + title: "Implementing your API with FASTAPI" + speakers: [esperanza-buitrago] + type: workshop + language: en + topic: "Software Engineering" + duration_minutes: 75 + description: "Implement your API with FastAPI from scratch and make it run in local." + - id: building-the-cloud-with-python-getting-started-with-aws-cdk + title: "Building the Cloud with Python: getting started with AWS CDK" + speakers: [anton-caceres, alexandre-savio] + type: workshop + language: en + topic: "Cloud-native Python applications" + duration_minutes: 75 + description: "With emerging cloud technologies it is just a matter of time until most backends run in serverless or container-based environments. This workshop is showcasing a recently released open-source Cloud Development Kit by Amazon, which lets us control cloud resources just like we control our application logic - in pure Python. CDK offers high-level abstraction to define AWS resources imperatively as customizable and reusable Python classes. Unfortunately, there are not many tutorials available yet and the documentation is limited. So we will be happy to share with you how to: 1) Break down AWS infrastructure into reusable constructs represented by Python classes; 2) Combine own and public constructs into Stack applications; 3) Deploy CDK apps to AWS cloud" + - id: creating-cute-user-interfaces-in-python-with-qt + title: "Creating cute user interfaces in python with Qt" + speakers: [elisabeth-ortega-carrasco] + type: workshop + language: es + topic: "User interfaces" + duration_minutes: 75 + description: "Most of us learn to use python as a command line tool, asking information to the users and passing them to the code as arguments. Some of us later moved to Django and related web development tools, to have a better interaction with the user paying the cost of fighting against the web layout in different languages. Few of us faced tkinter to build our first user interfaces with more or less success, but almost none of us were happy with the result of the user interfaces created in pure python.<br/>In \"Creating cute user interfaces in python with Qt\" I will show you how to enjoy creating user interfaces interactively with some clicks and few lines of code using the PySide6 library with all the Qt potential behind it." + - id: vector-search-engines-with-python-from-embeddings-to + title: "Vector search engines with Python: from embeddings to similarity search" + speakers: [gabriel-de-maeztu] + type: workshop + language: en + topic: "Data Science" + duration_minutes: 75 + description: "I would cover the following topics, providing to anyone familiar with Python an overall idea about embeddings and similarity search in addition to a tutorial with with a use cases:<br/><ul><li>What are Vector Embeddings?</li><li>What is a Vector Database?</li><li>What is Vector Similarity Search?</li><li>So what do I do with my vector embedding?</li><li>Efficient Filtering of Vectors</li><li>Use cases: text, image, video, audio, graph and relational data</li><li>Let's build a search engine: Semantic textual search with vector embeddings<ol><li>Get the data</li><li>Create the embeddings</li><li>Upload the embeddings</li> <li>Query the data</li></ol></li></ul>" + - id: introduction-to-django + title: "Introduction to Django" + speakers: [vincent-choubard] + type: workshop + language: en + topic: "Web Development" + duration_minutes: 75 + description: "We are going to build a web app using Django to create a pet profile and store it." + - id: microservicios-en-la-vida-moderna-un-enfoque-python-centrico + title: "Microservicios en la vida moderna. Un enfoque python-centrico." + title_lang: Spanish + speakers: [antonio-molina, erik-tordera, pablo-fernandez] + type: workshop + language: es + topic: "Architecture" + duration_minutes: 75 + description: "Las arquitecturas distribuidas y los microservicios están en boca de todos. Unos defienden que son la cura para todos los males mientras que otros advierten que la complejidad añadida puede desembocar en frustraciones y malos sueños. En este workshop, proponemos una reflexión sobre arquitecturas distribuidas a través de un ejercicio práctico. Aunque orientado a desarrollos basados en nuestro querido python, proponemos salir de nuestra zona de confort para profundizar juntos en eso que llamamos dev/ops y de cómo los equipos podemos operar nuestros servicios asi como un primer contacto con las herramientas que nos ayudarán a minimizar los riesgos y las complejidades (tales como Helm, MiniKubes, Istio, GRPC, Prometheus, etc). Acompañanos en este rato a pensar y entender algunos de los problemas, soluciones y buenas prácticas en este tipo de arquitecturas." + - id: making-mlops-uncool-again + title: "Making MLOps uncool again" + speakers: [david-de-la-iglesia-castro] + type: workshop + language: es + topic: "Data science" + duration_minutes: 75 + description: "In this workshop we will learn how to build an \"MLOps workflow\" by extending the power of Git and GitHub. Using only open source tools and without the need of external platfforms or complicated infrastructure. <br/><br/>We will use [HuggingFace] (https://huggingface.co/) to train a model that automatically adds labels to GitHub issues and we will extend the power of Git with [DVC](https://dvc.org/) and [CML](https://cml.dev/) in order to build a living Data Registry and set up a Continuous Training and Deployment loop for our model." + - id: causal-data-science-workshop + title: "Causal Data Science workshop" + speakers: [jordi-mur] + type: workshop + language: en + topic: "Data science" + duration_minutes: 75 + description: "Causal data science is a hot topic in the business applications of machine learning that go beyond predicting a value to actually deciding the best intervention to take based on such a prediction. We will briefly provide the key concepts and methods of causal inference (the topic of this year's Nobel prize in economics!), and then move on to some hands-on practice with Jupyter notebooks based on business use cases. No prior knowledge of causal inference is required." + - id: how-to-beat-imposter-syndrome-confessions-of-a-developer + title: "How to beat imposter syndrome: confessions of a developer" + speakers: [matteo-bruno] + type: talk + language: en + duration_minutes: 75 + description: "Do you feel like you don't belong, you don't deserve what you've achieved, everyone in your office is more talented than you? Do you have imposter syndrome... too?<br/><br/>Impostor syndrome is a psychological pattern in which people doubt their accomplishments or talents and have a persistent internalized fear of being exposed as a \"fraud\".<br/><br/>Imposter syndrome is common across all industries, but the increasing pressure to be successful in your professional career is taking its toll on employees, affecting more than half workers, including our speaker :)<br/><br/>After many years working in tech for a lot of companies, (from startups to big corporations) in many business fields, Matteo discovered a way to overcome self-doubt and turn this weird feeling into a booster for greater achievements.<br/><br/>He'd like to share all his experience with everyone, making you understand that feeling inadequate is quite common and that there are ways to approach it in a proactive way." + - id: building-a-dag-factory + title: "Building a DAG Factory" + speakers: [albert-franzi-cros] + type: talk + language: en + duration_minutes: 30 + description: "At Typeform there are several teams that interact with data. Machine learning engineers, data scientists, data analysts, insights teams. None of them should have to worry about Airflow operators, upstream tasks, downstream tasks and all the million ways that writing Airflow DAGs by hand makes you miserable.<br/><br/>This is where the Data Platform teams comes to save the day and create Chester, a DAG factory, powered by a set of API connectors handled by us. Other teams only need to worry about where the data comes from and where it goes to, and write some YAML that describes it. All the rest is handled by Chester's superpowers." + - id: burnout-paradise-buenas-practicas-para-evitar-el-burnout-en + title: "Burnout Paradise: buenas prácticas para evitar el burnout en desarrollo" + title_lang: Spanish + speakers: [alejandro-nicolas] + type: talk + language: es + duration_minutes: 30 + description: "Durante la conferencia se tratará la programación desde el punto de vista psicológico, tanto a nivel individual como a nivel de equipo. Se presentarán los posibles efectos de una rutina de trabajo mal llevada, se evaluarán las causas y se propondrán sistemas o hábitos que afectarían positivamente al bienestar de un desarrollador en un mundo en el que el trabajo en remoto se ha implantado de manera inesperada en nuestro día a día." + - id: build-a-machine-learning-iot-device-running-python + title: "Build a Machine Learning IoT Device running Python" + speakers: [marc-pous] + type: workshop + language: en + topic: "IOT, ML, Edge AI" + duration_minutes: 75 + description: "Learn on this workshop how to create a fleet of edge AI devices in a simple way using Python, Edge Impulse and balena.<br/><br/>During the workshop attendants will learn how to create a Bird Watcher using a Raspberry Pi and a USB camera (or Pi Camera). Using Python we will get the feed from the camera, apply machine learning models from Edge Impulse and send telegram messages. Finally we will be able to deploy a fleet of Bird Watchers in a simple way all around the world.<br/><br/>The goal of this session is to introduce IoT and AI topics to Python developers. Topics such as the Internet of Things, Artificial Intelligence and citizen science are consistently united in a single project. " + - id: the-moons-of-jupyter-widgets-ecosystem + title: "The moons of Jupyter: widgets ecosystem" + speakers: [mariana-meireles, laysa-uchoa] + type: workshop + language: en + topic: "Data science, scientific computing" + duration_minutes: 75 + description: "Jupyter has much more to offer than an interface for notebooks, the widgets ecosystem can leverage your research, dashboards, data visualization and much more!<br/>In the moons of Jupyter workshop we aim to give an overview of the standard widget library as well the expanded ecosystem created by contributors." + - id: signal-processing-from-neurons-to-mars + title: "Signal Processing - From Neurons to Mars!" + speakers: [vivek-sharma] + type: workshop + language: en + topic: "Signal Processing" + duration_minutes: 75 + description: "What we see around us with time as its one dimension is a Signal! and to comprehend we just need to analyze it. This workshop is all about the last pit. We'll begin by examining some brain impulses, then move on to our environment, and lastly, Mars! Let's see what's going on over there.<br/>You'll learn how to make a frequency-specific filter, how to use the Fourier transform, and how to visualize data. <br/>Don't forget to bring your sense of wonder." + - id: keeping-sync-between-datasets-with-diffsync + title: "Keeping sync between datasets with Diffsync" + speakers: [christian-adell] + type: workshop + language: en + topic: "Data set synchronisation" + duration_minutes: 75 + description: "Working with multiple data models (and data inventories) while keeping a common state is a problem that involves a diff calculation first and then a synchronisation in one direction or another, sometimes solving the mapping between the data models.<br/>Diffsync (https://github.com/networktocode/diffsync) library helps with this common problem by providing an easy data modeling and structured CRUD operations to update the state." - - start_time_slot: 17:30 - end_time_slot: 17:45 - track_length: 4 - color: purple - title: "Closing session & Kahoot" - speaker: "PyDay BCN 2021 Organising Committee" - type: group - location: All rooms - class: middle +# The grid, one row per slot of the day, in the order it is printed. A slot +# names the talk it holds, or carries its own label and type when it holds +# none: a break, the group photo, the welcome. The level and the requirements +# sit here and not on the talk, because they are what the slot asks of whoever +# walks into it. A start is always quoted: YAML 1.1 reads an unquoted 9:00 as +# the integer 540. +agenda: + - start: "9:00" + credited_as: "PyDay BCN 2021 Organising Committee" + track_length: 4 + room: open-air-terrace + type: group + label: "Registration & Welcome" + duration_minutes: 15 + - start: "9:30" + track_length: 1 + room: room-actes + talk: how-to-create-data-apps-with-python + python_level: intermediate + topic_level: beginner + - start: "9:30" + track_length: 1 + room: room-guinardo + talk: build-a-chat-application-that-lets-you-speak-multiple + python_level: intermediate + topic_level: intermediate + sponsor: "Preply" + - start: "9:30" + track_length: 1 + room: room-gotica + talk: implementing-your-api-with-fastapi + python_level: beginner + topic_level: beginner + requirements: "<ul><li>Python3</li><li>Visual Studio Code</li><li>Pip3</li><li>Conda</li><li>We'll do everything from scratch: such as installing FastAPI, uvicorn and typing</li></ul>" + - start: "9:30" + track_length: 1 + room: room-raval + talk: building-the-cloud-with-python-getting-started-with-aws-cdk + python_level: intermediate + topic_level: beginner + requirements: "Python 3.8+" + - start: "11:00" + track_length: 4 + room: open-air-terrace + type: coffee + label: "Coffee Break" + duration_minutes: 15 + sponsor: "Bling" + - start: "11:30" + track_length: 1 + room: room-actes + talk: creating-cute-user-interfaces-in-python-with-qt + python_level: intermediate + topic_level: beginner + requirements: "PySide6 (https://pypi.org/project/PySide6/)<br/><br/>Course repo:<br/>Empty and private until some days before the meeting but it will be this: https://github.com/draentropia/pyside-pyday21" + - start: "11:30" + track_length: 1 + room: room-guinardo + talk: vector-search-engines-with-python-from-embeddings-to + python_level: intermediate + topic_level: intermediate + sponsor: "IOMED" + - start: "11:30" + track_length: 1 + room: room-gotica + talk: introduction-to-django + python_level: beginner + topic_level: beginner + requirements: "Ideally have python and django installed on your machine by following <a href=\"https://docs.djangoproject.com/en/3.2/intro/install/\">https://docs.djangoproject.com/en/3.2/intro/install/</a>" + sponsor: "Rover" + - start: "11:30" + track_length: 1 + room: room-raval + talk: microservicios-en-la-vida-moderna-un-enfoque-python-centrico + python_level: beginner + topic_level: intermediate + sponsor: "Qustodio" + - start: "13:00" + track_length: 4 + room: open-air-terrace + type: photo + label: "Group photo" + duration_minutes: 0 + - start: "13:15" + track_length: 4 + room: open-air-terrace + type: lunch + label: "Lunch" + duration_minutes: 30 + - start: "14:00" + track_length: 1 + room: room-actes + talk: making-mlops-uncool-again + python_level: intermediate + topic_level: intermediate + requirements: "A browser (preferably Google Chrome)<br/>Github account." + - start: "14:00" + track_length: 1 + room: room-guinardo + talk: causal-data-science-workshop + python_level: intermediate + topic_level: beginner + requirements: "Bring your own laptop<br/>Libraries: Jupyter notebooks will use DoWhy: https://microsoft.github.io/dowhy/index.html" + - start: "14:00" + track_length: 1 + room: room-gotica + talk: how-to-beat-imposter-syndrome-confessions-of-a-developer + sponsor: "Onna" + - start: "14:00" + track_length: 1 + room: room-raval + talk: building-a-dag-factory + sponsor: "Typeform" + - start: "14:45" + track_length: 1 + room: room-raval + talk: burnout-paradise-buenas-practicas-para-evitar-el-burnout-en + sponsor: "Hybrid Theory" + - start: "15:30" + track_length: 4 + room: open-air-terrace + type: coffee + label: "Coffee Break" + duration_minutes: 15 + sponsor: "CloudBlue" + - start: "16:00" + track_length: 1 + room: room-actes + talk: build-a-machine-learning-iot-device-running-python + python_level: intermediate + topic_level: beginner + requirements: "Bring your own Raspberry Pi (3 or 4) with camera (USB or Pi Camera) with your laptop to try to deploy together a ML edge device." + - start: "16:00" + track_length: 1 + room: room-guinardo + talk: the-moons-of-jupyter-widgets-ecosystem + python_level: intermediate + topic_level: beginner + requirements: "https://github.com/jupyter-widgets/tutorial#readme<br/><br/>But a link to a Binder project where you can run the workshop without installing anything on your machine will also be provided. It’s recommendable to install requirements locally, though." + - start: "16:00" + track_length: 1 + room: room-gotica + talk: signal-processing-from-neurons-to-mars + python_level: beginner + topic_level: beginner + - start: "16:00" + track_length: 1 + room: room-raval + talk: keeping-sync-between-datasets-with-diffsync + python_level: intermediate + topic_level: beginner + requirements: "Try to run Nautobot Lab (https://github.com/nautobot/nautobot-lab) in Docker, as we'll use it as support during the workshop." + - start: "17:30" + credited_as: "PyDay BCN 2021 Organising Committee" + track_length: 4 + room: all-rooms + type: group + label: "Closing session & Kahoot" + duration_minutes: 15 - --- ## About PyDay BCN 2021 We are organizing the **the fifth edition** of PyDay in Barcelona! -PyDay is an event full of FREE **python-related workshops** and activities for the Python community, organized once per year. Over the [last four editions](#previous_editions_section), PyDay has become a great opportunity to share our love for Python and engage users, companies and newcomers into it! +PyDay is an event full of FREE **python-related workshops** and activities for the Python community, organized once per year. Over the last four editions, PyDay has become a great opportunity to share our love for Python and engage users, companies and newcomers into it! ### When and where diff --git a/content/events/pyday_bcn/pyday_bcn_2022.md b/content/events/pyday_bcn/pyday_bcn_2022.md index f32965db8..3fe2d0d86 100644 --- a/content/events/pyday_bcn/pyday_bcn_2022.md +++ b/content/events/pyday_bcn/pyday_bcn_2022.md @@ -1,6 +1,10 @@ --- title: "PyDay BCN (2022)" year: 2022 +# The day of this edition, from the Meetup export, which records it per event. +date: 2022-11-26 +# The venue of this edition, from the Meetup export, which records it per event. +venue: "Canòdrom" description: "For the community, by the community!" menu: main: @@ -25,7 +29,6 @@ free_text_sections: id: registration content: "General registration will open on Monday 21st of November, at 9AM through <a target='_blank' href='https://www.eventbrite.es/e/entradas-pydaybcn-2022-470666304587'>Eventbrite</a>." -sponsors_text: "Would you like to sponsor this event? Please contact us at pydaybcn2022@googlegroups.com<br/><br/>" sponsor_levels: - sponsors_per_line: 2 sponsors: [canodrom] @@ -72,58 +75,46 @@ people_sections: - xavi-francisco-gilabert - mireia-alvarez-dominguez -previous_editions: - - name: PyDay BCN 2021 - url: /events/pyday_bcn/pyday_bcn_2021/ - - name: PyDay BCN 2020 - url: /events/pyday_bcn/pyday_bcn_2020/ - - name: PyDay BCN 2019 - url: /events/pyday_bcn/pyday_bcn_2019/ - - name: PyDay BCN 2018 - url: /events/pyday_bcn/pyday_bcn_2018/ - - name: PyDay BCN 2016 - url: /events/pyday_bcn/pyday_bcn_2016/ - spansDuration: 15 numTracks: 3 eventTimes: [ - 9:00, - 9:15, - 9:30, - 9:45, - 10:00, - 10:15, - 10:30, - 10:45, - 11:00, - 11:15, - 11:30, - 11:45, - 12:00, - 12:15, - 12:30, - 12:45, - 13:00, - 13:15, - 13:30, - 13:45, - 14:00, - 14:15, - 14:30, - 14:45, - 15:00, - 15:15, - 15:30, - 15:45, - 16:00, - 16:15, - 16:30, - 16:45, - 17:00, - 17:15, - 17:30, - 17:45, + "9:00", + "9:15", + "9:30", + "9:45", + "10:00", + "10:15", + "10:30", + "10:45", + "11:00", + "11:15", + "11:30", + "11:45", + "12:00", + "12:15", + "12:30", + "12:45", + "13:00", + "13:15", + "13:30", + "13:45", + "14:00", + "14:15", + "14:30", + "14:45", + "15:00", + "15:15", + "15:30", + "15:45", + "16:00", + "16:15", + "16:30", + "16:45", + "17:00", + "17:15", + "17:30", + "17:45", ] legend: - type: workshop @@ -132,291 +123,267 @@ legend: - level: beginner - level: intermediate - level: advanced -events: - - start_time_slot: 9:00 - end_time_slot: 9:15 - track_length: 3 - color: purple - title: "Registration & Welcome" - speaker: "PyDay BCN 2022 Organising Committee" - type: group - location: Sala d'actes Ada Lovelace - class: middle - - speaker: "Gema Parreño" +# The rooms of this edition, in the order the grid first names them. A room is +# a record with an id because the colour of a block now comes from it: the +# template gives every room of an event one colour of the agenda palette and +# keeps it for the whole day. See partials/agenda_entry.html. +rooms: + - id: sala-dactes-ada-lovelace + name: "Sala d'actes Ada Lovelace" + - id: sala-hedy-lamarr-margarita-salas + name: "Sala Hedy Lamarr / Margarita Salas" + - id: sala-hipatia-dalexandria + name: "Sala Hipàtia d'Alexandria" + - id: open-air-terrace + name: "Open-air terrace" + +# The talks of this edition: what was said, by whom, in which language. A talk +# carries no time and no room, because it is the content and not the slot. +# agenda below is what places it on the grid, and one talk can take more than +# one slot. The id is derived from the title and is the anchor a photo of the +# gallery links to, so it must not change. +talks: + - id: machine-learning-en-produccion-experimentos-con-versionado title: "Machine Learning en producción: Experimentos con versionado de datos con DVC y VSCode" + title_lang: Spanish + speakers: [gema-parreno] + type: workshop + language: es + topic: "Data Science and MLOPS" + duration_minutes: 75 description: "El workshop utiliza herramientas OpenSource de DVC y su extension para VSCode para preparar los experimentos de Data Science para su versionado y puesta en producción. Utilizamos el IDE de VS Code y lo transformamos en una plataforma de experimentación de Machine Learning.<br><br>A través de un caso de uso real, veremos las posibilidades que ofrece el implementar practicas de Software a los proyectos de Data Science y herramientas para versionar los experimentos de Machine Learning.<br><br>Objetivo : ayudar a los data scientist a salir de los notebooks y preparar la experimentación y puesta en producción de manera un poco mas robusta ." - start_time_slot: 9:30 - end_time_slot: 10:45 - track_length: 1 - color: red + - id: friendly-fuzzing-for-your-python-saas-applications + title: "Friendly fuzzing for your Python SaaS applications" + speakers: [pavel-lonkin] + type: workshop + language: en + topic: "Security, software development" + duration_minutes: 75 + description: "Tired of bugs? Security issues in your Python code? Fuzzing approach can help you to decrease number of issues received from your production environment using only few lines of code! In this topic you are going to:<br/><ul><li>learn what the fuzzing is and what type of fuzzing exists</li><li>learn how it helps to catch the bugs and find potential security issues when you are sleeping</li><li>\"fuzz\" your first python application</li><li>find the way to fuzz your REST Django application</li><li>discover the instruments to fuzz any API</li></ul>" + - id: how-many-ants-can-carry-an-elephant-pushing-the-limits-of + title: "How many ants can carry an elephant? Pushing the limits of AWS Chalice" + speakers: [kemalcan-bora] + type: workshop + language: en + topic: "Serverless apps" + duration_minutes: 75 + description: "Chalice is a framework for writing serverless apps in python. It allows you to quickly create and deploy applications that use AWS Lambda. Serverless applications generally have some limits like RAM, storage, and CPU.. and the main purpose is simple functions like login, registration, etc. So what if we want to create an ML application? How can we handle our limits? don't panic young Skywalker. We have to push our limits and we'll install NumPy, and Sci-kit learn libraries and our app will roam freely in the cloud in peace." + - id: build-air-quality-sensors-with-python-and-choose-your-own + title: "Build Air Quality Sensors with Python and choose your own adventure!" + speakers: [marc-pous] type: workshop - language: "Spanish" + language: en + topic: "Internet of Things and Air quality sensors" + duration_minutes: 75 + description: "The goal of this hands-on workshop is to build an Air Quality sensor (with Raspberry Pis) using Python to get the data from the sensors. From here you are going to choose what happens next. Would you like to store the data on a database? Visualize it? Send it to a Cloud? or to a Telegram bot? You choose your own adventure! Everything in the edge using containers, python and balena." + - id: build-a-full-stack-app-with-flask-and-vue + title: "Build a full-stack app with Flask and Vue" + speakers: [eva-martin-del-pico] + type: workshop + language: en + topic: "Web apps" + duration_minutes: 75 + description: "In this workshop we will build a complete web application using Flask Python micro framework in the backend and Vue.js JS framework in the frontend. Both Flask and Vue are easy to learn, yet flexible and powerful, making them a great choice for those who want to create modern and robust applications - and do it fast." + - id: python-as-a-gis-tools-howtos-and-gotchas + title: "Python as a GIS: Tools, howtos and gotchas" + speakers: [biel-stela-ballester] + type: workshop + language: en + topic: "Python as a GIS" + duration_minutes: 75 + description: "Use python as a GIS with Rasterio, Xarray and GeoPandas" + - id: building-an-end-to-end-open-source-modern-data-platform-for + title: "Building an End-to-End Open-Source Modern Data Platform for Biomedical Data" + speakers: [alberto-labarga] + type: workshop + language: [en, es] + topic: "Data engineering" + duration_minutes: 75 + description: "A detailed guide to help you navigate the modern data stack and build your own platform using open-source technologies.<br/><br/>Data engineering has experiences enormous growth in the last years, allowing for rapid progress and innovation as more people than ever are thinking about data resources and how to better leverage them.<br/><br/>In this talk we will explore the related technologies and build from scratch an end-to-end modern data platform for the analysis of medical data. We will be using open-source tools and libraries, including python-based DBT, Apache Airflow and Querybook.<br/><br/>The platform will consist of the following components:<ul><li>Data warehouse</li><li>Data integration</li><li>Data transformation</li><li>Data orchestration</li><li>Data visualization</li></ul>" + - id: cuando-los-precios-suben-scrapy + title: "Cuando los precios suben: Scrapy" title_lang: Spanish + speakers: [jimena-escobar-bermudez] + type: workshop + language: es + topic: "Scrapy" + duration_minutes: 75 + description: "Criptomonedas, la guerra en Ucrania, la pandemia, la falta de componentes y toda la serie de catastróficas desdichas que estamos sufriendo nos ha llevado a un punto en el que el precio de todo ha subido. En este taller aprenderemos a usar Scrapy para conseguir descargar, almacenar y comparar los precios de los productos que queramos." + - id: inside-out-or-how-to-get-your-app-observable + title: "Inside out. Or how to get your app observable" + speakers: [antonio-molina] + type: workshop + language: es + topic: "Observability" + duration_minutes: 75 + description: "Observability is key in distributed systems and it is gaining importance within the industry. So it is important to understand the concepts behind the idea of observabiity and why is important to us, as developers, to make our developments \"observable\". Being able to create software that is easy to debug while systems scales and complexity grows will level up us as developers and will make our clients and employers far happier. This is what this workshop is about. From a brief theory of what observability is to some practices and best practices." + - id: lightning-talks-session-1-coffee + title: "Lightning talks (session 1) & coffee" + type: talk + duration_minutes: 15 + description: " <h2>Lightning talks</h2>\n<b>How to beat your friends in fantasy football</b><br> <i>Alex Molas</i> <p><q>Have you ever wondered how to win your friends in a football fantasy league? In this talk I will show how to use python to get the best performant team by using web scraping, operations research, and machine learning!</q></p>\n<b>Measuring media bias</b><br> <i>Luis Ignacio Menéndez</i> <p><q>We'd like to talk about a research project (working progress) trying to measure media bias in Spanish TV news. For this, we employ techniques of speech recognition, speaker diarization and text analysis. This project is carried on by PhD students of the Economics department at Universitat Autònoma de Barcelona.</q></p>\n<b>Astropy 5.X: astronomical tools for everybody</b><br> <i>Francesc Vilardell Sallés</i> <p><q>Astropy is now a mature python library with over 34.000 commits on Github and hundreds of contributors. Astropy is still little known beyond the astronomical community, but offers several powerful tools that are useful to all python developers. In this lightning talk I will present some of these tools. </q></p>\n<b>Fighting climate change the Python way</b><br> <i>Rafael Giménez</i> <p><q>The Digital Team at Cetaqua works in bringing state of the art AI (Computer Vision, Reinforcement Learning) to one of the most crucial issues of our time: water and environmental management. The talk aims to briefly showcase how we use Python for that.</q></p>\n<b>PyCamp España </b><br> <i>Johanna Sanchez</i> <p><q>Invitación a la comunidad para participar de un evento diferente</q></p>\n<b>PyLadies España y PyCon ES 2023</b><br> <i>Johanna Sanchez</i> <p><q>Invitación a la comunidad para participar en conferencia y comunidades</q></p> " + - id: using-numba-effectively-today + title: "Using Numba Effectively Today" + speakers: [cheuk-ting-ho] + type: workshop + language: en + topic: "Data Science" + duration_minutes: 75 + description: "Numba is syntactically easy to use - just add a decorator, but actually very hard to use effectively. The reason being it is difficult to understand what Numba does to speed up the numeric operation. This workshop will provide all the knowledge that you need to make Numba works for you." + - id: making-sense-of-your-data-platform-with-openmetadata + title: "Making sense of your Data Platform with OpenMetadata" + speakers: [pere-miquel-brull] + type: workshop + language: en + topic: "Data Management" + duration_minutes: 75 + description: "OpenMetadata is an open-source project (https://open-metadata.org/) that is building a metadata standard and a centralized and shared metadata platform on top of it. In this workshop, we will explore the tool, how it works, and bit by bit we will dive into its implementation and design." + - id: tdd-coding-dojo + title: "TDD Coding Dojo" + speakers: [ana-eliza-barbosa] + type: workshop + language: en + topic: "Test driven development" + duration_minutes: 75 + description: "Nowadays software products are becoming so complex that is unimaginable that one software engineer would develop it alone without any sort of automated testing, so let's get together to practice Test Driven Development while pair programming with the other workshop participants. We will solve some code challenges together, under a bit of friendly time pressure and changing development hats every 5 minutes. If you are interested in knowing how it all looks like then join the workshop!" + - id: lightning-talks-session-2-closing-session-kahoot + title: "Lightning talks (session 2) + closing session & Kahoot" + type: talk + duration_minutes: 15 + description: " <h2>Lightning talks</h2>\n<b>Intenciones ganadoras: Cómo implementar la arquitectura de un chatbot basado en intenciones</b><br> <i>Nadal Llabrés Belmar</i> <p><q>En esta charla explicaremos los aspectos fundamentales de cómo diseñar e implementar un chatbot basado en el reconocimiento de intenciones desde el punto de vista de la ingeniería de Software. Mediante un caso de uso, exploramos cómo diseñar e implementar una arquitectura que nos permita integrar y gestionar la base de conocimiento que requiere el bot para su aprendizaje, integrar un motor de reconocimiento de intenciones que sea capaz de entender a los usuarios a partir de un entendimiento contextual de una conversación e integrar un sistema de respuestas en distintos formatos (voz, texto, imágenes, vídeos).</q></p>\n<b>Satellite super-resolution and 3d scenes</b><br> <i>Biel Stela</i> <p><q>Match the resolution of Landsat imagery to fine grained Sentinel using Deep Learning, then create dynamic evolving scenes with blender. </q></p>\n<b>trrex: Efficient keyword extraction with regex</b><br> <i>Daniel Mesejo</i> <p><q>In this talk I'm going to introduce the trrex package, for performing efficient keyword extraction with regular expressions. Additionally I'll show how to integrate it with pandas for text cleaning, how to use it with spacy to build a gazetteer and how to perform fuzzy matching with the regex library.</q></p>\n<b>Transactions</b><br> <i>Christian Barra</i> <p><q>The goal of the LT is to give to the audience a brief overview about DB transactions, why there are important and how to leverage them for some specific use cases where they play a critical role.</q></p>\n<b>Optimal binning using Python</b><br> <i>Guillermo Navas Palencia</i> <p><q>Presentation of the OptBinning library, a Python library to perform optimal binning and scorecard modelling. Description of main features, current roadmap and applications.</q></p> " + +# The grid, one row per slot of the day, in the order it is printed. A slot +# names the talk it holds, or carries its own label and type when it holds +# none: a break, the group photo, the welcome. The level and the requirements +# sit here and not on the talk, because they are what the slot asks of whoever +# walks into it. A start is always quoted: YAML 1.1 reads an unquoted 9:00 as +# the integer 540. +agenda: + - start: "9:00" + credited_as: "PyDay BCN 2022 Organising Committee" + track_length: 3 + room: sala-dactes-ada-lovelace + type: group + label: "Registration & Welcome" + duration_minutes: 15 + - start: "9:30" + track_length: 1 + room: sala-dactes-ada-lovelace + talk: machine-learning-en-produccion-experimentos-con-versionado python_level: intermediate topic_level: intermediate requirements: "<ul><li>Laptop , requirements.txt installed.</li><li>VS Code IDE.</li></ul>" - topic: "Data Science and MLOPS" - location: Sala d'actes Ada Lovelace - - speaker: "Pavel Lonkin" - title: "Friendly fuzzing for your Python SaaS applications" - description: "Tired of bugs? Security issues in your Python code? Fuzzing approach can help you to decrease number of issues received from your production environment using only few lines of code! In this topic you are going to:<br/><ul><li>learn what the fuzzing is and what type of fuzzing exists</li><li>learn how it helps to catch the bugs and find potential security issues when you are sleeping</li><li>“fuzz” your first python application</li><li>find the way to fuzz your REST Django application</li><li>discover the instruments to fuzz any API</li></ul>" - start_time_slot: 9:30 - end_time_slot: 10:45 + - start: "9:30" track_length: 1 - color: yellow - type: workshop - language: "English" + room: sala-hedy-lamarr-margarita-salas + talk: friendly-fuzzing-for-your-python-saas-applications python_level: intermediate topic_level: beginner requirements: "<ul><li>Initial python knowledges</li><li>Would be great to know Django</li><li>Laptop with installed Docker and Docker Compose</li><//ul>" - topic: "Security, software development" - location: Sala Hedy Lamarr / Margarita Salas - - speaker: "Kemalcan Bora" - title: "How many ants can carry an elephant? Pushing the limits of AWS Chalice" - description: "Chalice is a framework for writing serverless apps in python. It allows you to quickly create and deploy applications that use AWS Lambda. Serverless applications generally have some limits like RAM, storage, and CPU.. and the main purpose is simple functions like login, registration, etc. So what if we want to create an ML application? How can we handle our limits? don't panic young Skywalker. We have to push our limits and we'll install NumPy, and Sci-kit learn libraries and our app will roam freely in the cloud in peace." - start_time_slot: 9:30 - end_time_slot: 10:45 + - start: "9:30" track_length: 1 - color: blue - type: workshop - language: "English" + room: sala-hipatia-dalexandria + talk: how-many-ants-can-carry-an-elephant-pushing-the-limits-of python_level: beginner topic_level: beginner - topic: "Serverless apps" - location: Sala Hipàtia d'Alexandria requirements: "Python, AWS account, AWS chalice framework" - - - start_time_slot: 11:00 - end_time_slot: 11:15 + - start: "11:00" track_length: 3 - color: purple - title: "Coffee break" + room: open-air-terrace type: coffee - location: Open-air terrace - class: middle - - - speaker: "Marc Pous" - title: "Build Air Quality Sensors with Python and choose your own adventure!" - description: "The goal of this hands-on workshop is to build an Air Quality sensor (with Raspberry Pis) using Python to get the data from the sensors. From here you are going to choose what happens next. Would you like to store the data on a database? Visualize it? Send it to a Cloud? or to a Telegram bot? You choose your own adventure! Everything in the edge using containers, python and balena." - start_time_slot: 11:30 - end_time_slot: 12:45 + label: "Coffee break" + duration_minutes: 15 + - start: "11:30" track_length: 1 - color: blue - type: workshop - language: "English" + room: sala-dactes-ada-lovelace + talk: build-air-quality-sensors-with-python-and-choose-your-own python_level: beginner topic_level: beginner requirements: "Laptop" - topic: "Internet of Things and Air quality sensors" - location: Sala d'actes Ada Lovelace - - speaker: "Eva Martín del Pico" - title: "Build a full-stack app with Flask and Vue" - description: "In this workshop we will build a complete web application using Flask Python micro framework in the backend and Vue.js JS framework in the frontend. Both Flask and Vue are easy to learn, yet flexible and powerful, making them a great choice for those who want to create modern and robust applications - and do it fast." - start_time_slot: 11:30 - end_time_slot: 12:45 + - start: "11:30" track_length: 1 - color: blue - type: workshop - language: "English" + room: sala-hedy-lamarr-margarita-salas + talk: build-a-full-stack-app-with-flask-and-vue python_level: beginner topic_level: beginner requirements: "<ul><li>Familiarity with Python and basic understanding of HTML and CSS (ideally JS too, but it is not necessary)</li><li>Laptop with Python3, Flask, NuxtJS and Docker.</li></ul>" - topic: "Web apps" - location: Sala Hedy Lamarr / Margarita Salas - - speaker: "Biel Stela" - title: "Python as a GIS: Tools, howtos and gotchas" - description: "Use python as a GIS with Rasterio, Xarray and GeoPandas" - start_time_slot: 11:30 - end_time_slot: 12:45 + - start: "11:30" track_length: 1 - color: red - type: workshop - language: "English" + room: sala-hipatia-dalexandria + talk: python-as-a-gis-tools-howtos-and-gotchas python_level: intermediate topic_level: intermediate requirements: "Laptop with conda if attendees want to follow the notebooks and do some exercises, just ears and be present otherwise." - topic: "Python as a GIS" - location: Sala Hipàtia d'Alexandria - - - start_time_slot: 13:00 - end_time_slot: 13:00 + - start: "13:00" track_length: 3 - color: pink - title: "Group photo" + room: open-air-terrace type: photo - location: Open-air terrace - class: middle - - - start_time_slot: 13:15 - end_time_slot: 13:45 + label: "Group photo" + duration_minutes: 0 + - start: "13:15" track_length: 3 - color: purple - title: "Lunch break" + room: open-air-terrace type: lunch - location: Open-air terrace - class: middle - - - speaker: "Alberto Labarga" - title: "Building an End-to-End Open-Source Modern Data Platform for Biomedical Data" - description: "A detailed guide to help you navigate the modern data stack and build your own platform using open-source technologies.<br/><br/>Data engineering has experiences enormous growth in the last years, allowing for rapid progress and innovation as more people than ever are thinking about data resources and how to better leverage them.<br/><br/>In this talk we will explore the related technologies and build from scratch an end-to-end modern data platform for the analysis of medical data. We will be using open-source tools and libraries, including python-based DBT, Apache Airflow and Querybook.<br/><br/>The platform will consist of the following components:<ul><li>Data warehouse</li><li>Data integration</li><li>Data transformation</li><li>Data orchestration</li><li>Data visualization</li></ul>" - start_time_slot: 14:00 - end_time_slot: 15:15 + label: "Lunch break" + duration_minutes: 30 + - start: "14:00" track_length: 1 - color: yellow - type: workshop - language: "Spanish or English" + room: sala-dactes-ada-lovelace + talk: building-an-end-to-end-open-source-modern-data-platform-for python_level: beginner topic_level: intermediate - topic: "Data engineering" - location: Sala d'actes Ada Lovelace requirements: "Follow the installation steps in https://github.com/alabarga/pybcn22-modern-data-stack" - - speaker: "Jimena Escobar Bermúdez" - title: "Cuando los precios suben: Scrapy" - description: "Criptomonedas, la guerra en Ucrania, la pandemia, la falta de componentes y toda la serie de catastróficas desdichas que estamos sufriendo nos ha llevado a un punto en el que el precio de todo ha subido. En este taller aprenderemos a usar Scrapy para conseguir descargar, almacenar y comparar los precios de los productos que queramos." - start_time_slot: 14:00 - end_time_slot: 15:15 + - start: "14:00" track_length: 1 - color: blue - type: workshop - language: "Spanish" - title_lang: Spanish + room: sala-hedy-lamarr-margarita-salas + talk: cuando-los-precios-suben-scrapy python_level: beginner topic_level: beginner - topic: "Scrapy" requirements: "Laptop" - location: Sala Hedy Lamarr / Margarita Salas - - speaker: "Antonio Molina Garcia-Retamero" - title: "Inside out. Or how to get your app observable" - description: "Observability is key in distributed systems and it is gaining importance within the industry. So it is important to understand the concepts behind the idea of observabiity and why is important to us, as developers, to make our developments “observable”. Being able to create software that is easy to debug while systems scales and complexity grows will level up us as developers and will make our clients and employers far happier. This is what this workshop is about. From a brief theory of what observability is to some practices and best practices." - start_time_slot: 14:00 - end_time_slot: 15:15 + - start: "14:00" track_length: 1 - color: blue - type: workshop - language: "Spanish" + room: sala-hipatia-dalexandria + talk: inside-out-or-how-to-get-your-app-observable python_level: beginner topic_level: beginner requirements: "Laptop" - topic: "Observability" - location: Sala Hipàtia d'Alexandria - - - start_time_slot: 15:30 - end_time_slot: 15:45 + - start: "15:30" track_length: 3 - color: purple - title: "Lightning talks (session 1) & coffee" - description: " -<h2>Lightning talks</h2> - -<b>How to beat your friends in fantasy football</b><br> -<i>Alex Molas</i> -<p><q>Have you ever wondered how to win your friends in a football fantasy league? In this talk I will show how to use python to get the best performant team by using web scraping, operations research, and machine learning!</q></p> - -<b>Measuring media bias</b><br> -<i>Luis Ignacio Menéndez</i> -<p><q>We'd like to talk about a research project (working progress) trying to measure media bias in Spanish TV news. For this, we employ techniques of speech recognition, speaker diarization and text analysis. This project is carried on by PhD students of the Economics department at Universitat Autònoma de Barcelona.</q></p> - -<b>Astropy 5.X: astronomical tools for everybody</b><br> -<i>Francesc Vilardell Sallés</i> -<p><q>Astropy is now a mature python library with over 34.000 commits on Github and hundreds of contributors. Astropy is still little known beyond the astronomical community, but offers several powerful tools that are useful to all python developers. In this lightning talk I will present some of these tools. </q></p> - -<b>Fighting climate change the Python way</b><br> -<i>Rafael Giménez</i> -<p><q>The Digital Team at Cetaqua works in bringing state of the art AI (Computer Vision, Reinforcement Learning) to one of the most crucial issues of our time: water and environmental management. The talk aims to briefly showcase how we use Python for that.</q></p> - -<b>PyCamp España </b><br> -<i>Johanna Sanchez</i> -<p><q>Invitación a la comunidad para participar de un evento diferente</q></p> - -<b>PyLadies España y PyCon ES 2023</b><br> -<i>Johanna Sanchez</i> -<p><q>Invitación a la comunidad para participar en conferencia y comunidades</q></p> -" - type: talk - location: Sala d'actes Ada Lovelace - class: middle - - - speaker: "Cheuk Ting Ho" - title: "Using Numba Effectively Today" - description: "Numba is syntactically easy to use - just add a decorator, but actually very hard to use effectively. The reason being it is difficult to understand what Numba does to speed up the numeric operation. This workshop will provide all the knowledge that you need to make Numba works for you." - start_time_slot: 16:00 - end_time_slot: 17:15 + room: sala-dactes-ada-lovelace + talk: lightning-talks-session-1-coffee + - start: "16:00" track_length: 1 - color: red - type: workshop - language: "English" + room: sala-dactes-ada-lovelace + talk: using-numba-effectively-today python_level: intermediate topic_level: intermediate requirements: "This workshop is for Data scientists or developers who have math-heavy code that would like to speed up with the benefit of Numpy and Numba.<br/><br/>What is required from attendees<br/><br/><ul><li>- A computer with a stable internet connection (useful to look up information);</li><li>- Python 3.8 or above;</li><li>- Jupyter and Numba installed (detail about Python libraries required will be announced later);</li><li>- An opened mind and ready to learn something new</li></ul>" - topic: "Data Science" - location: Sala d'actes Ada Lovelace - - speaker: "Pere Miquel Brull" - title: "Making sense of your Data Platform with OpenMetadata" - description: "OpenMetadata is an open-source project (https://open-metadata.org/) that is building a metadata standard and a centralized and shared metadata platform on top of it. In this workshop, we will explore the tool, how it works, and bit by bit we will dive into its implementation and design." - start_time_slot: 16:00 - end_time_slot: 17:15 + - start: "16:00" track_length: 1 - color: yellow - type: workshop - language: "English" + room: sala-hedy-lamarr-margarita-salas + talk: making-sense-of-your-data-platform-with-openmetadata python_level: intermediate topic_level: beginner - topic: "Data Management" - location: Sala Hedy Lamarr / Margarita Salas requirements: "For the folks who would like to follow along, a laptop with docker compose" - - speaker: "Ana Eliza Barbosa" - title: "TDD Coding Dojo" - description: "Nowadays software products are becoming so complex that is unimaginable that one software engineer would develop it alone without any sort of automated testing, so let’s get together to practice Test Driven Development while pair programming with the other workshop participants. We will solve some code challenges together, under a bit of friendly time pressure and changing development hats every 5 minutes. If you are interested in knowing how it all looks like then join the workshop!" - start_time_slot: 16:00 - end_time_slot: 17:15 + - start: "16:00" track_length: 1 - color: blue - type: workshop - language: "English" + room: sala-hipatia-dalexandria + talk: tdd-coding-dojo python_level: beginner topic_level: beginner - topic: "Test driven development " - location: Sala Hipàtia d'Alexandria - - - start_time_slot: 17:30 - end_time_slot: 17:45 + - start: "17:30" track_length: 3 - color: purple - title: "Lightning talks (session 2) + closing session & Kahoot" - description: " -<h2>Lightning talks</h2> - -<b>Intenciones ganadoras: Cómo implementar la arquitectura de un chatbot basado en intenciones</b><br> -<i>Nadal Llabrés Belmar</i> -<p><q>En esta charla explicaremos los aspectos fundamentales de cómo diseñar e implementar un chatbot basado en el reconocimiento de intenciones desde el punto de vista de la ingeniería de Software. Mediante un caso de uso, exploramos cómo diseñar e implementar una arquitectura que nos permita integrar y gestionar la base de conocimiento que requiere el bot para su aprendizaje, integrar un motor de reconocimiento de intenciones que sea capaz de entender a los usuarios a partir de un entendimiento contextual de una conversación e integrar un sistema de respuestas en distintos formatos (voz, texto, imágenes, vídeos).</q></p> - -<b>Satellite super-resolution and 3d scenes</b><br> -<i>Biel Stela</i> -<p><q>Match the resolution of Landsat imagery to fine grained Sentinel using Deep Learning, then create dynamic evolving scenes with blender. </q></p> + room: sala-dactes-ada-lovelace + talk: lightning-talks-session-2-closing-session-kahoot -<b>trrex: Efficient keyword extraction with regex</b><br> -<i>Daniel Mesejo</i> -<p><q>In this talk I’m going to introduce the trrex package, for performing efficient keyword extraction with regular expressions. Additionally I'll show how to integrate it with pandas for text cleaning, how to use it with spacy to build a gazetteer and how to perform fuzzy matching with the regex library.</q></p> - -<b>Transactions</b><br> -<i>Christian Barra</i> -<p><q>The goal of the LT is to give to the audience a brief overview about DB transactions, why there are important and how to leverage them for some specific use cases where they play a critical role.</q></p> - -<b>Optimal binning using Python</b><br> -<i>Guillermo Navas Palencia</i> -<p><q>Presentation of the OptBinning library, a Python library to perform optimal binning and scorecard modelling. Description of main features, current roadmap and applications.</q></p> -" - type: talk - location: Sala d'actes Ada Lovelace - class: middle --- ## About PyDay BCN 2022 We are organizing the **the sixth edition** of PyDay in Barcelona! -PyDay is an event full of FREE **python-related workshops** and activities for the Python community, organized once per year. Over the [last five editions](#previous_editions_section), PyDay has become a great opportunity to share our love for Python and engage users, companies and newcomers into it! +PyDay is an event full of FREE **python-related workshops** and activities for the Python community, organized once per year. Over the last five editions, PyDay has become a great opportunity to share our love for Python and engage users, companies and newcomers into it! ### When and where diff --git a/content/events/pyday_bcn/pyday_bcn_2023.md b/content/events/pyday_bcn/pyday_bcn_2023.md index 57345f4c3..5f6b5820b 100644 --- a/content/events/pyday_bcn/pyday_bcn_2023.md +++ b/content/events/pyday_bcn/pyday_bcn_2023.md @@ -1,6 +1,10 @@ --- title: "PyDay BCN (2023)" year: 2023 +# The day of this edition, from the Meetup export, which records it per event. +date: 2023-11-11 +# The venue of this edition, from the Meetup export, which records it per event. +venue: "Universitat de Barcelona" description: "For the community, by the community!" menu: main: @@ -25,7 +29,6 @@ free_text_sections: id: registration content: "General registration will open on Monday 6th of November, at 9AM through <a target='_blank' href='https://www.eventbrite.es/e/entradas-pydaybcn-2023-751258453257?aff=oddtdtcreator'>Eventbrite</a>." -sponsors_text: "Would you like to sponsor this event? Please contact us at pydaybcn2023@googlegroups.com<br/><br/>" sponsor_levels: - sponsors_per_line: 2 sponsors: [qustodio, travelperk, iomed, flanks, preply] @@ -73,60 +76,46 @@ people_sections: - patricia-lamadrid-robles - elisabeth-ortega-carrasco -previous_editions: - - name: PyDay BCN 2022 - url: /events/pyday_bcn/pyday_bcn_2022/ - - name: PyDay BCN 2021 - url: /events/pyday_bcn/pyday_bcn_2021/ - - name: PyDay BCN 2020 - url: /events/pyday_bcn/pyday_bcn_2020/ - - name: PyDay BCN 2019 - url: /events/pyday_bcn/pyday_bcn_2019/ - - name: PyDay BCN 2018 - url: /events/pyday_bcn/pyday_bcn_2018/ - - name: PyDay BCN 2016 - url: /events/pyday_bcn/pyday_bcn_2016/ - spansDuration: 15 numTracks: 3 eventTimes: [ - 9:00, - 9:15, - 9:30, - 9:45, - 10:00, - 10:15, - 10:30, - 10:45, - 11:00, - 11:15, - 11:30, - 11:45, - 12:00, - 12:15, - 12:30, - 12:45, - 13:00, - 13:15, - 13:30, - 13:45, - 14:00, - 14:15, - 14:30, - 14:45, - 15:00, - 15:15, - 15:30, - 15:45, - 16:00, - 16:15, - 16:30, - 16:45, - 17:00, - 17:15, - 17:30, - 17:45, + "9:00", + "9:15", + "9:30", + "9:45", + "10:00", + "10:15", + "10:30", + "10:45", + "11:00", + "11:15", + "11:30", + "11:45", + "12:00", + "12:15", + "12:30", + "12:45", + "13:00", + "13:15", + "13:30", + "13:45", + "14:00", + "14:15", + "14:30", + "14:45", + "15:00", + "15:15", + "15:30", + "15:45", + "16:00", + "16:15", + "16:30", + "16:45", + "17:00", + "17:15", + "17:30", + "17:45", ] legend: - type: workshop @@ -135,300 +124,263 @@ legend: - level: beginner - level: intermediate - level: advanced -events: - - start_time_slot: 9:00 - end_time_slot: 9:15 - track_length: 3 - color: purple - title: "Registration & Welcome" - speaker: "PyDay BCN 2023 Organising Committee" - type: group - location: Room B5 - class: middle - - speaker: "Noé Casas" +# The rooms of this edition, in the order the grid first names them. A room is +# a record with an id because the colour of a block now comes from it: the +# template gives every room of an event one colour of the agenda palette and +# keeps it for the whole day. See partials/agenda_entry.html. +rooms: + - id: room-b5 + name: "Room B5" + - id: room-b6 + name: "Room B6" + - id: room-b3 + name: "Room B3" + - id: claustre + name: "Claustre" + +# The talks of this edition: what was said, by whom, in which language. A talk +# carries no time and no room, because it is the content and not the slot. +# agenda below is what places it on the grid, and one talk can take more than +# one slot. The id is derived from the title and is the anchor a photo of the +# gallery links to, so it must not change. +talks: + - id: introduction-to-neural-networks-with-pytorch title: "Introduction to Neural Networks with PyTorch" + speakers: [noe-casas] + type: workshop + language: en + topic: "Data science" + duration_minutes: 75 description: "In this session, we'll delve into the fundamentals of deep learning, explore the basics of PyTorch, and learn how to create and train simple neural networks. You won't need a GPU to run the code from the workshop. All you'll need is a computer with Python, PyTorch, and Jupyter installed." - start_time_slot: 9:30 - end_time_slot: 10:45 - track_length: 1 - color: blue + - id: quantum-computing-for-everyone + title: "Quantum Computing for Everyone" + speakers: [vyron-vasileiadis, adria-blanco, guillermo-abad, javier-sabariego] + type: workshop + language: en + topic: "Quantum Computing" + duration_minutes: 75 + description: "Quantum computing stands at the forefront of the next technological revolution, offering promises to solve problems beyond the reach of classical computers. This workshop aims to demystify the complex world of quantum computing, making it accessible to a broad audience, including students, professionals, and enthusiasts with varying levels of expertise in physics and computer science. We begin with a gentle introduction to the fundamental principles of quantum computing and key concepts such as superposition, entanglement, and quantum gates.\nMoving beyond theory, the focus will shift to practical aspects with an introduction to Qibo, a new open-source framework designed for quantum simulation and experimentation. Qibo provides an intuitive platform for implementing quantum algorithms, making it an ideal tool for both beginners and experienced researchers.\nThe highlight of the talk will be live demonstrations using Qibo. These demos will showcase how to set up a quantum environment, create simple quantum circuits, and run basic quantum algorithms." + - id: automating-networks-with-nornir + title: "Automating networks with Nornir" + speakers: [christian-adell] + type: workshop + language: en + topic: "Network/Infrastructure Automation" + duration_minutes: 75 + description: "In this workshop, we will leverage the Nornir Python framework to automate a network environment (but it could be applied to other infrastructure) in a multi-threaded way. We will also leverage other networking-related libraries such as NAPALM and Netmiko." + - id: introduction-to-artificial-emotional-intelligence-decode + title: "Introduction to Artificial [Emotional] Intelligence: Decode emotions with Deep Learning and Facial Recognition" + speakers: [emanuel-frazao] + type: workshop + language: en + topic: "Data Science" + duration_minutes: 75 + description: "One of the most interesting applications of artificial intelligence is Deep Learning, which involves using unstructured data such as images or text in conjunction with mathematical algorithms to create predictive models that will help us make more accurate decisions and enhance our analytical capabilities." + - id: quantum-breakthrough-from-basic-quantum-algorithms-to + title: "Quantum Breakthrough: From Basic Quantum Algorithms to Quantum Generative AI" + speakers: [pavel-sulimov] + type: workshop + language: en + topic: "Quantum Computing" + duration_minutes: 75 + description: "Recently, IBM has announced free access to quantum computers with 100+ qubits. Does it mean that soon anybody will be able to easily crack passwords, hack banking systems and extract government secrets? At this workshop, we'll discuss the pros and potential hurdles of quantum algorithms, as well as look at possibilities of making money with quantum technologies (and Python) - but without breaking the law: from risk assessment to option pricing." + - id: python-packaging-101 + title: "Python Packaging 101" + speakers: [ferran-jovell] + type: workshop + language: en + topic: "Python Packaging" + duration_minutes: 75 + description: "Have you ever wondered how does the pip install the packages? Would you like to know how to create your very own python package? In this workshop, we will go through on all the necessary steps to get started on creating python packages and uploading them to the Python Packaging Index (PyPI)." + - id: creating-virtual-worlds-generating-synthetic-data-for-ai + title: "Creating Virtual Worlds: Generating Synthetic Data for AI Digital Twins" + speakers: [alberto-labarga] + type: workshop + language: es + topic: "Data science" + duration_minutes: 75 + description: "In the era of digital transformation, the concept of \"Digital Twins\" has emerged as a powerful tool for simulating, predicting, and optimizing real-world systems. At the heart of these digital replicas lies data, and often, the challenge is to have enough high-quality data to train robust AI models. This is where synthetic data generation comes into play. In this workshop, participants will be introduced to the world of synthetic data generation and its pivotal role in enabling AI-based digital twins. We will delve into the challenges of real-world data, the need for synthetic data, and the methodologies to generate it using Python" + - id: creacion-de-apis-con-python-y-manejo-de-datos + title: "Creación de APIs con Python y manejo de datos" + title_lang: Spanish + speakers: [diego-giaquinta] type: workshop - language: "English" + language: es + topic: "API requests" + duration_minutes: 75 + description: "Implementación de APIs con Python, para poder realizar peticiones http e intercambio de información entre aplicaciones y automatizar tareas" + - id: create-a-personal-website-with-sphinx + title: "Create a personal website with sphinx" + speakers: [oriol-abril-pla] + type: workshop + language: en + topic: "Documentation and blogging" + duration_minutes: 75 + description: "Personal websites are becoming more common, and there are countless alternatives to create them. Sphinx might often not make that list, but it can do everything we need, and most python projects use it for their documentation, so it won't require you to learn any new tool." + - id: lightning-talks-session-1-coffee-break + title: "Lightning talks (session 1) & Coffee break" + type: talk + duration_minutes: 15 + description: " <h2>Lightning talks</h2>\n<b>Data Visualization using Blender</b><br> <i>Muhammad Usman</i> <p><q>Welcome to the 'Data Visualization using Python in Blender' adventure - where your data turns into a magic carpet ride through enchanted forests and talking teapots! Just like a certain enchanted rose or a friendly blue genie, we'll use Python scripting in Blender to bring your data to life in whimsical 3D visualizations, animated charts, and interactive scenes that would make any animated teapot dance with joy!</q></p>\n<b>Writing Code Is Not Your Job: Thoughts On Data Science On A Post-chatGPT World</b><br> <i>Álvaro Durán </i> <p><q>ChatGPT has taken the world by storm. Self-proclaimed futurists such as Chamath Palihapitiya have predicted the disruption of many multi-million dollar companies as a result. The role of data scientists, as a result, will be diminished if a machine can understand unstructured text.</q></p>\n<b>PyCamp 2024</b><br> <i>Israel Saeta</i> <p><q>We will present the PyCamp 2024 event that will take place in Girona next spring.</q></p>\n<b>Algorithmic Fairness (Ethics in Data)</b><br> <i>Neema Balolebwami Nelly</i> <p><q>Gain a profound understanding of the ethical dimensions in data-driven systems, focusing on algorithmic fairness. Discover how to implement fairness principles to promote just and equitable outcomes in your software projects.</q></p>\n<b>Demystifying LLM deployments in AWS SageMaker</b><br> <i>Guillermo Blasco</i> <p><q>OS LLMs (falcon, lama, mistral,...) can be challenging to deploy for production, but they are not! We will deploy lince-zero (fine tune of falcon7b by clibrain) in AWS SageMaker in 3 minutes from sage maker studio notebooks with python!</q></p> " + - id: retrieval-augmented-generation-from-scratch + title: "Retrieval Augmented Generation from scratch" + speakers: [gabriel-de-maeztu] + type: workshop + language: en + topic: "Data Science" + duration_minutes: 75 + description: "In this workshop, I will focus on how to build a Retrieval Augmented Generation model from scratch using Postgres pg_vector for efficient similarity search and Hugging Face Transformers for generating human-like text. This workshop is aimed at data scientists, NLP practitioners, and engineers interested in cutting-edge NLP techniques." + - id: mojo-el-poderoso-aliado-de-python + title: "Mojo: El poderoso aliado de Python" + title_lang: Spanish + speakers: [camilo-chacon-sartori] + type: workshop + language: es + topic: "General, Core" + duration_minutes: 75 + description: "En este workshop, te invitamos a explorar las virtudes de Mojo (https://www.modular.com/mojo), un nuevo lenguaje de programación que pretende ser un aliado de Python. Mojo aspira a ofrecer todas las funcionalidades de Python, y va más allá, al incorporar características adicionales que le permiten alcanzar un rendimiento superior." + - id: mob-programming-solving-coding-problems-collaboratively + title: "Mob programming: Solving coding problems collaboratively" + speakers: [israel-saeta-perez] + type: workshop + language: es + topic: "Test driven development" + duration_minutes: 75 + description: "Coding together is much more fun than coding alone! In this workshop we will learn from each other by solving a basic coding problem using mob programming and Test Driven Development techniques." + - id: lightning-talks-session-2-closing-session-kahoot + title: "Lightning talks (session 2) & Closing session & Kahoot" + type: talk + duration_minutes: 15 + description: " <h2>Lightning talks</h2>\n<b>Creación de APIs con Python y manejo de datos</b><br> <i>Diego Giaquinta</i> <p><q>Implementación sencilla de APIs con Python, para poder realizar peticiones http e intercambio de información entre aplicaciones.</q></p>\n<b>Step4ward: Empowering Women in Tech</b><br> <i>Susana Vázquez y Coral Olivares</i> <p><q>Come explore step4ward, a non-profit organization passionately crafted BY and FOR women. In just 5 minutes, learn how we're all about supporting women in the tech job market. We provide advice, build a community, and help with interview prep and early career steps. Let's break barriers and boost women in tech together!</q></p>\n<b>Common Security Vulnerabilities for Developers</b><br> <i>Dan Neciu</i> <p><q>Best practices for developers to protect themselves from scams and hacking attempts</q></p>\n<b>Machine Learning for time-series analysis in the context of IoT</b><br> <i>Raziel Amador</i> <p><q>In this light talk, I would like to present my implementation of temperature and humidity monitoring using Iot (Raspberry Pi, DHT22 sensor, all in Docker services), and Machine learning for time series analysis.</q></p>\n<b>How to support the Python open source ecosytem</b><br> <i>Oriol Abril</i> <p><q>I will showcase a wide array of ways for anyone to support the Python open source ecosystem, with a special focus on financial support. I won't have any special focus on special communities or libraries but will aim for a general overview: including open source contributions as part of one's job description, sponsoring events and/or libraries, donating to foundations that act as umbrella for the exisiting projects...</q></p>\n<b>Tinymem: a game under 40 lines and under 30mm</b><br> <i>Isaac Bernat</i> <p><q>We'll go through <a href='https://github.com/isaacbernat/tinymem' target='_blank'>tinymem</a>, a working example of a game programmed in MicroPython which has menus, audio, sprites, text, button inputs... All this under 40 lines of code available for the <a href='https://thumby.us/' target='_blank'>Thumby</a> hardware, which is a miniature Raspberry Pi Pico based console.</q></p> " + +# The grid, one row per slot of the day, in the order it is printed. A slot +# names the talk it holds, or carries its own label and type when it holds +# none: a break, the group photo, the welcome. The level and the requirements +# sit here and not on the talk, because they are what the slot asks of whoever +# walks into it. A start is always quoted: YAML 1.1 reads an unquoted 9:00 as +# the integer 540. +agenda: + - start: "9:00" + credited_as: "PyDay BCN 2023 Organising Committee" + track_length: 3 + room: room-b5 + type: group + label: "Registration & Welcome" + duration_minutes: 15 + - start: "9:30" + track_length: 1 + room: room-b6 + talk: introduction-to-neural-networks-with-pytorch python_level: beginner topic_level: beginner requirements: "Python, PyTorch, Jupyter, Matplotlib." - topic: "Data science" - location: Room B6 - - speaker: "Vyron Vasileiadis, Adrià Blanco, Guille Abad and Javier Sabariego" - title: "Quantum Computing for Everyone" - description: "Quantum computing stands at the forefront of the next technological revolution, offering promises to solve problems beyond the reach of classical computers. This workshop aims to demystify the complex world of quantum computing, making it accessible to a broad audience, including students, professionals, and enthusiasts with varying levels of expertise in physics and computer science. - We begin with a gentle introduction to the fundamental principles of quantum computing and key concepts such as superposition, entanglement, and quantum gates. - - Moving beyond theory, the focus will shift to practical aspects with an introduction to Qibo, a new open-source framework designed for quantum simulation and experimentation. Qibo provides an intuitive platform for implementing quantum algorithms, making it an ideal tool for both beginners and experienced researchers. - - The highlight of the talk will be live demonstrations using Qibo. These demos will showcase how to set up a quantum environment, create simple quantum circuits, and run basic quantum algorithms." - start_time_slot: 9:30 - end_time_slot: 10:45 + - start: "9:30" track_length: 1 - color: blue - type: workshop - language: "English" + room: room-b5 + talk: quantum-computing-for-everyone python_level: beginner topic_level: beginner requirements: "To have the `qibo` package installed." - topic: "Quantum Computing" - location: Room B5 - - speaker: "Christian Adell" - title: "Automating networks with Nornir" - description: "In this workshop, we will leverage the Nornir Python framework to automate a network environment (but it could be applied to other infrastructure) in a multi-threaded way. We will also leverage other networking-related libraries such as NAPALM and Netmiko." - start_time_slot: 9:30 - end_time_slot: 10:45 + - start: "9:30" track_length: 1 - color: yellow - type: workshop - language: "English" + room: room-b3 + talk: automating-networks-with-nornir python_level: beginner topic_level: intermediate - topic: "Network/Infrastructure Automation" - location: Room B3 - requirements: "" - - - start_time_slot: 11:00 - end_time_slot: 11:15 + - start: "11:00" track_length: 3 - color: purple - title: "Coffee break" + room: claustre type: coffee - location: Claustre - class: middle - - - speaker: "Emanuel Frazao" - title: "Introduction to Artificial [Emotional] Intelligence: Decode emotions with Deep Learning and Facial Recognition" - description: "One of the most interesting applications of artificial intelligence is Deep Learning, which involves using unstructured data such as images or text in conjunction with mathematical algorithms to create predictive models that will help us make more accurate decisions and enhance our analytical capabilities." - start_time_slot: 11:30 - end_time_slot: 12:45 + label: "Coffee break" + duration_minutes: 15 + - start: "11:30" track_length: 1 - color: blue - type: workshop - language: "English" + room: room-b6 + talk: introduction-to-artificial-emotional-intelligence-decode python_level: beginner topic_level: beginner - requirements: "" - topic: "Data Science" - location: Room B6 - - speaker: "Pavel Sulimov" - title: "Quantum Breakthrough: From Basic Quantum Algorithms to Quantum Generative AI" - description: "Recently, IBM has announced free access to quantum computers with 100+ qubits. Does it mean that soon anybody will be able to easily crack passwords, hack banking systems and extract government secrets? At this workshop, we'll discuss the pros and potential hurdles of quantum algorithms, as well as look at possibilities of making money with quantum technologies (and Python) - but without breaking the law: from risk assessment to option pricing." - start_time_slot: 11:30 - end_time_slot: 12:45 + - start: "11:30" track_length: 1 - color: yellow - type: workshop - language: "English" + room: room-b5 + talk: quantum-breakthrough-from-basic-quantum-algorithms-to python_level: intermediate topic_level: intermediate requirements: "Numpy, Scipy, Matplotlib, PyTorch, Qiskit" - topic: "Quantum Computing" - location: Room B5 - - speaker: "Ferran Jovell" - title: "Python Packaging 101" - description: "Have you ever wondered how does the pip install the packages? Would you like to know how to create your very own python package? - In this workshop, we will go through on all the necessary steps to get started on creating python packages and uploading them to the Python Packaging Index (PyPI)." - start_time_slot: 11:30 - end_time_slot: 12:45 + - start: "11:30" track_length: 1 - color: blue - type: workshop - language: "English" + room: room-b3 + talk: python-packaging-101 python_level: beginner topic_level: beginner requirements: "Laptop with latest Python version available and git installed" - topic: "Python Packaging" - location: Room B3 - - - start_time_slot: 13:00 - end_time_slot: 13:00 + - start: "13:00" track_length: 3 - color: pink - title: "Group photo" + room: claustre type: photo - location: Claustre - class: middle - - - start_time_slot: 13:15 - end_time_slot: 13:45 + label: "Group photo" + duration_minutes: 0 + - start: "13:15" track_length: 3 - color: purple - title: "Lunch break" + room: claustre type: lunch - location: Claustre - class: middle - - - speaker: "Alberto Labarga" - title: "Creating Virtual Worlds: Generating Synthetic Data for AI Digital Twins" - description: "In the era of digital transformation, the concept of \"Digital Twins\" has emerged as a powerful tool for simulating, predicting, and optimizing real-world systems. At the heart of these digital replicas lies data, and often, the challenge is to have enough high-quality data to train robust AI models. This is where synthetic data generation comes into play. In this workshop, participants will be introduced to the world of synthetic data generation and its pivotal role in enabling AI-based digital twins. We will delve into the challenges of real-world data, the need for synthetic data, and the methodologies to generate it using Python" - start_time_slot: 14:00 - end_time_slot: 15:15 + label: "Lunch break" + duration_minutes: 30 + - start: "14:00" track_length: 1 - color: yellow - type: workshop - language: "Spanish" + room: room-b6 + talk: creating-virtual-worlds-generating-synthetic-data-for-ai python_level: intermediate topic_level: beginner - requirements: "" - topic: "Data science" - location: Room B6 - - speaker: "Diego Giaquinta" - title: "Creación de APIs con Python y manejo de datos" - description: "Implementación de APIs con Python, para poder realizar peticiones http e intercambio de información entre aplicaciones y automatizar tareas" - start_time_slot: 14:00 - end_time_slot: 15:15 + - start: "14:00" track_length: 1 - color: yellow - type: workshop - language: "Spanish" - title_lang: Spanish + room: room-b5 + talk: creacion-de-apis-con-python-y-manejo-de-datos python_level: intermediate topic_level: intermediate - topic: "API requests" requirements: "Python 3.8 or above, VSCode or some similar IDE, FastApi and uvicorn libraries" - location: Room B5 - - speaker: "Oriol Abril" - title: "Create a personal website with sphinx" - description: "Personal websites are becoming more common, and there are countless alternatives to create them. Sphinx might often not make that list, but it can do everything we need, and most python projects use it for their documentation, so it won't require you to learn any new tool." - start_time_slot: 14:00 - end_time_slot: 15:15 + - start: "14:00" track_length: 1 - color: blue - type: workshop - language: "English" + room: room-b3 + talk: create-a-personal-website-with-sphinx python_level: beginner topic_level: beginner - requirements: "" - topic: "Documentation and blogging" - location: Room B3 - - - start_time_slot: 15:30 - end_time_slot: 15:45 + - start: "15:30" track_length: 3 - color: purple - title: "Lightning talks (session 1) & Coffee break" - description: " -<h2>Lightning talks</h2> - -<b>Data Visualization using Blender</b><br> -<i>Muhammad Usman</i> -<p><q>Welcome to the 'Data Visualization using Python in Blender' adventure – where your data turns into a magic carpet ride through enchanted forests and talking teapots! Just like a certain enchanted rose or a friendly blue genie, we'll use Python scripting in Blender to bring your data to life in whimsical 3D visualizations, animated charts, and interactive scenes that would make any animated teapot dance with joy!</q></p> - -<b>Writing Code Is Not Your Job: Thoughts On Data Science On A Post-chatGPT World</b><br> -<i>Álvaro Durán </i> -<p><q>ChatGPT has taken the world by storm. Self-proclaimed futurists such as Chamath Palihapitiya have predicted the disruption of many multi-million dollar companies as a result. The role of data scientists, as a result, will be diminished if a machine can understand unstructured text.</q></p> - -<b>PyCamp 2024</b><br> -<i>Israel Saeta</i> -<p><q>We will present the PyCamp 2024 event that will take place in Girona next spring.</q></p> - -<b>Algorithmic Fairness (Ethics in Data)</b><br> -<i>Neema Balolebwami Nelly</i> -<p><q>Gain a profound understanding of the ethical dimensions in data-driven systems, focusing on algorithmic fairness. Discover how to implement fairness principles to promote just and equitable outcomes in your software projects.</q></p> - -<b>Demystifying LLM deployments in AWS SageMaker</b><br> -<i>Guillermo Blasco</i> -<p><q>OS LLMs (falcon, lama, mistral,…) can be challenging to deploy for production, but they are not! We will deploy lince-zero (fine tune of falcon7b by clibrain) in AWS SageMaker in 3 minutes from sage maker studio notebooks with python!</q></p> -" - type: talk - location: Room B5 - class: middle - - - speaker: "Gabriel de Maeztu" - title: "Retrieval Augmented Generation from scratch" - description: "In this workshop, I will focus on how to build a Retrieval Augmented Generation model from scratch using Postgres pg_vector for efficient similarity search and Hugging Face Transformers for generating human-like text. This workshop is aimed at data scientists, NLP practitioners, and engineers interested in cutting-edge NLP techniques." - start_time_slot: 16:00 - end_time_slot: 17:15 + room: room-b5 + talk: lightning-talks-session-1-coffee-break + - start: "16:00" track_length: 1 - color: red - type: workshop - language: "English" + room: room-b6 + talk: retrieval-augmented-generation-from-scratch python_level: intermediate topic_level: advanced requirements: "Python, Docker" - topic: "Data Science" - location: Room B6 - - - speaker: "Camilo Chacón" - title: "Mojo: El poderoso aliado de Python" - description: "En este workshop, te invitamos a explorar las virtudes de Mojo (https://www.modular.com/mojo), un nuevo lenguaje de programación que pretende ser un aliado de Python. Mojo aspira a ofrecer todas las funcionalidades de Python, y va más allá, al incorporar características adicionales que le permiten alcanzar un rendimiento superior." - start_time_slot: 16:00 - end_time_slot: 17:15 + - start: "16:00" track_length: 1 - color: yellow - type: workshop - language: "Spanish" - title_lang: Spanish + room: room-b5 + talk: mojo-el-poderoso-aliado-de-python python_level: intermediate topic_level: intermediate - requirements: "" - topic: "General, Core" - location: Room B5 - - - speaker: "Israel Saeta" - title: "Mob programming: Solving coding problems collaboratively" - description: "Coding together is much more fun than coding alone! In this workshop we will learn from each other by solving a basic coding problem using mob programming and Test Driven Development techniques." - start_time_slot: 16:00 - end_time_slot: 17:15 + - start: "16:00" track_length: 1 - color: yellow - type: workshop - language: "Spanish" + room: room-b3 + talk: mob-programming-solving-coding-problems-collaboratively python_level: intermediate topic_level: beginner - requeriments: "Python with pytest installed, code editor, git (for downloading the exercise)." - topic: "Test driven development" - location: Room B3 - - - start_time_slot: 17:30 - end_time_slot: 17:45 + requirements: "Python with pytest installed, code editor, git (for downloading the exercise)." + - start: "17:30" track_length: 3 - color: purple - title: "Lightning talks (session 2) & Closing session & Kahoot" - description: " -<h2>Lightning talks</h2> - -<b>Creación de APIs con Python y manejo de datos</b><br> -<i>Diego Giaquinta</i> -<p><q>Implementación sencilla de APIs con Python, para poder realizar peticiones http e intercambio de información entre aplicaciones.</q></p> - -<b>Step4ward: Empowering Women in Tech</b><br> -<i>Susana Vázquez y Coral Olivares</i> -<p><q>Come explore step4ward, a non-profit organization passionately crafted BY and FOR women. In just 5 minutes, learn how we're all about supporting women in the tech job market. We provide advice, build a community, and help with interview prep and early career steps. Let's break barriers and boost women in tech together!</q></p> - -<b>Common Security Vulnerabilities for Developers</b><br> -<i>Dan Neciu</i> -<p><q>Best practices for developers to protect themselves from scams and hacking attempts</q></p> + room: room-b5 + talk: lightning-talks-session-2-closing-session-kahoot -<b>Machine Learning for time-series analysis in the context of IoT</b><br> -<i>Raziel Amador</i> -<p><q>In this light talk, I would like to present my implementation of temperature and humidity monitoring using Iot (Raspberry Pi, DHT22 sensor, all in Docker services), and Machine learning for time series analysis.</q></p> - -<b>How to support the Python open source ecosytem</b><br> -<i>Oriol Abril</i> -<p><q>I will showcase a wide array of ways for anyone to support the Python open source ecosystem, with a special focus on financial support. I won't have any special focus on special communities or libraries but will aim for a general overview: including open source contributions as part of one's job description, sponsoring events and/or libraries, donating to foundations that act as umbrella for the exisiting projects...</q></p> - -<b>Tinymem: a game under 40 lines and under 30mm</b><br> -<i>Isaac Bernat</i> -<p><q>We'll go through <a href='https://github.com/isaacbernat/tinymem' target='_blank'>tinymem</a>, a working example of a game programmed in MicroPython which has menus, audio, sprites, text, button inputs... All this under 40 lines of code available for the <a href='https://thumby.us/' target='_blank'>Thumby</a> hardware, which is a miniature Raspberry Pi Pico based console.</q></p> -" - type: talk - location: Room B5 - class: middle --- ## About PyDay BCN 2023 We are organizing the **the seventh edition** of PyDay in Barcelona! -PyDay is an event full of FREE **python-related workshops** and activities for the Python community, organized once per year. Over the [last six editions](#previous_editions_section), PyDay has become a great opportunity to share our love for Python and engage users, companies and newcomers into it! +PyDay is an event full of FREE **python-related workshops** and activities for the Python community, organized once per year. Over the last six editions, PyDay has become a great opportunity to share our love for Python and engage users, companies and newcomers into it! ### When and where diff --git a/content/events/pyday_bcn/pyday_bcn_2024.md b/content/events/pyday_bcn/pyday_bcn_2024.md index 3d1ebb105..c7639535a 100644 --- a/content/events/pyday_bcn/pyday_bcn_2024.md +++ b/content/events/pyday_bcn/pyday_bcn_2024.md @@ -1,6 +1,10 @@ --- title: "PyDay BCN (2024)" year: 2024 +# The day of this edition, from the Meetup export, which records it per event. +date: 2024-11-09 +# The venue of this edition, from the Meetup export, which records it per event. +venue: "Canòdrom" description: "For the community, by the community!" menu: main: @@ -25,7 +29,6 @@ free_text_sections: id: registration content: "General registration will open on Tuesday 5th of November, at 9AM through <a target='_blank' href='https://www.eventbrite.es/e/entradas-pydaybcn-2024-1068930563089?aff=oddtdtcreator'>Eventbrite</a>." -sponsors_text: "Would you like to sponsor this event? Please contact us at pyday2024@googlegroups.com<br/><br/>" sponsor_levels: - sponsors_per_line: 2 sponsors: [lambdaloopers, nagarro, innovamat, protopixel, pythones, isdieducation, coopdevs, rover, quside] @@ -68,62 +71,46 @@ people_sections: - jose-riera-sanchez -previous_editions: - - name: PyDay BCN 2023 - url: /events/pyday_bcn/pyday_bcn_2023/ - - name: PyDay BCN 2022 - url: /events/pyday_bcn/pyday_bcn_2022/ - - name: PyDay BCN 2021 - url: /events/pyday_bcn/pyday_bcn_2021/ - - name: PyDay BCN 2020 - url: /events/pyday_bcn/pyday_bcn_2020/ - - name: PyDay BCN 2019 - url: /events/pyday_bcn/pyday_bcn_2019/ - - name: PyDay BCN 2018 - url: /events/pyday_bcn/pyday_bcn_2018/ - - name: PyDay BCN 2016 - url: /events/pyday_bcn/pyday_bcn_2016/ - spansDuration: 15 numTracks: 4 eventTimes: [ - 9:00, - 9:15, - 9:30, - 9:45, - 10:00, - 10:15, - 10:30, - 10:45, - 11:00, - 11:15, - 11:30, - 11:45, - 12:00, - 12:15, - 12:30, - 12:45, - 13:00, - 13:15, - 13:30, - 13:45, - 14:00, - 14:15, - 14:30, - 14:45, - 15:00, - 15:15, - 15:30, - 15:45, - 16:00, - 16:15, - 16:30, - 16:45, - 17:00, - 17:15, - 17:30, - 17:45, + "9:00", + "9:15", + "9:30", + "9:45", + "10:00", + "10:15", + "10:30", + "10:45", + "11:00", + "11:15", + "11:30", + "11:45", + "12:00", + "12:15", + "12:30", + "12:45", + "13:00", + "13:15", + "13:30", + "13:45", + "14:00", + "14:15", + "14:30", + "14:45", + "15:00", + "15:15", + "15:30", + "15:45", + "16:00", + "16:15", + "16:30", + "16:45", + "17:00", + "17:15", + "17:30", + "17:45", ] legend: - type: workshop @@ -132,394 +119,304 @@ legend: - level: beginner - level: intermediate - level: advanced -events: - - start_time_slot: 9:00 - end_time_slot: 9:15 + +# The rooms of this edition, in the order the grid first names them. A room is +# a record with an id because the colour of a block now comes from it: the +# template gives every room of an event one colour of the agenda palette and +# keeps it for the whole day. See partials/agenda_entry.html. +rooms: + - id: sala-dactes-ada-lovelace + name: "Sala d'actes Ada Lovelace" + - id: sala-margarita-salas + name: "Sala Margarita Salas" + - id: grades + name: "Grades" + - id: aula-hedy-lamarr + name: "Aula Hedy Lamarr" + - id: aula-hipatia-dalexandria + name: "Aula Hipàtia d'Alexandria" + +# The talks of this edition: what was said, by whom, in which language. A talk +# carries no time and no room, because it is the content and not the slot. +# agenda below is what places it on the grid, and one talk can take more than +# one slot. The id is derived from the title and is the anchor a photo of the +# gallery links to, so it must not change. +talks: + - id: unboxing-machine-learning-models-predicting-with-numpy + title: "Unboxing Machine Learning Models: Predicting with Numpy After Model Training" + speakers: [xiang-xu] + type: workshop + language: en + topic: "Data science, ML" + duration_minutes: 75 + description: "In this hands-on workshop, we'll bridge the gap between high-level machine learning libraries (like Scikit-learn and Keras) and the core mathematical principles driving their predictions. Participants will firstly train regression models using machine learning methods like Kernel Ridge Regression (KRR) and Deep Neural Networks (DNNs), save the trained model parameters, and then use only Numpy to replicate the prediction process." + - id: discovering-etl-testing-essential-for-your-ai-solutions + title: "Discovering ETL Testing: Essential for Your AI Solutions" + speakers: [paula-bassaganas-odena] + type: workshop + language: en + topic: "Testing" + duration_minutes: 75 + description: "High-quality data is the foundation of effective AI, and rigorous ETL testing ensures your AI models are built on solid ground. ETL (Extract, Transform, Load) processes are vital for extracting, transforming, and loading data into systems for analysis, and well-tested ETLs are crucial for making reliable, data-driven decisions and successful AI implementations." + - id: lightning-talks-coffee + title: "Lightning talks & coffee" + type: talk + duration_minutes: 0 + description: " <h2>Lightning talks</h2>\n<b>IZI Record, revolutionizing the camera app</b><br> <i>Ferran Jovell </i> <p><q>What we do at izi? How do we generate videos from different sources? How does it all work?!</q></p>\n<b>A solution to store, catalog and visualize images using Django and Django Rest Framework. </b><br> <i>Josep Sitjar Suñer</i> <p><q>KeepYourPhoto (https://keepyourphoto.com) is a personal project developed with Django (Python) on the backend and Vue.js on the frontend, created in my free time to store, catalog and share photos. <br><br> During the last 5 years, since my daughter was born, our family has been accumulating gigabytes of images. Especially when she started kindergarten, the amount of images increased exponentially, as we've received a catalog of hundred of images for each activity they did. And of course, we want to keep all them as a treasure. <br><br> First, we exhausted the available free space of providers like Google Drive or Dropbox. Then we start paying some basic plans. But in order to keep control of all these images, and implement custom functions to catalog and to share them with other members of the family, I decided to create my own solution. <br><br> I've developed a web application, with Django on the backend. The images are stored on AWS S3, and served with Cloudfront to increase the speed and security of access to them. Django-storages has been a good ally to implement that. <br> In order to create the API, I've been using the Django Rest Framework, and as I work in the geospatial sector (as web map developer) it was mandatory to geolocate all the images with coordinates in their metadata. In that sense, I've been using GeoDjango. <br><br> The platform is not completely finished, as I try to implement new functionalities in my free time. But It's working as expected. It's possible to create albums, massively upload images to them, visualize the images through a gallery carousel, delete albums and images, and visualize over a map the photos with coordinates on their metadata. <br><br> I've received interest from other people, and now I'm trying to make it available to them. The self- registry is working, but it is not yet a payment solution to afford the storage costs at AWS. <br><br> During the talk, my idea is to present the tool and the technological solutions to implement it.</q></p> " + - id: image-generation-with-ai-gans-and-diffusion-techniques + title: "Image Generation with AI (GANs and Diffusion Techniques)" + speakers: [marina-palma] + type: workshop + language: es + topic: "Artificial Intelligence" + duration_minutes: 75 + description: "This workshop explores the techniques of AI-driven image generation, focusing on two powerful models: Generative Adversarial Networks (GANs) and Diffusion Models. Participants will learn the fundamental principles, practical applications, and differences between these approaches. Through hands-on exercises, attendees will build three types of GANs, progressing from basic to more advanced models, for generating custom synthetic images." + - id: introduccio-a-xarray-etiqueta-les-teves-dades-n-dimensionals + title: "Introducció a xarray: etiqueta les teves dades n-dimensionals" + title_lang: Catalan + speakers: [oriol-abril-pla] + type: workshop + language: ca + topic: "Data science" + duration_minutes: 75 + description: "Apren com utilitzar xarray per treballar amb arrays n-dimensionals a través d'etiquetes i indexs arbitraris. Descobreix el model de dades d'xarray: DataArrays, Datasets, dimensions, coordenades, indexes. Explora a través del tutorial les operacions més comunes en matrius n-dimensionals: com especificar en quines dimensions han d'operar les funcions utilitzant noms enlloc d'indexs posicionals, com definir subconjunts a través de coordenades, com combinar el metode `.query` amb filtrar multiples dimensions, com crear multiples indexs per a una mateixa dimensió, les diferencies entre operacions d'indexatge exteriors o vectoritzades, groupbys multidimensionals, i més." + - id: static-typing-in-python + title: "Static Typing in Python" + speakers: [alex-molas] + type: workshop + language: en + topic: "Programming" + duration_minutes: 75 + description: "Since 2014, with the introduction of type hints in Python 3.5, Python has been adding support to types while still maintaining its dynamic nature. Later, in Python 3.10, pattern matching was added to Python, which provides a powerful way to match data structures based on their types and values, improving Python's capability to work with typed data. Both type hints and pattern matching help make code more testable, predictable and robust.<br> In this talk, we'll answer the following questions: <br> - **Introduction to types in Python**: what's a type? which types does python have? What do they mean?<br> - **The basics of type hints**: how to define a type hint? <br> - **mypy**: how to use mypy to check that your code does what you expect?<br> - **Advanced type hints**: how to define complex type hints? how to define your own types? how to use generic types?<br> - **Data validation**: how to use Pydantic and dataclasses for data validation?<br> - **Pattern matching**: how to use pattern matching together with type hints to write cleaner and more maintainable code.<br> By the end of this talk, you'll have a clear understanding of how to use type hints effectively and why they're a valuable tool in any Python developer's toolkit." + - id: building-data-pipelines-with-sqlmesh + title: "Building data pipelines with SQLMesh" + speakers: [marc-ramirez] + type: workshop + language: es + topic: "Data engineering" + duration_minutes: 75 + description: "In this session, participants will gain an in-depth understanding of SQLMesh's core concepts, including its innovative approach to environments (physical and virtual layers), diverse model types, and the integration of SQL and Python models. We'll also explore SQLMesh's testing framework, enabling reliable data transformations through rigorous validation. Attendees will be equipped with practical knowledge of how SQLMesh can streamline data pipeline development, making it easier to manage complex transformations and collaborate across data teams." + - id: lightning-talks-1345 + title: "Lightning talks" + type: talk + duration_minutes: 0 + description: " <h2>Lightning talks</h2>\n<b>Leveraging Python in AWS for Smarter Stock Investment Strategies</b><br> <i>Przemyslaw Mikulski</i> <p><q>In this lightning talk, I'll demonstrate how Python can be a powerful ally for retail investors seeking to optimize their stock investments. We'll explore, in just five minutes, how to use Python libraries to solve common challenges faced by investors: data acquisition, analysis, and automation using AWS.</q></p>\n<b>La Rosalía Unveiled: Decoding Her Lyrics with AI</b><br> <i>Olga Ss</i> <p><q>We'll dive into the lyrics of urban singer Rosalía through the lens of Artificial Intelligence, specifically using NLP techniques.</q></p> " + - id: lightning-talks-1545 + title: "Lightning talks" + type: talk + duration_minutes: 0 + description: " <h2>Lightning talks</h2>\n<b>Polars: Procesando datos a la velocidad de la luz con recursos espartanos</b><br> <i>Fernando Aparicio</i> <p><q>Pandas y Spark son las herramientas más conocidas para gestionar nuestros sets de datos, pero hay un jugador nuevo que quiere cambiar las reglas.Polars está pensado para el rendimiento y la resiliencia en entornos con pocos recursos. Cada megabyte y cada segundo cuenta. Os explicaré qué lo hace diferente al resto y qué es capaz de hacer.</q></p>\n<b>Evita bugs amb Pre-Commit</b><br> <i>Carles Julià</i> <p><q>How we improve code quality in our company for Python: pre-commit, ruff-format, ruff, mypy, etc</q></p> " + - id: lightning-talks-1730 + title: "Lightning talks" + type: talk + duration_minutes: 0 + description: " <h2>Lightning talks</h2>\n<b>La iniciativa Scientific Python</b><br> <i>Oriol Abril Pla</i> <p><q>Fa uns anys es va engegar la iniciativa Scientific Python, amb l'objectiu d'enfortir la col·laboració entre llibreries de Python en el camp de la computació científica. En els 5 minuts intentaré explicar què és i algunes de les seves iniciatives principals, que van des de gestió de dependències a consells d'accessibilitat passant per traduccions, 'nightly builds' o governança.</q></p>\n<b>DrugScope: a ML-based platform for drug discovery</b><br> <i>Verónica Larroy</i> <p><q>DrugScope is a machine learning-powered tool designed to predict the binding affinity of small molecules to specific proteins, aiming to accelerate drug discovery and reduce costs. Using Graph Neural Networks (GNNs), the project models molecular structures as graphs, with atoms as nodes and bonds as edges. A public dataset from Leash Biosciences, containing around 300 million molecules and their interactions with three key proteins (HSA, BRD4, and SEH), was used for model training. <br><br> The project involved developing three separate GNN models, one for each protein, to capture the unique molecular interactions relevant to each target. Features for atoms and bonds were extracted using RDKit, and the data was prepared for training by converting these features into graph structures. The models were deployed using FastAPI, allowing researchers to input molecule data and receive predictions on binding affinity, potentially helping speed up the early stages of drug development.</q></p>\n<b>Can LLMs Power Product Recommendations?</b><br> <i>Babaniyi Olaniyi</i> <p><q>I will discuss the use of large language models (LLMs) for product recommendation systems, leveraging their natural language understanding capabilities to predict items a user might purchase given their historical product reviews and purchases.</q></p>\n<b>Pixel2Mechanics: Automated Biomechanical Simulations of High-Resolution Intervertebral Discs from Anisotropic MRIs</b><br> <i>Sai Natarajan</i> <p><q>This study presents Pixel2Mechanics, an automated pipeline for generating patient-specific biomechanical finite element (FE) models of lumbar intervertebral discs (IVD) from clinical MRI data. It utilizes a deep learning framework to create high-resolution meshes of the Annulus Fibrosus (AF) and Nucleus Pulposus (NP) across L1-L2 to L4-L5. The pipeline features a novel optimization method based on differentiable rendering and a Bayesian Coherent Point Drift++ morphing algorithm for volumetric FE meshes that maintain tissue topology. Load simulations validate the models against manual segmentation, demonstrating potential for clinical integration in diagnosing and treating IVD degeneration.</q></p> " + - id: a-kingdom-above-the-clouds-how-far-can-you-go-on-aws-for-1 + title: "A kingdom above the clouds: How far can you go on AWS for $1 a month?" + speakers: [kemalcan-bora] + type: workshop + language: en + topic: "Serverless development" + duration_minutes: 75 + description: "Let's discover how to create a fully functional serverless application that costs less than your morning coffee! We'll build Cloud Kingdom, a cool document processing app that uses AWS Lambda, S3, SQS, and SNS, topped with AI capabilities from Claude. You'll learn how to upload documents, generate automatic summaries, and notify users, all while keeping your wallet happy." + - id: a-deep-dive-into-the-arrow-columnar-format-with-pyarrow-and + title: "A deep dive into the Arrow Columnar format with pyarrow and nanoarrow" + speakers: [raul-cumplido] + type: workshop + language: en + topic: "Apache Arrow, Data Science" + duration_minutes: 75 + description: "Apache Arrow has become a de-facto standard for efficient in-memory columnar data representation. You might have heard about Arrow or using Arrow, but do you understand the format and why it's so useful? This workshop will dive deep into the details of the Arrow columnar format, the different types and buffer layouts, and explore those details interactively using the pyarrow and nanoarrow libraries." + - id: automate-end-to-end-mlflow-with-kestra-and-mlflow + title: "Automate end to end MLflow with Kestra and MLFlow" + speakers: [manuel-gijon-agudo] + type: workshop + language: en + topic: "Data engineering" + duration_minutes: 75 + description: "During this session we are going to create a whole ML pipeline, from gathering and prepare the data to train different models and perform inference. We will use a Kaggle competition as our use case. We will learn the basics of Kestra, an orchestration platform, and MLFlow, a tool for keeping track of all processes relative to the full lifecycle for machine learning projects. We are going to use these tools to download a dataset from Kaggle, analyse it, process it, train different models by using different algorithms, perform inference on submission samples, and automatically upload the results back to Kaggle." + - id: open-source-databases-python-devs + title: "Open Source Databases Python Devs" + speakers: [dave-pitts] + type: workshop + language: en + topic: "Databases" + duration_minutes: 75 + description: "Are you interested in exploring open-source databases? Maybe you have experience with MySQL or PostgreSQL? Perhaps you are unsure which one to pick for your next project, then this workshop is for you. Both are highly successful open-source projects, with many similarities but also some notable differences. I'll also touch on some techniques for optimizing database queries." + - id: lembolic-videojuegos-hechos-en-el-frontend-por-un-lenguaje + title: "L'Embolic: Videojuegos hechos en el frontend por un lenguaje de backend" + title_lang: Spanish + speakers: [jimena-escobar-bermudez] + type: workshop + language: es + topic: "Web development, Videogames" + duration_minutes: 75 + description: "¿Te gustan los videojuegos? Entonces, seguro sabes que, desde hace años, los juegos diseñados para ejecutarse en el navegador son bastante populares, tanto por la facilidad de desarrollo como por su versatilidad, al poder jugarlos independientemente del sistema operativo. ¿Y si te digo que ya no es necesario dominar todos los entresijos del desarrollo frontend para poder crearlos? Hoy en día, podrías programarlos con tus conocimientos de Python. PyScript es un framework que permite crear aplicaciones que se ejecutan en el navegador y, con un poco de práctica, ¡incluso podemos desarrollar juegos! Pásate por este taller y te enseñaré cómo hacerlo." + - id: predict-gender-equality-with-your-own-machine-learning-model + title: "Predict gender equality with your own Machine Learning model" + speakers: [asia-noble] + type: workshop + language: en + topic: "Data science" + duration_minutes: 75 + description: "In this session, you will use Python and Pandas to analyze how gender equality (or inequality) reveals itself through data.<br> What you'll learn:<br> <br>✅ The logic and foundations behind Machine Learning <br>✅ The different use cases of Machine Learning <br>✅ How to predict the gender pay gap" + +# The grid, one row per slot of the day, in the order it is printed. A slot +# names the talk it holds, or carries its own label and type when it holds +# none: a break, the group photo, the welcome. The level and the requirements +# sit here and not on the talk, because they are what the slot asks of whoever +# walks into it. A start is always quoted: YAML 1.1 reads an unquoted 9:00 as +# the integer 540. +agenda: + - start: "9:00" + credited_as: "PyDay BCN 2024 Organizing Committee" track_length: 4 - color: purple - title: "Registration & Welcome" - speaker: "PyDay BCN 2024 Organizing Committee" + room: sala-dactes-ada-lovelace type: group - location: "Sala d'actes Ada Lovelace" - class: middle - - speaker: "Xiang Xu" - title: "Unboxing Machine Learning Models: Predicting with Numpy After Model Training" - description: "In this hands-on workshop, we’ll bridge the gap between high-level machine learning libraries (like Scikit-learn and Keras) and the core mathematical principles driving their predictions. Participants will firstly train regression models using machine learning methods like Kernel Ridge Regression (KRR) and Deep Neural Networks (DNNs), save the trained model parameters, and then use only Numpy to replicate the prediction process." - start_time_slot: 9:30 - end_time_slot: 10:45 + label: "Registration & Welcome" + duration_minutes: 15 + - start: "9:30" track_length: 1 - color: red - type: workshop - language: English + room: sala-dactes-ada-lovelace + talk: unboxing-machine-learning-models-predicting-with-numpy python_level: intermediate topic_level: intermediate requirements: "numpy, scikit-learn, and keras installed" - topic: "Data science, ML" - location: "Sala d'actes Ada Lovelace" - - speaker: "" - title: "" - description: "" - start_time_slot: 9:30 - end_time_slot: 10:45 + - start: "9:30" track_length: 1 - color: grey type: workshop - language: - python_level: "" - topic_level: "" - requirements: "" - topic: "" - location: - - speaker: "" - title: "" - description: "" - start_time_slot: 9:30 - end_time_slot: 10:45 + duration_minutes: 75 + - start: "9:30" track_length: 1 - color: grey type: workshop - language: - python_level: "" - topic_level: "" - requirements: "" - topic: "" - location: - - speaker: "Paula Bassagañas Òdena" - title: "Discovering ETL Testing: Essential for Your AI Solutions" - description: "High-quality data is the foundation of effective AI, and rigorous ETL testing ensures your AI models are built on solid ground. ETL (Extract, Transform, Load) processes are vital for extracting, transforming, and loading data into systems for analysis, and well-tested ETLs are crucial for making reliable, data-driven decisions and successful AI implementations." - start_time_slot: 9:30 - end_time_slot: 10:45 + duration_minutes: 75 + - start: "9:30" track_length: 1 - color: yellow - type: workshop - language: "English" + room: sala-margarita-salas + talk: discovering-etl-testing-essential-for-your-ai-solutions python_level: beginner topic_level: beginner - topic: "Testing" - location: "Sala Margarita Salas" requirements: "A Github account" - - start_time_slot: 11:00 - end_time_slot: 11:00 + - start: "11:00" track_length: 4 - color: orange - title: "Coffee break" + room: grades type: coffee - location: "Grades" - class: middle - - start_time_slot: 11:15 - end_time_slot: 11:15 + label: "Coffee break" + duration_minutes: 0 + - start: "11:15" track_length: 4 - color: purple - title: "Lightning talks & coffee" - type: talk - location: "Aula Hedy Lamarr" - class: middle - description: " -<h2>Lightning talks</h2> - -<b>IZI Record, revolutionizing the camera app</b><br> -<i>Ferran Jovell </i> -<p><q>What we do at izi? How do we generate videos from different sources? How does it all work?!</q></p> - -<b>A solution to store, catalog and visualize images using Django and Django Rest Framework. </b><br> -<i>Josep Sitjar Suñer</i> -<p><q>KeepYourPhoto (https://keepyourphoto.com) is a personal project developed with Django (Python) on the backend and Vue.js on the frontend, created in my free time to store, catalog and share photos. -<br><br> -During the last 5 years, since my daughter was born, our family has been accumulating gigabytes of images. Especially when she started kindergarten, the amount of images increased exponentially, as we’ve received a catalog of hundred of images for each activity they did. And of course, we want to keep all them as a treasure. -<br><br> -First, we exhausted the available free space of providers like Google Drive or Dropbox. Then we start paying some basic plans. But in order to keep control of all these images, and implement custom functions to catalog and to share them with other members of the family, I decided to create my own solution. -<br><br> -I’ve developed a web application, with Django on the backend. The images are stored on AWS S3, and served with Cloudfront to increase the speed and security of access to them. Django-storages has been a good ally to implement that. -<br> -In order to create the API, I’ve been using the Django Rest Framework, and as I work in the geospatial sector (as web map developer) it was mandatory to geolocate all the images with coordinates in their metadata. In that sense, I’ve been using GeoDjango. -<br><br> -The platform is not completely finished, as I try to implement new functionalities in my free time. But It’s working as expected. It’s possible to create albums, massively upload images to them, visualize the images through a gallery carousel, delete albums and images, and visualize over a map the photos with coordinates on their metadata. -<br><br> -I’ve received interest from other people, and now I’m trying to make it available to them. The self- registry is working, but it is not yet a payment solution to afford the storage costs at AWS. -<br><br> -During the talk, my idea is to present the tool and the technological solutions to implement it.</q></p> -" - - - speaker: "Marina Palma" - title: "Image Generation with AI (GANs and Diffusion Techniques)" - description: "This workshop explores the techniques of AI-driven image generation, focusing on two powerful models: Generative Adversarial Networks (GANs) and Diffusion Models. Participants will learn the fundamental principles, practical applications, and differences between these approaches. Through hands-on exercises, attendees will build three types of GANs, progressing from basic to more advanced models, for generating custom synthetic images." - start_time_slot: 11:30 - end_time_slot: 12:45 + room: aula-hedy-lamarr + talk: lightning-talks-coffee + - start: "11:30" track_length: 1 - color: red - type: workshop - language: "Spanish" + room: sala-dactes-ada-lovelace + talk: image-generation-with-ai-gans-and-diffusion-techniques python_level: beginner topic_level: beginner requirements: "torch==2.0.1 torchvision==0.15.2 matplotlib==3.7.1" - topic: "Artificial Intelligence" - location: "Sala d'actes Ada Lovelace" - - speaker: "Oriol Abril Pla" - title: "Introducció a xarray: etiqueta les teves dades n-dimensionals" - description: "Apren com utilitzar xarray per treballar amb arrays n-dimensionals a través d'etiquetes i indexs arbitraris. - Descobreix el model de dades d'xarray: DataArrays, Datasets, dimensions, coordenades, indexes. - Explora a través del tutorial les operacions més comunes en matrius n-dimensionals: com especificar en quines dimensions han d'operar les funcions utilitzant noms enlloc d'indexs posicionals, com definir subconjunts a través de coordenades, com combinar el metode `.query` amb filtrar multiples dimensions, com crear multiples indexs per a una mateixa dimensió, les diferencies entre operacions d'indexatge exteriors o vectoritzades, groupbys multidimensionals, i més." - start_time_slot: 11:30 - end_time_slot: 12:45 + - start: "11:30" track_length: 1 - color: green - type: workshop - language: "Català" - title_lang: Catalan + room: aula-hipatia-dalexandria + talk: introduccio-a-xarray-etiqueta-les-teves-dades-n-dimensionals python_level: beginner topic_level: beginner requirements: "https://github.com/OriolAbril/pyday2024-xarray/blob/main/requirements.txt" - topic: "Data science" - location: "Aula Hipàtia d'Alexandria" - - speaker: "Alex Molas" - title: "Static Typing in Python" - description: "Since 2014, with the introduction of type hints in Python 3.5, Python has been adding support to types while still maintaining its dynamic nature. Later, in Python 3.10, pattern matching was added to Python, which provides a powerful way to match data structures based on their types and values, improving Python’s capability to work with typed data. Both type hints and pattern matching help make code more testable, predictable and robust.<br> - In this talk, we’ll answer the following questions: <br> - - **Introduction to types in Python**: what's a type? which types does python have? What do they mean?<br> - - **The basics of type hints**: how to define a type hint? <br> - - **mypy**: how to use mypy to check that your code does what you expect?<br> - - **Advanced type hints**: how to define complex type hints? how to define your own types? how to use generic types?<br> - - **Data validation**: how to use Pydantic and dataclasses for data validation?<br> - - **Pattern matching**: how to use pattern matching together with type hints to write cleaner and more maintainable code.<br> - By the end of this talk, you’ll have a clear understanding of how to use type hints effectively and why they’re a valuable tool in any Python developer’s toolkit." - start_time_slot: 11:30 - end_time_slot: 12:45 + - start: "11:30" track_length: 1 - color: yellow - type: workshop - language: "English" + room: aula-hedy-lamarr + talk: static-typing-in-python python_level: beginner topic_level: intermediate requirements: "https://github.com/alexmolas/python-static-typing/blob/main/requirements.txt" - topic: "Programming" - location: "Aula Hedy Lamarr" - - speaker: "Marc Ramirez Invernon" - title: "Building data pipelines with SQLMesh" - description: "In this session, participants will gain an in-depth understanding of SQLMesh’s core concepts, including its innovative approach to environments (physical and virtual layers), diverse model types, and the integration of SQL and Python models. We’ll also explore SQLMesh’s testing framework, enabling reliable data transformations through rigorous validation. Attendees will be equipped with practical knowledge of how SQLMesh can streamline data pipeline development, making it easier to manage complex transformations and collaborate across data teams." - start_time_slot: 11:30 - end_time_slot: 12:45 + - start: "11:30" track_length: 1 - color: blue - type: workshop - language: "Spanish" + room: sala-margarita-salas + talk: building-data-pipelines-with-sqlmesh python_level: beginner topic_level: intermediate requirements: "Git, Docker Desktop, Visual Studio Code" - topic: "Data engineering" - location: "Sala Margarita Salas" - - - start_time_slot: 13:00 - end_time_slot: 13:00 + - start: "13:00" track_length: 4 - color: purple - title: "Group photo" + room: grades type: photo - location: Grades - class: middle - - - start_time_slot: 13:15 - end_time_slot: 13:30 + label: "Group photo" + duration_minutes: 0 + - start: "13:15" track_length: 4 - color: orange - title: "Lunch break" + room: grades type: lunch - location: Grades - class: middle - - - start_time_slot: 13:45 - end_time_slot: 13:45 + label: "Lunch break" + duration_minutes: 15 + - start: "13:45" track_length: 4 - color: purple - title: "Lightning talks" - type: talk - location: Aula Hedy Lamarr - class: middle - description: " -<h2>Lightning talks</h2> - -<b>Leveraging Python in AWS for Smarter Stock Investment Strategies</b><br> -<i>Przemyslaw Mikulski</i> -<p><q>In this lightning talk, I’ll demonstrate how Python can be a powerful ally for retail investors seeking to optimize their stock investments. We’ll explore, in just five minutes, how to use Python libraries to solve common challenges faced by investors: data acquisition, analysis, and automation using AWS.</q></p> - -<b>La Rosalía Unveiled: Decoding Her Lyrics with AI</b><br> -<i>Olga Ss</i> -<p><q>We'll dive into the lyrics of urban singer Rosalía through the lens of Artificial Intelligence, specifically using NLP techniques.</q></p> -" - - - speaker: "Kemalcan Bora" - title: "A kingdom above the clouds: How far can you go on AWS for $1 a month?" - description: "Let's discover how to create a fully functional serverless application that costs less than your morning coffee! - We'll build Cloud Kingdom, a cool document processing app that uses AWS Lambda, S3, SQS, and SNS, topped with AI capabilities from Claude. You'll learn how to upload documents, generate automatic summaries, and notify users, all while keeping your wallet happy." - start_time_slot: 14:00 - end_time_slot: 15:15 + room: aula-hedy-lamarr + talk: lightning-talks-1345 + - start: "14:00" track_length: 1 - color: yellow - type: workshop - language: "English" + room: sala-dactes-ada-lovelace + talk: a-kingdom-above-the-clouds-how-far-can-you-go-on-aws-for-1 python_level: advanced topic_level: advanced - topic: "Serverless development" - location: "Sala d'actes Ada Lovelace" requirements: "AWS Account" - - speaker: "" - title: "" - description: "" - start_time_slot: 14:00 - end_time_slot: 15:15 + - start: "14:00" track_length: 1 - color: grey type: workshop - language: "" - python_level: "" - topic_level: "" - requirements: "" - topic: "" - location: "" - - speaker: "Raúl Cumplido" - title: "A deep dive into the Arrow Columnar format with pyarrow and nanoarrow" - description: "Apache Arrow has become a de-facto standard for efficient in-memory columnar data representation. You might have heard about Arrow or using Arrow, but do you understand the format and why it’s so useful? This workshop will dive deep into the details of the Arrow columnar format, the different types and buffer layouts, and explore those details interactively using the pyarrow and nanoarrow libraries." - start_time_slot: 14:00 - end_time_slot: 15:15 + duration_minutes: 75 + - start: "14:00" track_length: 1 - color: blue - type: workshop - language: "English" + room: sala-margarita-salas + talk: a-deep-dive-into-the-arrow-columnar-format-with-pyarrow-and python_level: intermediate topic_level: intermediate - topic: "Apache Arrow, Data Science" requirements: "You will be able to find both the requirements and the Notebooks on the following repository: https://github.com/raulcd/2024-pyday-bcn-arrow-workshop" - location: "Sala Margarita Salas" - - - start_time_slot: 15:30 - end_time_slot: 15:30 + - start: "15:30" track_length: 4 - color: orange - title: "Coffee break" + room: grades type: coffee - location: Grades - class: middle - - - start_time_slot: 15:45 - end_time_slot: 15:45 + label: "Coffee break" + duration_minutes: 0 + - start: "15:45" track_length: 4 - color: purple - title: "Lightning talks" - type: talk - location: Aula Hedy Lamarr - class: middle - description: " -<h2>Lightning talks</h2> - -<b>Polars: Procesando datos a la velocidad de la luz con recursos espartanos</b><br> -<i>Fernando Aparicio</i> -<p><q>Pandas y Spark son las herramientas más conocidas para gestionar nuestros sets de datos, pero hay un jugador nuevo que quiere cambiar las reglas.Polars está pensado para el rendimiento y la resiliencia en entornos con pocos recursos. Cada megabyte y cada segundo cuenta. Os explicaré qué lo hace diferente al resto y qué es capaz de hacer.</q></p> - -<b>Evita bugs amb Pre-Commit</b><br> -<i>Carles Julià</i> -<p><q>How we improve code quality in our company for Python: pre-commit, ruff-format, ruff, mypy, etc</q></p> -" - - - speaker: "Manuel Gijón" - title: "Automate end to end MLflow with Kestra and MLFlow" - description: "During this session we are going to create a whole ML pipeline, from gathering and prepare the data to train different models and perform inference. We will use a Kaggle competition as our use case. We will learn the basics of Kestra, an orchestration platform, and MLFlow, a tool for keeping track of all processes relative to the full lifecycle for machine learning projects. We are going to use these tools to download a dataset from Kaggle, analyse it, process it, train different models by using different algorithms, perform inference on submission samples, and automatically upload the results back to Kaggle." - start_time_slot: 16:00 - end_time_slot: 17:15 + room: aula-hedy-lamarr + talk: lightning-talks-1545 + - start: "16:00" track_length: 1 - color: blue - type: workshop - language: "English" + room: sala-dactes-ada-lovelace + talk: automate-end-to-end-mlflow-with-kestra-and-mlflow python_level: beginner topic_level: beginner - topic: "Data engineering" - location: "Sala d'actes Ada Lovelace" requirements: "Docker, Conda" - - speaker: "Dave Pitts" - title: "Open Source Databases Python Devs" - description: "Are you interested in exploring open-source databases? Maybe you have experience with MySQL or PostgreSQL? Perhaps you are unsure which one to pick for your next project, then this workshop is for you. Both are highly successful open-source projects, with many similarities but also some notable differences. I'll also touch on some techniques for optimizing database queries." - start_time_slot: 16:00 - end_time_slot: 17:15 + - start: "16:00" track_length: 1 - color: yellow - type: workshop - language: "English" + room: aula-hipatia-dalexandria + talk: open-source-databases-python-devs python_level: intermediate topic_level: beginner requirements: "Postgres and MySQL installed locally or via Docker" - topic: "Databases" - location: "Aula Hipàtia d'Alexandria" - - speaker: "Jimena" - title: "L'Embolic: Videojuegos hechos en el frontend por un lenguaje de backend" - description: "¿Te gustan los videojuegos? Entonces, seguro sabes que, desde hace años, los juegos diseñados para ejecutarse en el navegador son bastante populares, tanto por la facilidad de desarrollo como por su versatilidad, al poder jugarlos independientemente del sistema operativo. - ¿Y si te digo que ya no es necesario dominar todos los entresijos del desarrollo frontend para poder crearlos? Hoy en día, podrías programarlos con tus conocimientos de Python. - PyScript es un framework que permite crear aplicaciones que se ejecutan en el navegador y, con un poco de práctica, ¡incluso podemos desarrollar juegos! Pásate por este taller y te enseñaré cómo hacerlo." - start_time_slot: 16:00 - end_time_slot: 17:15 + - start: "16:00" track_length: 1 - color: yellow - type: workshop - language: "Spanish" - title_lang: Spanish + room: aula-hedy-lamarr + talk: lembolic-videojuegos-hechos-en-el-frontend-por-un-lenguaje python_level: intermediate topic_level: beginner - topic: "Web development, Videogames" - location: "Aula Hedy Lamarr" - - speaker: "Asia Noble" - title: "Predict gender equality with your own Machine Learning model" - description: "In this session, you will use Python and Pandas to analyze how gender equality (or inequality) reveals itself through data.<br> - What you’ll learn:<br> - <br>✅ The logic and foundations behind Machine Learning - <br>✅ The different use cases of Machine Learning - <br>✅ How to predict the gender pay gap" - start_time_slot: 16:00 - end_time_slot: 17:15 + - start: "16:00" track_length: 1 - color: red - type: workshop - language: "English" + room: sala-margarita-salas + talk: predict-gender-equality-with-your-own-machine-learning-model python_level: beginner topic_level: beginner - topic: "Data science" - location: "Sala Margarita Salas" requirements: "Data Science techstack: PowerBI, Python, Scikit Learn, Tensorflow. Background n the creative tech industry, management, consulting, and operations." - - start_time_slot: 17:30 - end_time_slot: 17:30 + - start: "17:30" track_length: 4 - color: purple - title: "Lightning talks" - type: talk - location: Sala d'actes Ada Lovelace - class: middle - description: " -<h2>Lightning talks</h2> - -<b>La iniciativa Scientific Python</b><br> -<i>Oriol Abril Pla</i> -<p><q>Fa uns anys es va engegar la iniciativa Scientific Python, amb l'objectiu d'enfortir la col·laboració entre llibreries de Python en el camp de la computació científica. En els 5 minuts intentaré explicar què és i algunes de les seves iniciatives principals, que van des de gestió de dependències a consells d'accessibilitat passant per traduccions, 'nightly builds' o governança.</q></p> - -<b>DrugScope: a ML-based platform for drug discovery</b><br> -<i>Verónica Larroy</i> -<p><q>DrugScope is a machine learning-powered tool designed to predict the binding affinity of small molecules to specific proteins, aiming to accelerate drug discovery and reduce costs. Using Graph Neural Networks (GNNs), the project models molecular structures as graphs, with atoms as nodes and bonds as edges. A public dataset from Leash Biosciences, containing around 300 million molecules and their interactions with three key proteins (HSA, BRD4, and SEH), was used for model training. -<br><br> -The project involved developing three separate GNN models, one for each protein, to capture the unique molecular interactions relevant to each target. Features for atoms and bonds were extracted using RDKit, and the data was prepared for training by converting these features into graph structures. The models were deployed using FastAPI, allowing researchers to input molecule data and receive predictions on binding affinity, potentially helping speed up the early stages of drug development.</q></p> - -<b>Can LLMs Power Product Recommendations?</b><br> -<i>Babaniyi Olaniyi</i> -<p><q>I will discuss the use of large language models (LLMs) for product recommendation systems, leveraging their natural language understanding capabilities to predict items a user might purchase given their historical product reviews and purchases.</q></p> - -<b>Pixel2Mechanics: Automated Biomechanical Simulations of High-Resolution Intervertebral Discs from Anisotropic MRIs</b><br> -<i>Sai Natarajan</i> -<p><q>This study presents Pixel2Mechanics, an automated pipeline for generating patient-specific biomechanical finite element (FE) models of lumbar intervertebral discs (IVD) from clinical MRI data. It utilizes a deep learning framework to create high-resolution meshes of the Annulus Fibrosus (AF) and Nucleus Pulposus (NP) across L1-L2 to L4-L5. The pipeline features a novel optimization method based on differentiable rendering and a Bayesian Coherent Point Drift++ morphing algorithm for volumetric FE meshes that maintain tissue topology. Load simulations validate the models against manual segmentation, demonstrating potential for clinical integration in diagnosing and treating IVD degeneration.</q></p> -" - - - start_time_slot: 17:45 - end_time_slot: 17:45 + room: sala-dactes-ada-lovelace + talk: lightning-talks-1730 + - start: "17:45" track_length: 4 - color: purple - title: "Closing session & Kahoot" - description: "" + room: sala-dactes-ada-lovelace type: group - location: Sala d'actes Ada Lovelace - class: middle + label: "Closing session & Kahoot" + duration_minutes: 0 + --- @@ -527,7 +424,7 @@ The project involved developing three separate GNN models, one for each protein, We are excited to announce the **8th edition** of PyDay in Barcelona! -PyDay is an event packed with FREE **python-related workshops** and activities for the Python community. It is organized once per year. Over the [last seven editions](#previous_editions_section), PyDay has become a fantastic opportunity to share our love for Python and engage users, companies, and newcomers! +PyDay is an event packed with FREE **python-related workshops** and activities for the Python community. It is organized once per year. Over the last seven editions, PyDay has become a fantastic opportunity to share our love for Python and engage users, companies, and newcomers! ### When and where diff --git a/content/events/pyday_bcn/pyday_bcn_2025.md b/content/events/pyday_bcn/pyday_bcn_2025.md index e0dc33d1b..c44e58898 100644 --- a/content/events/pyday_bcn/pyday_bcn_2025.md +++ b/content/events/pyday_bcn/pyday_bcn_2025.md @@ -1,6 +1,11 @@ --- title: "PyDay BCN (2025)" year: 2025 +# The day of this edition. It is not in the Meetup export: the registration +# of 2025 ran on Eventbrite. +date: 2025-11-29 +# The venue of this edition, from the room names and the hero image of this page: this edition sold tickets on Eventbrite and was never a Meetup event. +venue: "Canòdrom" description: "For the community, by the community!" menu: main: @@ -25,7 +30,6 @@ free_text_sections: id: registration content: "General registration will open on Tuesday 25th of November, at 9AM through <a target='_blank' href='https://www.eventbrite.es/e/pyday-2025-tickets-1924233868299?aff=oddtdtcreator'>Eventbrite</a>." -sponsors_text: "Would you like to sponsor this event? Please contact us at pyday2025@googlegroups.com<br/><br/>" sponsor_levels: - sponsors_per_line: 2 sponsors: [okta, rover, pythones, preply] @@ -95,64 +99,46 @@ people_sections: # - gaby # - Camilo -previous_editions: - - name: PyDay BCN 2024 - url: /events/pyday_bcn/pyday_bcn_2024/ - - name: PyDay BCN 2023 - url: /events/pyday_bcn/pyday_bcn_2023/ - - name: PyDay BCN 2022 - url: /events/pyday_bcn/pyday_bcn_2022/ - - name: PyDay BCN 2021 - url: /events/pyday_bcn/pyday_bcn_2021/ - - name: PyDay BCN 2020 - url: /events/pyday_bcn/pyday_bcn_2020/ - - name: PyDay BCN 2019 - url: /events/pyday_bcn/pyday_bcn_2019/ - - name: PyDay BCN 2018 - url: /events/pyday_bcn/pyday_bcn_2018/ - - name: PyDay BCN 2016 - url: /events/pyday_bcn/pyday_bcn_2016/ - spansDuration: 15 numTracks: 4 eventTimes: [ - 9:00, - 9:15, - 9:30, - 9:45, - 10:00, - 10:15, - 10:30, - 10:45, - 11:00, - 11:15, - 11:30, - 11:45, - 12:00, - 12:15, - 12:30, - 12:45, - 13:00, - 13:15, - 13:30, - 13:45, - 14:00, - 14:15, - 14:30, - 14:45, - 15:00, - 15:15, - 15:30, - 15:45, - 16:00, - 16:15, - 16:30, - 16:45, - 17:00, - 17:15, - 17:30, - 17:45, + "9:00", + "9:15", + "9:30", + "9:45", + "10:00", + "10:15", + "10:30", + "10:45", + "11:00", + "11:15", + "11:30", + "11:45", + "12:00", + "12:15", + "12:30", + "12:45", + "13:00", + "13:15", + "13:30", + "13:45", + "14:00", + "14:15", + "14:30", + "14:45", + "15:00", + "15:15", + "15:30", + "15:45", + "16:00", + "16:15", + "16:30", + "16:45", + "17:00", + "17:15", + "17:30", + "17:45", ] legend: - type: workshop @@ -161,399 +147,383 @@ legend: - level: beginner - level: intermediate - level: advanced -events: - - start_time_slot: 9:00 - end_time_slot: 9:15 - track_length: 4 - color: purple - title: "Registration & Welcome" - speaker: "PyDay BCN 2025 Organising Committee" - type: group - location: "Sala d'actes Ada Lovelace" - class: middle - - speaker: "Enric Domingo" +# The rooms of this edition, in the order the grid first names them. A room is +# a record with an id because the colour of a block now comes from it: the +# template gives every room of an event one colour of the agenda palette and +# keeps it for the whole day. See partials/agenda_entry.html. +rooms: + - id: sala-dactes-ada-lovelace + name: "Sala d'actes Ada Lovelace" + - id: sala-margarita-salas + name: "Sala Margarita Salas" + - id: sala-hedy-lamarr + name: "Sala Hedy Lamarr" + - id: sala-hipatia-dalexandria + name: "Sala Hipàtia d'Alexandria" + - id: terrassa + name: "Terrassa" + - id: grades + name: "Grades" + - id: claustre + name: "Claustre" + +# The talks of this edition: what was said, by whom, in which language. A talk +# carries no time and no room, because it is the content and not the slot. +# agenda below is what places it on the grid, and one talk can take more than +# one slot. The id is derived from the title and is the anchor a photo of the +# gallery links to, so it must not change. +talks: + - id: build-advanced-agentic-llm-apps-with-langgraph-and-langchain title: "Build advanced Agentic LLM Apps with LangGraph and LangChain" + speakers: [enric-domingo] + type: workshop + language: en + topic: "LLM" + duration_minutes: 75 description: "In this workshop we will learn how to build useful LLM agentic workflows in Python using LangChain and LangGraph, open source libraries and the most popular and powerful tools for advanced AI Engineering projects. They are capable of solving complex tasks, doing multiple LLM calls, using memory, structured outputs, popular tools, custom tools and even being able to introduce human-in-the-loop interactions when needed." - start_time_slot: 9:30 - end_time_slot: 10:45 - track_length: 1 - color: blue + links: + - type: github + url: "https://github.com/enricd/langgraph_agents_pyday_bcn" + - id: from-zero-to-chatbot-create-your-own-ai-assistant-with + title: "From Zero to Chatbot: Create Your Own AI Assistant with Python" + speakers: [ester-jara] + type: workshop + language: es + topic: "Artificial Intelligence (IA)" + duration_minutes: 75 + description: "The development of a local AI chatbot using Python is explored step by step. It begins with setting up the environment and loading a compact open-source language model, then guides through creating a structured interaction loop to process input and generate responses. Prompts are designed, conversational context is managed with a rolling history, and a lightweight memory component is added to maintain coherent multi-turn interactions. A short introduction to agentic behaviour illustrates how simple decision-making and task handling can make a chatbot more autonomous. By the end, a fully functional chatbot is built, with a clear understanding of its main components and how they work together." + links: + - type: github + url: "https://github.com/esterjara/ai-chatbot-workshop" + - id: introduction-to-analog-quantum-computing + title: "Introduction to Analog Quantum Computing" + speakers: [natalia-padilla, amir-azam, david-arcos, javier-sabariego, ely-farres-palomeras, flavie-le-bars] type: workshop - language: "English" + language: en + topic: "Quantum Computing" + duration_minutes: 75 + description: "Participants will learn how to design and simulate an analog quantum algorithm using QiliSDK, directly from their laptops.\nQiliSDK is a Python framework for writing digital and analog quantum algorithms and executing them across multiple quantum backends. Its modular design streamlines the development process and enables easy integration with a variety of quantum platforms." + links: + - type: slides + label: "Presentation" + url: "https://docs.google.com/presentation/d/1QHQHSbCnpdEJj2BLAFIFk0M0lbjLM6StTgbNojUBcQk/edit" + - type: notebooks + label: "Workshop Notebooks" + url: "https://drive.google.com/drive/folders/18ds2Onl0hqW3NMJ7FpgErkaRtYvslrHK" + - id: testeando-apis-like-a-boss-con-bdd + title: "Testeando API's like a boss con BDD" + title_lang: Spanish + speakers: [javier-ramos-panduro] + type: workshop + language: es + topic: "Testing" + duration_minutes: 75 + description: "Un repaso de como realizar test e2e de nuestras API's utilizando pytest y bdd" + links: + - type: github + url: "https://github.com/breadhardIT/pytest-pybdd" + - id: del-texto-al-dato-como-entienden-las-maquinas-el-lenguaje + title: "Del texto al dato: cómo entienden las maquinas el lenguaje humano con Python" + title_lang: Spanish + speakers: [cristina-cosma] + type: workshop + language: es + topic: "Data science, Natural Language Process, Data Visualization" + duration_minutes: 75 + description: "Exploraremos como los ordenadores pueden analizar el lenguaje natural humano, transformarlo en datos y extraer información valiosa a partir de palabras. Aplicaremos técnicas básicas de NLP (procesamiento de lenguaje natural) como el procesamiento de palabras, el análisis de sentimientos, de las intensidades y frecuencias. Visualizaremos y compararemos los resultados para comprender cómo los algoritmos interpretan el tono y el contenido de lo que los humanos expresamos." + links: + - type: github + url: "https://github.com/cristinasprogrammingadventure/PyDay-2025_workshop-Del-Texto-al-Dato_NLP" + - id: crea-un-agente-llm-desde-cero-sin-frameworks + title: "Crea un agente LLM desde cero, sin frameworks." + title_lang: Spanish + speakers: [ricardo-ander-egg-aguilar] + type: workshop + language: [en, es] + topic: "LLM" + duration_minutes: 75 + description: "En este taller vamos a desmitificar los agentes LLM y a construir uno desde cero, sin usar frameworks. Entenderás la lógica fundamental que permite a un modelo de lenguaje razonar y usar herramientas externas, programándolo todo con Python y la librería oficial de OpenAI.\nTrabajaremos de forma 100% práctica para implementar el bucle de control que convierte a un LLM en un agente autónomo: recibir un objetivo, pensar qué herramienta usar, ejecutarla y decidir el siguiente paso. El objetivo es que comprendas el mecanismo interno de un agente.\nAl finalizar, serás capaz de:\n- Entender la arquitectura básica de un agente LLM (razonamiento + acción).\n- Implementar un bucle de control para que el LLM pueda usar herramientas.\n- Permitir al modelo ejecutar funciones de Python." + links: + - type: github + url: "https://github.com/polyrand/pyday2025-llm" + - id: building-multi-agent-system-with-pydantic-ai + title: "Building Multi-Agent System with Pydantic AI" + speakers: [alberto-camara] + type: workshop + language: en + topic: "Data Science" + duration_minutes: 75 + description: "A hands-on workshop teaching multi-agent system design using Pydantic AI to analyze arXiv papers. Participants will build cooperating agents that extract citations, analyze context, and link claims to evidence-demonstrating agent orchestration, validation patterns, and structured outputs." + links: + - type: github + url: "https://github.com/ber2/2025-pyday-multiagents-pydantic-ai" + - id: mastering-word-automation-with-python + title: "Mastering Word Automation with Python" + speakers: [jordi-bosch] + type: workshop + language: es + topic: "Artificial Intelligence" + duration_minutes: 75 + description: "Tired of editing Word documents manually and breaking templates by mistake? Join the automation revolution as we see how Python can manage bookmarks, placeholders and structured templates inside .docx files. We'll discover how to populate fields, update content programmatically and generate consistent documents with just a few lines of code. By the end, you'll be creating automated Word files smoothly, saving time and reducing errors in your everyday workflows. Get ready to upgrade your document-handling skills!" + links: + - type: github + url: "https://github.com/jordiba90/PyBcn-PyDay-2024.11.29-Docx" + - id: keywords-bm25-y-vectores-construyendo-un-buscador-de-texto + title: "Keywords, BM25 y vectores: construyendo un buscador de texto desde cero" + title_lang: Spanish + speakers: [ricardo-ander-egg-aguilar] + type: workshop + language: [en, es] + topic: "LLM" + duration_minutes: 75 + description: "En este taller aprenderemos cómo funcionan de verdad los buscadores de texto, más allá de las cajas negras de las librerías. Partiremos de los conceptos más básicos (índices, tokens, ranking) y llegaremos hasta técnicas modernas como BM25 y búsqueda vectorial, implementándolo todo a mano desde cero.\nTrabajaremos de forma totalmente práctica: construirás tu propio mini-buscador, primero basado en keywords y \"scoring\" clásico, y después lo extenderemos con métodos más avanzados y representación vectorial. El objetivo del taller es entender los principios básicos que hay detrás de los motores de búsqueda y cómo se implementan.\nAl finalizar, serás capaz de:\n- Implementar un índice invertido simple y un buscador basado en keywords.\n- Entender y programar un sistema de ranking con TF-IDF / BM25.\n- Utilizar vectores y similitud de coseno para búsqueda semántica básica.\n- Comparar enfoques y saber cuándo usar palabras clave, BM25 o vectores." + links: + - type: github + url: "https://github.com/polyrand/pyday2025-text" + - id: del-desorden-visual-al-significado-una-aventura-con + title: "Del Desorden Visual al Significado: Una Aventura con Transformers y Donut" + title_lang: Spanish + speakers: [kevin-sanchez-sancho] + type: workshop + language: ca + topic: "Computer vision" + duration_minutes: 75 + description: "En este workshop práctico de 90 minutos exploraremos cómo los modelos basados en Transformers han revolucionado el campo de la visión por computadora, superando arquitecturas clásicas como CNNs en tareas de clasificación, detección y segmentación. A través de un caso de estudio original, aprenderás a:\n- Preparar un dataset para visión por computadora.\n- Implementar un pipeline completo usando Python, PyTorch, HuggingFace y Ollama.\n- Aplicar un Vision Transformer (ViT) y/o modelos híbridos como DETR.\n- Evaluar resultados y visualizar predicciones con herramientas modernas.\n- Comprender cómo extender el pipeline a casos reales de negocio.\nEl enfoque será 100% práctico, con código reproducible y materiales descargables para que puedas continuar experimentando después del taller." + links: + - type: github + url: "https://github.com/kevinSanchez21/pyday_2025_vision_transformers" + - id: house-controlled-by-ai-what-could-go-wrong + title: "House, Controlled by AI (What Could Go Wrong?)" + speakers: [kemalcan-bora] + type: workshop + language: en + topic: "Agent IA" + duration_minutes: 75 + description: "This project demonstrates how agentic AI can enable autonomous decision-making and natural-language interaction in smart home systems. By integrating an ESP32 microcontroller with basic sensors (e.g., temperature, motion, or object detection), we show how an AI agent can perceive environmental data, reason about it, and act on user instructions or contextual conditions.\nFor example, the agent can:\n- Adjust the air conditioner temperature to 30°C based on voice or text commands. - Query fridge inventory data (e.g., count remaining eggs). - Detect home occupancy using motion or door sensors." + links: + - type: github + url: "https://github.com/kemalcanbora/pybcn2025" + - id: models-de-regressio-bayesians + title: "Models de regressió bayesians" + title_lang: Catalan + speakers: [oriol-abril-pla] + type: workshop + language: ca + topic: "Statistics and Data Science" + duration_minutes: 75 + description: "En aquesta xerrada explorarem els models lineals generalitzats (GLMs) dins del paradigma Bayesià a través de la llibreria bambi. Introduirem els GLMs i els seus tres components principals: el predictor lineal, la distribució observacional i la funció d'enllaç. Després veurem el paper que hi juguen les distribucions a priori per als paràmetres del model i com utilitzar-los per a ampliar els GLMs incorporant-hi jerarquia. Tot això ho farem utilitzant la llibreria bambi, una llibreria comunitària de programari lliure que permet definir GLMs a través d'una sintaxis amb fórmules i fer inferència a través de PyMC o NumPyro." + links: + - type: github + url: "https://github.com/OriolAbril/pyday2025-bambi" + - id: agentes-inteligentes-que-evolucionan-software + title: "Agentes Inteligentes que Evolucionan: Software Automodificable con LLMs y Python" + title_lang: Spanish + speakers: [camilo-chacon-sartori] + type: workshop + language: es + topic: "IA Generativa" + duration_minutes: 75 + description: "En este workshop exploraremos cómo construir software automodificable utilizando agentes basados en LLMs, con implementaciones prácticas en Python. Partiremos de los fundamentos de agentes autónomos y LLMs, para mostrar cómo estos sistemas pueden autoevaluarse, reescribirse y adaptarse a nuevas tareas de manera autónoma. La sesión tendrá un énfasis práctico, aprovechando mi experiencia en la integración de la computación evolutiva y LLMs, para que los participantes adquieran herramientas concretas para experimentar con software autoevolutivo." + links: + - type: github + url: "https://github.com/camilochs/pydaybcn2025-workshop-code-evolution" + - id: fabric-en-accion-conectando-bloques-datos-y-magia-en-python + title: "Fabric en Acción: conectando bloques, datos y magia en python" + title_lang: Spanish + speakers: [victor-garcia-dominguez] + type: workshop + language: en + duration_minutes: 75 + description: "En este workshop práctico de 90 minutos exploraremos Fabric, una poderosa herramienta que permite automatizar tareas, orquestar flujos de trabajo y construir pipelines reproducibles en Python. A través de ejemplos concretos aprenderás cómo combinar bloques de código, manejar datos y desplegar procesos complejos de forma elegante y extensible.\nDurante la sesión veremos desde los fundamentos de Fabric hasta casos de uso reales: automatización de tareas repetitivas, integración con servicios externos, ejecución remota y creación de scripts que convierten procesos largos y manuales en flujos automatizados. Todo ello acompañado de demostraciones paso a paso para que puedas aplicar lo aprendido inmediatamente en tus propios proyectos.\nSi buscas potenciar tus habilidades para crear herramientas internas, pipelines de datos o automatizar el día a día con Python, este workshop es para ti. ¡Ven a descubrir cómo Fabric puede convertir tus scripts en auténtica magia productiva!" + links: + - type: github + url: "https://github.com/ramitjans/pyDay25_fabrik_with_python" + - id: htmx-a-love-story-between-a-backend-dev-and-a-frontend + title: "HTMX: A love story between a backend dev and a frontend \"framework\"" + speakers: [eric-massip] + type: workshop + language: en + topic: "Web development" + duration_minutes: 75 + description: "HTMX brings modern interactivity to the web without the complexity of a full frontend framework. In this workshop, we'll dig into how HTMX works while staying in the comfort of Django's views and templates. We'll explore how hypermedia can simplify frontend development and bring back clarity to the client-server relationship. We'll then put it all into practice by building a small hypermedia-driven web app that feels reactive and dynamic." + links: + - type: github + url: "https://github.com/ericmassip/carbon-home-watcher" + - id: causal-inference-a-brief-introduction + title: "Causal Inference: a brief introduction" + speakers: [ubaldo-hervas] + type: workshop + language: en + topic: "Causal Inference & Data Science" + duration_minutes: 75 + description: "Discover how causal inference separates correlation from causation to drive better decisions. This fast-paced introduction covers key concepts-treatments, counterfactuals, DAGs, confounding, experiments vs. observational data-and practical tools like A/B tests, DiD, and IVs. Learn design principles, common pitfalls, and how to frame questions that unlock credible, actionable insights at scale." + links: + - type: github + label: "Github" + url: "https://github.com/UbaldoHervas/PyDay-BCN-2025" + - type: link + label: "Leanalytics" + url: "https://leanalytics.substack.com/p/022-caso-practico-diferencia-en-diferencias-datos-sinteticos" + - id: lightning-talks-closing-session-kahoot + title: "Lightning talks + closing session & Kahoot" + type: talk + duration_minutes: 15 + description: "Lighting talks:\n<br> <b> Kevin Albes </b>: Building Multi-Agent Workflows with Agent Framework<br> <br> <b> Brian Power </b>: Five python code samples I show clients who know nothing about Python. And to those who know too much.<br>" + +# The grid, one row per slot of the day, in the order it is printed. A slot +# names the talk it holds, or carries its own label and type when it holds +# none: a break, the group photo, the welcome. The level and the requirements +# sit here and not on the talk, because they are what the slot asks of whoever +# walks into it. A start is always quoted: YAML 1.1 reads an unquoted 9:00 as +# the integer 540. +agenda: + - start: "9:00" + credited_as: "PyDay BCN 2025 Organising Committee" + track_length: 4 + room: sala-dactes-ada-lovelace + type: group + label: "Registration & Welcome" + duration_minutes: 15 + - start: "9:30" + track_length: 1 + room: sala-dactes-ada-lovelace + talk: build-advanced-agentic-llm-apps-with-langgraph-and-langchain python_level: intermediate topic_level: beginner requirements: "Intermediate experience in Python and basic understanding of LLMs and how to use LLM APIs" - topic: "LLM" - location: "Sala d'actes Ada Lovelace" - repositories: "https://github.com/enricd/langgraph_agents_pyday_bcn " - - - speaker: "Ester Jara" - title: "From Zero to Chatbot: Create Your Own AI Assistant with Python" - description: "The development of a local AI chatbot using Python is explored step by step. It begins with setting up the environment and loading a compact open-source language model, then guides through creating a structured interaction loop to process input and generate responses. Prompts are designed, conversational context is managed with a rolling history, and a lightweight memory component is added to maintain coherent multi-turn interactions. A short introduction to agentic behaviour illustrates how simple decision-making and task handling can make a chatbot more autonomous. By the end, a fully functional chatbot is built, with a clear understanding of its main components and how they work together." - start_time_slot: 9:30 - end_time_slot: 10:45 + - start: "9:30" track_length: 1 - color: yellow - type: workshop - language: "Spanish" + room: sala-margarita-salas + talk: from-zero-to-chatbot-create-your-own-ai-assistant-with python_level: intermediate topic_level: beginner - requirements: " - - No prior experience with AI or machine learning - - Basic familiarity with Python (variables, functions, running scripts) - - Laptop with Python 3.9+ installed - - Ability to install Python packages (pip) - - Code editor such as VS Code" - topic: "Artificial Intelligence (IA)" - location: "Sala Margarita Salas" - repositories: "https://github.com/esterjara/ai-chatbot-workshop" - - - speaker: "Natàlia Padilla, Amir Azam, David Arcos, Javier Sabariego, Ely Farrés & Flavie Le Bars" - title: "Introduction to Analog Quantum Computing" - description: "Participants will learn how to design and simulate an analog quantum algorithm using QiliSDK, directly from their laptops. - - QiliSDK is a Python framework for writing digital and analog quantum algorithms and executing them across multiple quantum backends. Its modular design streamlines the development process and enables easy integration with a variety of quantum platforms." - start_time_slot: 9:30 - end_time_slot: 10:45 + requirements: "- No prior experience with AI or machine learning - Basic familiarity with Python (variables, functions, running scripts) - Laptop with Python 3.9+ installed - Ability to install Python packages (pip) - Code editor such as VS Code" + - start: "9:30" track_length: 1 - color: red - type: workshop - language: "English" + room: sala-hedy-lamarr + talk: introduction-to-analog-quantum-computing python_level: beginner topic_level: beginner requirements: "pip install qilisdk" - topic: "Quantum Computing" - location: "Sala Hedy Lamarr" - repositories: " - <br> <b> Presentation </b>: https://docs.google.com/presentation/d/1QHQHSbCnpdEJj2BLAFIFk0M0lbjLM6StTgbNojUBcQk/edit<br> - <br> <b> Workshop Notebooks </b>: https://drive.google.com/drive/folders/18ds2Onl0hqW3NMJ7FpgErkaRtYvslrHK<br>" - - - speaker: "Javier Ramos Panduro" - title: "Testeando API's like a boss con BDD" - description: "Un repaso de como realizar test e2e de nuestras API's utilizando pytest y bdd" - start_time_slot: 9:30 - end_time_slot: 10:45 + - start: "9:30" track_length: 1 - color: orange - type: workshop - language: "Spanish" - title_lang: Spanish + room: sala-hipatia-dalexandria + talk: testeando-apis-like-a-boss-con-bdd python_level: intermediate topic_level: intermediate requirements: "Python environment y IDE" - topic: "Testing" - location: "Sala Hipàtia d'Alexandria" - repositories: "https://github.com/breadhardIT/pytest-pybdd" - - - start_time_slot: 11:00 - end_time_slot: 11:15 + - start: "11:00" track_length: 4 - color: purple - title: "Coffee break" + room: terrassa type: coffee - location: Terrassa - class: middle - - - speaker: "Cristina Cosma" - title: "Del texto al dato: cómo entienden las maquinas el lenguaje humano con Python " - description: "Exploraremos como los ordenadores pueden analizar el lenguaje natural humano, transformarlo en datos y extraer información valiosa a partir de palabras. Aplicaremos técnicas básicas de NLP (procesamiento de lenguaje natural) como el procesamiento de palabras, el análisis de sentimientos, de las intensidades y frecuencias. Visualizaremos y compararemos los resultados para comprender cómo los algoritmos interpretan el tono y el contenido de lo que los humanos expresamos." - start_time_slot: 11:30 - end_time_slot: 12:45 + label: "Coffee break" + duration_minutes: 15 + - start: "11:30" track_length: 1 - color: blue - type: workshop - language: "Spanish" - title_lang: Spanish + room: sala-dactes-ada-lovelace + talk: del-texto-al-dato-como-entienden-las-maquinas-el-lenguaje python_level: intermediate topic_level: beginner requirements: "Conexión a internet, cuenta de Google (para trabajar en Google Colab a través de librerías ya disponibles sin necesidad de usar consola de comandos (cmd) ni instalar Python en local." - topic: "Data science, Natural Language Process, Data Visualization" - location: "Sala d'actes Ada Lovelace" - repositories: "https://github.com/cristinasprogrammingadventure/PyDay-2025_workshop-Del-Texto-al-Dato_NLP" - - - speaker: "Ricardo Ander-Egg" - title: "Crea un agente LLM desde cero, sin frameworks." - description: "En este taller vamos a desmitificar los agentes LLM y a construir uno desde cero, sin usar frameworks. Entenderás la lógica fundamental que permite a un modelo de lenguaje razonar y usar herramientas externas, programándolo todo con Python y la librería oficial de OpenAI. - - Trabajaremos de forma 100% práctica para implementar el bucle de control que convierte a un LLM en un agente autónomo: recibir un objetivo, pensar qué herramienta usar, ejecutarla y decidir el siguiente paso. El objetivo es que comprendas el mecanismo interno de un agente. - - Al finalizar, serás capaz de: - - - Entender la arquitectura básica de un agente LLM (razonamiento + acción). - - - Implementar un bucle de control para que el LLM pueda usar herramientas. - - - Permitir al modelo ejecutar funciones de Python." - - start_time_slot: 11:30 - end_time_slot: 12:45 + - start: "11:30" track_length: 1 - color: yellow - type: workshop - language: "Spanish/English" - title_lang: Spanish + room: sala-margarita-salas + talk: crea-un-agente-llm-desde-cero-sin-frameworks python_level: beginner topic_level: beginner requirements: "Conexión a internet. Python 3.10+. Tener la librería \"openai\" instalada. No se necesitará una API key para el taller. Se recomienda usar un gestor de entornos como uv o virtualenv, aunque no es obligatorio. Cada participante debe tener su entorno listo. Durante el taller se utilizará \"uv\" para gestionar dependencias." - topic: "LLM" - location: "Sala Margarita Salas" - repositories: "https://github.com/polyrand/pyday2025-llm" - - - speaker: "Alberto Camara" - title: "Building Multi-Agent System with Pydantic AI" - description: "A hands-on workshop teaching multi-agent system design using Pydantic AI to analyze arXiv papers. Participants will build cooperating agents that extract citations, analyze context, and link claims to evidence—demonstrating agent orchestration, validation patterns, and structured outputs." - start_time_slot: 11:30 - end_time_slot: 12:45 + - start: "11:30" track_length: 1 - color: red - type: workshop - language: "English" + room: sala-hedy-lamarr + talk: building-multi-agent-system-with-pydantic-ai python_level: intermediate topic_level: intermediate - topic: "Data Science" - location: "Sala Hedy Lamarr" - requirements: "Participants should bring a laptop with: - - - Python 3.10+ installed - - - Ollama installed with Llama 3.2 model downloaded - - - Basic familiarity with Python - - - 8GB+ RAM recommended - - No prior experience with AI agents or Pydantic AI required." - repositories: "https://github.com/ber2/2025-pyday-multiagents-pydantic-ai" - - - speaker: "Jordi Bosch" - title: "Mastering Word Automation with Python" - description: "Tired of editing Word documents manually and breaking templates by mistake? Join the automation revolution as we see how Python can manage bookmarks, placeholders and structured templates inside .docx files. We’ll discover how to populate fields, update content programmatically and generate consistent documents with just a few lines of code. By the end, you’ll be creating automated Word files smoothly, saving time and reducing errors in your everyday workflows. Get ready to upgrade your document-handling skills!" - start_time_slot: 11:30 - end_time_slot: 12:45 + requirements: "Participants should bring a laptop with:\n- Python 3.10+ installed\n- Ollama installed with Llama 3.2 model downloaded\n- Basic familiarity with Python\n- 8GB+ RAM recommended\nNo prior experience with AI agents or Pydantic AI required." + - start: "11:30" track_length: 1 - color: orange - type: workshop - language: "Spanish" + room: sala-hipatia-dalexandria + talk: mastering-word-automation-with-python python_level: beginner topic_level: beginner requirements: "Python and DOCX" - topic: "Artificial Intelligence" - location: "Sala Hipàtia d'Alexandria" - repositories: "https://github.com/jordiba90/PyBcn-PyDay-2024.11.29-Docx" - - - start_time_slot: 13:00 - end_time_slot: 13:00 + - start: "13:00" track_length: 4 - color: pink - title: "Group photo" + room: grades type: photo - location: Grades - class: middle - - - start_time_slot: 13:15 - end_time_slot: 13:45 + label: "Group photo" + duration_minutes: 0 + - start: "13:15" track_length: 4 - color: purple - title: "Lunch break" + room: terrassa type: lunch - location: Terrassa - class: middle - - - speaker: "Ricardo Ander-Egg" - title: "Keywords, BM25 y vectores: construyendo un buscador de texto desde cero" - description: "En este taller aprenderemos cómo funcionan de verdad los buscadores de texto, más allá de las cajas negras de las librerías. Partiremos de los conceptos más básicos (índices, tokens, ranking) y llegaremos hasta técnicas modernas como BM25 y búsqueda vectorial, implementándolo todo a mano desde cero. - - Trabajaremos de forma totalmente práctica: construirás tu propio mini‑buscador, primero basado en keywords y \"scoring\" clásico, y después lo extenderemos con métodos más avanzados y representación vectorial. El objetivo del taller es entender los principios básicos que hay detrás de los motores de búsqueda y cómo se implementan. - - Al finalizar, serás capaz de: - - - Implementar un índice invertido simple y un buscador basado en keywords. - - - Entender y programar un sistema de ranking con TF‑IDF / BM25. - - - Utilizar vectores y similitud de coseno para búsqueda semántica básica. - - - Comparar enfoques y saber cuándo usar palabras clave, BM25 o vectores." - start_time_slot: 14:00 - end_time_slot: 15:15 + label: "Lunch break" + duration_minutes: 30 + - start: "14:00" track_length: 1 - color: blue - type: workshop - language: "Spanish/English" - title_lang: Spanish + room: sala-dactes-ada-lovelace + talk: keywords-bm25-y-vectores-construyendo-un-buscador-de-texto python_level: intermediate topic_level: beginner requirements: "Python 3.10+ (cada participante puede decidir seguir el taller con un Jupyter Notebook, Google Colab, scripts de Python, etc). El taller se desarrollará utilizando archivos de texto de Python, pero es apto para seguirlo en un notebook también." - topic: "LLM" - location: "Sala d'actes Ada Lovelace" - repositories: "https://github.com/polyrand/pyday2025-text" - - - - speaker: "Kevin Sanchez" - title: "Del Desorden Visual al Significado: Una Aventura con Transformers y Donut" - description: "En este workshop práctico de 90 minutos exploraremos cómo los modelos basados en Transformers han revolucionado el campo de la visión por computadora, superando arquitecturas clásicas como CNNs en tareas de clasificación, detección y segmentación. A través de un caso de estudio original, aprenderás a: - - - Preparar un dataset para visión por computadora. - - - Implementar un pipeline completo usando Python, PyTorch, HuggingFace y Ollama. - - - Aplicar un Vision Transformer (ViT) y/o modelos híbridos como DETR. - - - Evaluar resultados y visualizar predicciones con herramientas modernas. - - - Comprender cómo extender el pipeline a casos reales de negocio. - - El enfoque será 100% práctico, con código reproducible y materiales descargables para que puedas continuar experimentando después del taller." - start_time_slot: 14:00 - end_time_slot: 15:15 + - start: "14:00" track_length: 1 - color: yellow - type: workshop - language: "Catalan" - title_lang: Spanish + room: sala-margarita-salas + talk: del-desorden-visual-al-significado-una-aventura-con python_level: intermediate topic_level: intermediate - topic: "Computer vision" requirements: "Python" - location: "Sala Margarita Salas" - repositories: "https://github.com/kevinSanchez21/pyday_2025_vision_transformers" - - - speaker: "Kemalcan Bora" - title: "House, Controlled by AI (What Could Go Wrong?)" - description: "This project demonstrates how agentic AI can enable autonomous decision-making and natural-language interaction in smart home systems. By integrating an ESP32 microcontroller with basic sensors (e.g., temperature, motion, or object detection), we show how an AI agent can perceive environmental data, reason about it, and act on user instructions or contextual conditions. - - For example, the agent can: - - - Adjust the air conditioner temperature to 30°C based on voice or text commands. - - Query fridge inventory data (e.g., count remaining eggs). - - Detect home occupancy using motion or door sensors." - start_time_slot: 14:00 - end_time_slot: 15:15 + - start: "14:00" track_length: 1 - color: red - type: workshop - language: "English" + room: sala-hedy-lamarr + talk: house-controlled-by-ai-what-could-go-wrong python_level: advanced topic_level: advanced requirements: "python, transformers, llama-index" - topic: "Agent IA" - location: "Sala Hedy Lamarr" - repositories: "https://github.com/kemalcanbora/pybcn2025" - - - speaker: "Oriol Abril" - title: "Models de regressió bayesians" - description: "En aquesta xerrada explorarem els models lineals generalitzats (GLMs) dins del paradigma Bayesià a través de la llibreria bambi. Introduirem els GLMs i els seus tres components principals: el predictor lineal, la distribució observacional i la funció d’enllaç. Després veurem el paper que hi juguen les distribucions a priori per als paràmetres del model i com utilitzar-los per a ampliar els GLMs incorporant-hi jerarquia. Tot això ho farem utilitzant la llibreria bambi, una llibreria comunitària de programari lliure que permet definir GLMs a través d’una sintaxis amb fórmules i fer inferència a través de PyMC o NumPyro." - start_time_slot: 14:00 - end_time_slot: 15:15 + - start: "14:00" track_length: 1 - color: orange - type: workshop - language: "Catalan" - title_lang: Catalan + room: sala-hipatia-dalexandria + talk: models-de-regressio-bayesians python_level: intermediate topic_level: beginner requirements: "Utilitzarem la última versió de la llibreria bambi durant el taller. Es recomana tenir un virtual environment amb la llibreria ja instal·lada si es vol seguir el taller en directe. El taller també assumeix un nivell intermedi en l'ús de NumPy i Pandas." - topic: "Statistics and Data Science" - location: "Sala Hipàtia d'Alexandria" - repositories: "https://github.com/OriolAbril/pyday2025-bambi" - - - start_time_slot: 15:30 - end_time_slot: 15:45 + - start: "15:30" track_length: 4 - color: purple - title: "Coffee break" + room: claustre type: coffee - location: Claustre - class: middle - - - speaker: "Camilo Chacón Sartori" - title: "Agentes Inteligentes que Evolucionan: Software Automodificable con LLMs y Python" - description: "En este workshop exploraremos cómo construir software automodificable utilizando agentes basados en LLMs, con implementaciones prácticas en Python. Partiremos de los fundamentos de agentes autónomos y LLMs, para mostrar cómo estos sistemas pueden autoevaluarse, reescribirse y adaptarse a nuevas tareas de manera autónoma. La sesión tendrá un énfasis práctico, aprovechando mi experiencia en la integración de la computación evolutiva y LLMs, para que los participantes adquieran herramientas concretas para experimentar con software autoevolutivo." - start_time_slot: 16:00 - end_time_slot: 17:15 + label: "Coffee break" + duration_minutes: 15 + - start: "16:00" track_length: 1 - color: blue - type: workshop - language: "Spanish" - title_lang: Spanish + room: sala-dactes-ada-lovelace + talk: agentes-inteligentes-que-evolucionan-software python_level: intermediate topic_level: beginner requirements: "Portátil y acceso a internet, para poder clonar el repositorio y seguir las instrucciones." - topic: "IA Generativa" - location: "Sala d'actes Ada Lovelace" - repositories: "https://github.com/camilochs/pydaybcn2025-workshop-code-evolution" - - - speaker: "Victor Garcia" - title: "Fabric en Acción: conectando bloques, datos y magia en python" - description: "En este workshop práctico de 90 minutos exploraremos Fabric, una poderosa herramienta que permite automatizar tareas, orquestar flujos de trabajo y construir pipelines reproducibles en Python. A través de ejemplos concretos aprenderás cómo combinar bloques de código, manejar datos y desplegar procesos complejos de forma elegante y extensible. - - Durante la sesión veremos desde los fundamentos de Fabric hasta casos de uso reales: automatización de tareas repetitivas, integración con servicios externos, ejecución remota y creación de scripts que convierten procesos largos y manuales en flujos automatizados. Todo ello acompañado de demostraciones paso a paso para que puedas aplicar lo aprendido inmediatamente en tus propios proyectos. - - Si buscas potenciar tus habilidades para crear herramientas internas, pipelines de datos o automatizar el día a día con Python, este workshop es para ti. ¡Ven a descubrir cómo Fabric puede convertir tus scripts en auténtica magia productiva!" - start_time_slot: 16:00 - end_time_slot: 17:15 + - start: "16:00" track_length: 1 - color: yellow - type: workshop - language: "English" - title_lang: Spanish + room: sala-margarita-salas + talk: fabric-en-accion-conectando-bloques-datos-y-magia-en-python python_level: beginner topic_level: beginner - requirements: "" - topic: "" - location: "Sala Margarita Salas" - repositories: "https://github.com/ramitjans/pyDay25_fabrik_with_python" - - - speaker: "Eric Massip" - title: "HTMX: A love story between a backend dev and a frontend “framework”" - description: "HTMX brings modern interactivity to the web without the complexity of a full frontend framework. In this workshop, we’ll dig into how HTMX works while staying in the comfort of Django’s views and templates. We’ll explore how hypermedia can simplify frontend development and bring back clarity to the client–server relationship. We’ll then put it all into practice by building a small hypermedia-driven web app that feels reactive and dynamic." - start_time_slot: 16:00 - end_time_slot: 17:15 + - start: "16:00" track_length: 1 - color: red - type: workshop - language: "English" + room: sala-hedy-lamarr + talk: htmx-a-love-story-between-a-backend-dev-and-a-frontend python_level: intermediate topic_level: beginner - topic: "Web development" - location: "Sala Hedy Lamarr" - repositories: "https://github.com/ericmassip/carbon-home-watcher" - - - speaker: "Ubaldo Hervas" - title: "Causal Inference: a brief introduction" - description: "Discover how causal inference separates correlation from causation to drive better decisions. This fast-paced introduction covers key concepts—treatments, counterfactuals, DAGs, confounding, experiments vs. observational data—and practical tools like A/B tests, DiD, and IVs. Learn design principles, common pitfalls, and how to frame questions that unlock credible, actionable insights at scale." - start_time_slot: 16:00 - end_time_slot: 17:15 + - start: "16:00" track_length: 1 - color: orange - type: workshop - language: "English" + room: sala-hipatia-dalexandria + talk: causal-inference-a-brief-introduction python_level: intermediate topic_level: beginner requirements: "Notebook and basic python knowledge" - topic: "Causal Inference & Data Science" - location: "Sala Hipàtia d'Alexandria" - repositories: " - - <br> <b> Github </b>: https://github.com/UbaldoHervas/PyDay-BCN-2025 - - <br> <b> Leanalytics </b>: https://leanalytics.substack.com/p/022-caso-practico-diferencia-en-diferencias-datos-sinteticos - - " - - - start_time_slot: 17:30 - end_time_slot: 17:45 + - start: "17:30" track_length: 4 - color: purple - title: "Lightning talks + closing session & Kahoot" - description: "Lighting talks: - - <br> <b> Kevin Albes </b>: Building Multi-Agent Workflows with Agent Framework<br> - <br> <b> Brian Power </b>: Five python code samples I show clients who know nothing about Python. And to those who know too much.<br>" - type: talk - location: Sala d'Actes Ada Lovelace - class: middle + room: sala-dactes-ada-lovelace + talk: lightning-talks-closing-session-kahoot + --- @@ -561,7 +531,7 @@ events: We are excited to announce the **9th edition** of PyDay in Barcelona! -PyDay is an event packed with FREE **Python-related workshops** and activities for the Python community. It is organized once per year. Over the [last eight editions](#previous_editions_section), PyDay has become a fantastic opportunity to share our love for Python and engage users, companies, and newcomers! +PyDay is an event packed with FREE **Python-related workshops** and activities for the Python community. It is organized once per year. Over the last eight editions, PyDay has become a fantastic opportunity to share our love for Python and engage users, companies, and newcomers! ### When and where From d93aaa6e6caeed660bea27cfe5d4758fc7e1a70c Mon Sep 17 00:00:00 2001 From: David Arcos <david.arcos@gmail.com> Date: Thu, 15 Oct 2026 10:01:16 +0200 Subject: [PATCH 5/7] Read the programmes of PyData 2017, PyDay 2018, and PyDay 2019 off their frozen pages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Three editions had a page and no programme the templates could read. PyData Barcelona 2017 gets its 32 talks from the archive, with the description each speaker wrote and the slides the page used to list in its body as a numbered list with the speaker names typed in. The talks carry no room and no hour, because no source gives them, so the page lists them as rows and draws no grid. The Media and Slides lists leave the body: the talk records hold the same links. PyDay BCN 2018 gets its 8 sessions off the agenda table the association froze into the page, in 4 rooms, with no length because the printed programme gives none. Its five speakers get a record. PyDay BCN 2019 gets its 15 sessions off the agenda the thread of the day photographed, in 3 rooms. The printed agenda names no speaker, and the thread announced only some of the sessions, so 11 of the 15 talks credit nobody and the four that do (the two keynotes, Héctor Canto, and Anna Fedotova) carry the post they were read from as their source. Both pre-Hugo pages keep their body, the pasted table of 2018 and the calendar embed of 2019, and carry agenda, talks and rooms with no eventTimes, so the page draws no second grid under the frozen one. --- .../other_events/pydata_2017_barcelona.md | 696 +++++++++++++++++- content/events/pyday_bcn/pyday_bcn_2018.md | 437 ++++++++--- content/events/pyday_bcn/pyday_bcn_2019.md | 278 ++++++- 3 files changed, 1230 insertions(+), 181 deletions(-) diff --git a/content/events/other_events/pydata_2017_barcelona.md b/content/events/other_events/pydata_2017_barcelona.md index 8b996afbb..85c0307d9 100644 --- a/content/events/other_events/pydata_2017_barcelona.md +++ b/content/events/other_events/pydata_2017_barcelona.md @@ -1,39 +1,673 @@ --- -title: "PyData Barcelona (2017)" +title: PyData Barcelona (2017) year: 2017 -description: "The Data Science conference from NumFOCUS" +date: 2017-05-19 +end_date: 2017-05-21 +venue: ESADE +description: The Data Science conference from NumFOCUS menu: main: - parent: 'Other events' + parent: Other events weight: 1 heroBackground: /images/photos/pydata_badges.jpg -mainColumn: true +layout: event +talks: +- id: opening-keynote + title: Opening keynote + speakers: + - travis-oliphant + type: keynote + language: en + description: 'Filmed at PyData Barcelona 2017 + + + www.pydata.org + + + PyData is an educational program of NumFOCUS, a 501(c)3 non-profit organization in the United States. PyData provides a forum for the international community of users and developers of data analysis tools to share ideas and learn from each other. The global PyData network promotes discussion of best practices, new approaches, and emerging technologies for data management, processing, analytics, and visualization. PyData communities approach data science using many languages, including (but not limited to) Python, Julia, and R. + + + PyData conferences aim to be accessible and community-driven, with novice to advanced level presentations. PyData tutorials and talks bring attendees the latest project features along with cutting-edge use cases.' + title_note: 'pyvideo stored the role line of the speaker where the title goes, "Chief Data Scientist and co-founder of Continuum Analytics", and no source names the talk. "Opening keynote" is what it was.' +- id: the-magic-behind-pyspark-how-it-impacts-perf-the-future + title: The Magic Behind PySpark, how it impacts perf & the "future" + speakers: + - holden-karau + type: keynote + language: en + description: 'A look at how PySpark "works" today and how we can make it better in the future + insert engine noises of a fast car + + + + **Abstract** + + + This talk will introduce PySpark along with the magic done to make it work and be friends with the JVM. We will discuss why lazy evaluation makes a huge difference in PySpark, both in terms of general optimizations it opens up as well as Python specific considerations. From there we will explore much of the future of Spark, DataFrames & Datasets and what this means for PySpark. Most Spark DataFrame examples limit them selves to things written in the relational style query language, but we will explore how to add more functionality through UDFS. + + + We will wrap up with looking at the different pieces of work being done to make PySpark faster, from using better interchange formats like Apache Arrow to crazy hair brained schemes inspired by (but not the fault of) the Javascript on Spark project. + + + Hopefully no one is scared away from using Spark once they see the 300 small gnome like creatures behind the curtain, but parental guidance is encouraged for those who still believe in magic, reliable distributed systems, and vendor marketing brochures.' +- id: a-beginners-guide-to-weather-climate-data + title: A Beginners Guide to Weather & Climate Data + speakers: + - margriet-groenendijk + type: talk + language: en + description: 'Weather is part of our every day lives. Who doesn''t check the weather forecast regularly? But where does the data come from, what is it made of? The answer is a mix of measurements and models. This session looks at observations, predictions and forecast models, and weather data as a variable to consider in machine learning models. Learn how it is done from several Python notebook examples. + + + **Abstract** + + + Weather is part of our every day lives. Who doesn''t check the rain radar before heading out, or the weather forecast when planning a weekend away? But where does this data come from, what is it made of, and what can you do with it? The answer is a mix of measurements, models and statistics. This session will use Python notebooks with examples of how it is done: + + + * Weather is quantified by the temperature, humidity, wind, rainfall and radiation. These variables are all measured at thousands of locations worldwide and all data is collected and checked to improve the weather forecasts. Learn how to interpolate this data to create for instance global temperature maps to estimate the global monthly and annual temperature. + + * The observations are used to constrain the global weather forecast models. These models are complex and simulate the energy, water and carbon fluxes between and in the atmosphere, ocean and land. The output from the models is gridded data, which is generally stored in binary netcdf files. Learn how to load and process the gridded data into time series or maps for further analysis. + + * The raw model data is processed for you when you request weather data through a REST API. Learn how to use a weather API to train a supervised model with historical weather time series and then use the weather forecast data to do predictions. This session provides you with a brief overview of the science behind weather and climate forecasts and gives you the tools to get started with weather data.' + links: + - type: slides + url: https://www.slideshare.net/MargrietGroenendijk/pydata-barcelona-weather-and-climate-data +- id: despicable-machines-how-computers-can-be-assholes + title: 'Despicable machines: how computers can be assholes' + speakers: + - maciej-siwek + type: talk + language: en + description: 'There''s a widespread belief among machine learning practitioners that algorithms are objective and allow us to deal with the messy reality in a nice, objective way, without worrying about all the yucky human nature things. This talk will argue that this belief is wrong. Algorithms, just like the humans who create them, can be severely biased and despicable indeed. + + + **Abstract** + + + When working on a new ML solution to solve a given problem, do you think that you are simply using objective reality to infer a set of unbiased rules that will allow you to predict the future? Do you think that worrying about the morality of your work is something other people should do? If so, this talk is for you. + + + In this brief time, I will try to convince you that you hold great power over how the future world will look like and that you should incorporate thinking about morality into the set of ML tools you use every day. We will take a short journey through several problems, which surfaced over the last few years, as ML and AI generally, became more widely used. We will look at bias present in training data, at some real-world consequences of not considering it (including one or two hair-raising stories) and cutting-edge research on how to counteract this. + + + The outline of the talk is: + + + * Intro the problem: ML algos can be biased! + + * Two concrete examples. + + * What''s been done so far (i.e. techniques from recently-published papers). + + * What to do next: unanswered questions.' +- id: how-to-manage-complexity-in-distributed-applications + title: How to manage complexity in distributed applications + speakers: + - guillem-borrell-nogueras + type: talk + language: en + description: 'Complexity is tricky. Some years ago we got how to scale the performance of distributed applications, and that''s why everyone is talking about Big Data. But the challenge now is scaling the complexity within a fast-changing environment without penalizing the performance. These are the conclusions after one year developing a library trying to handle this issue, and using it in production. + + + **Abstract** + + + The development of large-scale distributed applications is an engineering challenge by itself. Development has to be orthogonal to be scalable, as you may know if you have heard about the Mythical Man-Month and the Conway''s law: trying to make your application faster may slow down your development. Managing complexity is a new technology trend, and NFQ and the Carlos III University of Madrid have developed a library to make large-scale distributed applications more sensible called pylm (https://pylm.readthedocs.io). Since this library has been already used in production, it is time to summarize what are the challenges one faces when building something more intricate than a Spark cluster. + + + This talk is about the value of developing in-house tools and obtaining deep technological insight opposed to the successive integration of trendy technologies. The latter is suitable to implement one-shot tools for isolated projects, but when facing a multi-year complex project, the former becomes a more solid ground for long-term maintenance. Complexity piles up nonlinearly, and the most popular tools nowadays cringe when they have to be tightly integrated, since in the long term it is impossible to isolate the technical and the human aspects of development. + + + Complexity''s weight is getting heavier in this scalability-obsessed world, and it''s time to talk about it. + + + This project has been funded by the Spanish Ministry of Economy and Competitivity under the grant IDI-20150936, cofinanced with FEDER funds' +- id: feature-importance-and-ensemble-methods-a-new-perspective + title: 'Feature Importance and Ensemble Methods : a new perspective' + speakers: + - constant-bridon + type: talk + language: en + description: 'Ensemble methods are extremely performant in terms of prediction, but lack easy interpretation. Feature importance is not only counting up how many times a feature has been used in a weak learner, but also by how much this feature contributes to the result. Detailed example and implementation are provided in a jupyter notebook in python for the library "xgboost" of extreme gradient boosting. + + + **Abstract** + + + I - Feature importance in ensemble algorithms - state of the art + + + 1) Feature importance in sklearn/xgboost: basically counts the occurrences of a feature in all the weak learners + + 2) Construction of the trees in xgboost: if the trees are deep enough, every feature is going to be used + + 3) Global feature importance is a misleading: a given feature might be critical for a given subpopulation but completely irrelevant for another (ex : multi-class classification) + + + II - Xgboost real feature importance + + + 1) Prediction influence: first splits influence the prediction more than last splits, so the importance of a feature must be weighted by the discrimination it provides + + + 2) Point-to-point feature importance: following the path of a given prediction, it is possible to weigh the importance of every used feature + + + 3) A relevant assessment of feature importance: explanation of a given prediction, and aggregation on a set of data points + + + III - Implementation and examples + + + 1) Point-to-point feature importance illustration and implementation explanation + + + 2) Evolution of feature importance with respect to learning iterations + + + 3) Noisy variables cancellation + + + IV - Limits and ways forward + + + 1) A word on correlated variables + + + 2) Is there a compromise performance/interpretation ?' +- id: happiness-inside-a-job-a-social-network-analysis + title: 'Happiness inside a job: a social network analysis' + speakers: + - guillem-duran-ballester + type: talk + language: en + description: 'In this talk, we will show how to analyze social network data from a mobile phone application to predict employee turnover and employee happiness. We will look into the process of extracting new features from a dataset using social network analysis techniques. We will also show how these features can be visualized and used to boost machine learning models. + + + **Abstract** + + + In this talk, we will show how to analyze social network data to predict employee turnover and employee happiness. This talk is a summary of different notebooks about social network analysis that will be available on [Github](https://github.com/Guillem-db/PyData-Bcn-2017). Please note that all the methodology and details we are using, are explained in depth in the notebooks. + + + We will cover the following topics: + + + * From tables to graphs: How to use [pandas](https://pandas.pydata.org/) and [networkx](https://networkx.github.io/) to merge several DataFrames into a graph, and different criteria for creating a graph representation of a database. + + + * Graph features: How to extract new features using social network analysis techniques such as [`Non-Negative Matrix Factorization`](https://scikit-learn.org/stable/modules/generated/sklearn.decomposition.NMF.html) and graph [`centrality metrics`](https://networkx.github.io/documentation/development/reference/algorithms.centrality.html). We will explain what these features represent, and how they relate to other types of features that can be extracted directly from the database. + + + * Improving ML models: How to use graph features to boost machine learning models. We will talk about different feature selection techniques that can be used to filter out the most significant set of graph-based features using [scikit-learn](https://scikit-learn.org/). + + + * Visualization: How to visualize social interactions using [bokeh](https://bokeh.pydata.org/en/latest/), and how visualization techniques can be used to check data integrity. + + + We will also review common mistakes that can happen during the modeling process and, how to prevent invalid data from getting leaked into your machine learning models. To conclude we compare the merits of using a Python framework versus R Language in terms of development time and computational performance. Data set provided by https://myhappyforce.com' + links: + - type: slides + url: https://github.com/Guillem-db/Happiness-inside-a-job-PyDataBcn17 +- id: machine-learning-to-know-if-you-r-coming + title: Machine Learning to know if you R coming + speakers: + - claudia-guirao + type: talk + language: en + description: 'Predicting Hotel Reservation Cancellations with R language. + + + Knowing in advance bookings that will be canceled before the arrival date is crucial in the hotel sector. We will examine the determinant characteristics of reservation cancellation, the constrains of this project and how the probability of cancellation was estimated. + + + **Abstract** + + + Some users are more likely to cancel their bookings than others, depending on several factors/conditions. Knowing these factors and how many bookings will be canceled will help hotels to optimize their incomes and maximize their occupancy.' +- id: analyzing-code-contributions-to-the-cpython-project-using + title: Analyzing code contributions to the CPython project using NetworkX and Matplotlib + speakers: + - jordi-torrents + type: talk + language: en + description: 'It''s a well established fact that only a small fraction of developers account for most code contributions to FOSS projects. The CPython project is not an exception, but analyzing code contributions through time reveals that the people that contribute the most is not always the same. I model CPython''s contribution dynamics as cooperation networks and analyze them using NetworkX and Matplotlib. + + + **Abstract** + + + I analyze cooperation on the CPython project by analyzing the code contributions that each participant on the project has done through time. I model these contributions as a succession of bipartite networks where the bipartite node sets are contributors and source code files; each contributor is linked to the source files to which they have contributed, weighted by the number of lines of source code added. Analyzing the structure of these networks using NetworkX and Matplotlib I found an hierarchy of nested groups of developers that corresponds to the developers that do most of the code contributions in the CPython project. This hierarchy, on the one hand, reflects the empirically well established fact that in FOSS projects only a small fraction of the developers account for most of the contributions. And, on the other hand, refutes the naive views of early academic accounts that characterized FOSS projects as a flat hierarchy of peers in which every individual does more or less the same. I argue that the structure of CPython''s cooperation network can be characterized as an open elite, where the top levels of this hierarchy are filled with new individuals at a high pace. This feature is key for understanding the mechanisms and dynamics that make FOSS communities able to develop long term projects, with high individual turnover, and yet achieve high impact and coherent results as a result of large scale cooperation. + + + You can download the slides for this talk from https://github.com/jtorrents/thesis/blob/master/presentations/pydata_bcn/cpython_code_contributions.pdf' + links: + - type: slides + url: https://github.com/jtorrents/thesis/blob/master/presentations/pydata_bcn/cpython_code_contributions.pdf +- id: running-jupyter-notebook-remotely-in-a-docker-swarm-cluster + title: Running jupyter notebook remotely in a docker swarm cluster + speakers: + - jordi-deu-pons + type: talk + language: en + description: 'The current version of Jupyter Notebook computes the document state at the browser side, this is a problem if you run long jobs in a remote notebook from a laptop. If you close the browser you lose all the output of the current running cell. I will explain how we solved this problem in our lab. This solution it also allows a "walkie-talkie" like real-time collaboration. + + + **Abstract** + + + The solution is based on running a docker container with a browser and a VNC server. All the remote access to the notebooks is done using Apache Guacamole a clientless remote desktop gateway. Everything is running on a dynamic docker swarm cluster of 20 nodes. As a lateral effect, this solution it also allows a real-time collaboration between users in a way that multiple users can access at the same time the same desktop (but they have to fight for the mouse and the keyboard). + + + https://github.com/jordeu/pytalks/tree/master/20170520_pydata_jupyter_in_a_docker_cluster' +- id: tensorflow-wide-deep-advanced-classification-the-easy-way + title: 'TensorFlow Wide & Deep: Advanced Classification the easy way' + speakers: + - yufeng-guo + type: talk + language: en + description: 'In this talk, we will go on an adventure to build a machine learning model that combines the benefits of linear regression models with deep neural networks. You will also gain some intuition about what is happening under the hood, and learn how you can use this model for your own datasets. + + + **Abstract** + + + Deep learning has already revolutionized machine learning research, but it remains out of reach for many developers. However, tools already exist today that enable leading-edge machine learning for many problem domains. + + In this talk, we will go on an adventure to build a machine learning model that combines the benefits of linear models with deep neural networks. You will also gain some intuition about what is happening under the hood, and learn how to use this model for your own datasets! To accomplish this, we will use TensorFlow, an open-source machine learning library with a full Python interface. It has become the most popular machine learning library on GitHub, and the community around it is growing rapidly.' + links: + - type: slides + url: https://storage.googleapis.com/yufengg-slides/pydataBCNslides.pdf +- id: deepcare-chatbot-generating-answers-to-customers-using-deep + title: DeepCare Chatbot - Generating answers to customers using Deep Learning and NLP + speakers: + - pascal-van-kooten + type: talk + language: en + description: 'The DeepCare chatbot is capable of learning to answer customer questions. Using a hybrid approach of NLP and Deep Learning, it tries to combat logical fallacies that occur in pure deep learning bots, while still coming up with unique answers. + + + In particular, it uses a sequence-to-sequence (seq2seq) long-short-term-memory LSTM deep learning model to capture intricacies in questions. As organisations cannot afford a bot making logical mistakes, verification through NLP is used. This two-step model prevents the downside of "no control" on deep learning, as well as the too static nature of classical rule based NLP models, and thus enables potentially higher quality answers. + + + A live demo will be available at https://deepcare.online on the day of the talk.' + links: + - type: slides + url: https://www.slideshare.net/PascalvanKooten/deepcare-chatbot-generating-answers-to-customers-using-a-hybrid-approach-of-deep-learning-and-nlp + title_note: 'The Slides list of the pre-Hugo page named it "DeepCare Chatbot - Generating answers to customers using a hybrid approach of Deep Learning and NLP", the title of the slides. The video names it as above.' +- id: extending-jupyter-with-google-cloud-storage-file-system + title: Extending Jupyter with Google Cloud Storage file system backend + speakers: + - egor-bulychev + type: talk + language: en + description: 'Jupyter has a modular architecture which allows extending it in numerous ways. This talk presents src-d/jgscm, Google Cloud Storage Jupyter file system backend which provides the ability to work with notebooks and other files directly in Google Cloud Storage. The described approach can be used for writing similar backends, e.g. for Amazon Cloud. + + + See more here : https://egorbu.github.io/pydata_2017_barcelona/index.html + + + **Abstract** + + + src-d/jgscm is a Jupyter file system backend for Google Cloud Storage. It allows to work with notebooks and other files directly in Google Cloud Storage. It''s codebase is rather small and simple thanks to Jupyter''s modular architecture. We start from the very basics, revise how Google Cloud Storage works and how Jupyter deals with the virtual file system and end up with the complete production-tested backend implementation. The described ideas are rather versatile and can be re-used to create backends for similar cloud storage systems, e.g. Amazon.' +- id: the-secret-life-of-rolling-pandas + title: The Secret Life Of Rolling Pandas + speakers: + - jaime-fernandez-del-rio + type: talk + language: en + description: 'Pandas provides a powerful set of functions to compute statistics on rolling windows. We will go beyond the convenient interface, and peek at the algorithmic gems that implement these operations efficiently: summed area tables, Welford''s method, skip lists, ring buffers, deques... will all get their minute of fame, and attendees may learn a thing or two they can use in their everyday coding. + + + **Abstract** + + + The talk will cover: + + + * A quick overview of the Rolling and Expanding objects in pandas. Why straightforward implementations, even clever ones using advanced NumPy tricks, are inefficient. + + * How is Series.rolling().sum() implemented. How the same idea can be extended to higher dimensions with the help of the inclusion-exclusion principle to yield summed area tables. + + * How are Series.rolling().var() and friends implemented. The importance of numerically stable algorithms: why Welford''s method is the better choice, even if it''s a little slower. How can the same ideas be generalized to higher order moments, and used to parallelize computations. + + * How are Series.rolling().max() and .min() implemented. The beauty of clever algorithms. The use of specialized data structures: a ring buffer as a deque. + + * How are Series.rolling().median() and .quantile() implemented. More specialized data structures: the skip list, or why randomization can be your friend.' +- id: nasa-space-apps-challenge-asteroid-prediction-impact + title: 'NASA Space APPS Challenge: Asteroid prediction impact' + speakers: + - gema-parreno + type: keynote + language: en + description: 'TensorFlow and Prophet : Forecasting Asteroid impact with opensource software Talk about NASA Space APPS 2016 global finalist project , focused on neural net design + + + **Abstract** + + + The talk will have two separate parts ; the first of it focuses on explaining Tensorflow architecture and Prophet opensource tools and the second part will dive into the Neural Net design and forecast prediction .' +- id: squeeze-gently-your-data + title: Squeeze (gently) your data + speakers: + - francesc-alted + type: keynote + language: en + description: 'Coping with the growing rate of data sources is becoming a big challenge, not only in terms of efficiently storing it, but also (and most specially) in doing more general computations with them. Compressing your data may help in many (and sometimes unexpected) ways in this task. This talk will introduce several ways in which you can benefit from highly efficient compression libraries. + + + **Abstract** + + + Nowadays CPUs are fast; they are coming with more and more cores and, in comparison, memory speed is not keeping this race in terms of speed. As a result, this opening gap is what is making of compression a valuable technique, not only for storing the same data by using less storage but also to accelerate data handling operations in an increasing number of cases. + + + My talk will start by introducing the technological reasons behind the increasing benefit of using compression in data science, and then will show some practical cases where data compression can lead to much more efficient data pipelines. For this, I will be using well-proven compression libraries like [Blosc](https://www.blosc.org/), [Zstandard](https://github.com/facebook/zstd) and [LZ4](https://github.com/lz4/lz4) that, either in combination with data handling libraries (like [PyTables](https://www.pytables.org/), [bcolz](https://bcolz.blosc.org/en/latest/) or [zarr](https://zarr.readthedocs.io/en/latest/)), or used for handling high-speed data streams (transmitted e.g. via [gRPC](https://www.grpc.io/)).' + links: + - type: slides + url: https://speakerdeck.com/francescalted/squeeze-gently-your-big-data +- id: increasing-the-trading-prediction-by-mining-aggregated + title: Increasing the trading prediction by mining aggregated human texting messages + speakers: + - yang-liu + type: talk + language: en + description: 'A novel approach is proposed to predict intraday directional-movements of the stock in the trading market based on the text of breaking financial news or social media by event data. This work is an effort to put more emphasis on the text-mining methods and tackle some specific aspects thereof that are weak in previous works. The research is a specific market, namely, the trading and stock market, + + + **Abstract** + + + Sentiment analysis This step is observed the time series of the company''s event based on the financial news or the social media, which analyses problem of coreference in text mining that is sentiment classification. Fasttext is inspired method that focuses on the meaning of words, which solves to obscure by ambiguity and play on words. This way can classify polarity, subjectivity and intensity in the corpus. According to the results of the classification, then it changes to the word representation. Thus, prediction accuracy increases significantly at this layer that is attributed to appropriate noise-reduction from the feature-space. Model creation and prediction The first layer is termed Sentiment Integration Layer by the deep neural network, which integrates sentiment analysis capability into the algorithm by proposing a sentiment weight that reflects their sentiment. Additionally, this layer reduces the dimensions by eliminating value in terms of sentiment and thereby improves prediction accuracy. The second layer encompasses a deep neural network model creation algorithm. It updates the models with the most recent information available, the deep learning algorithm is extensively evaluated using real market data and news content across multiple years, which is a good fitting capability to evaluate and select the financial news. The third layer is that it uses the recursive neural network explore patterns and of financial news through the recursive and pooling operation.' + links: + - type: slides + url: https://drive.google.com/open?id=0B19Xo1zu3JtgZmVDaWVyTk1uN3M +- id: the-neuroscience-lab + title: The Neuroscience Lab + speakers: + - nicholas-a-del-grosso + - javier-martinez-alcantara + type: talk + language: en + description: 'Python is an excellent fit for scientists; it is readable, has an active scientific community, and, most importantly, is versatile across a wide variety of programming tasks. In this talk, we will celebrate this versatility of Python by sharing the research being done in our neuroscience laboratory, focusing on Python''s involvement in each step of our scientific research. + + + **Abstract** + + + Biologists have always built their own hardware to perform unique experiments; today, new data collection and analysis techniques demand that they develop their own software as well. Often, this means that researchers without a formal education in programming must perform a wide variety of programming tasks in order to perform cutting-edge research. As a "real" programming language, Python is an excellent fit for scientists, not only for its oft-celebrated readability, active scientific community, and cross-platform support, but also for its versatility across a wide variety of domains. In this talk, we will celebrate this versatility of Python by sharing the research being done in our neuroscience laboratory, focusing how Python packages, applications, and plugins have become the tools of choice for everything from real-time machine vision and 3D graphics to data analysis and the presentation of scientific results.' + links: + - type: slides + url: https://www.slideshare.net/JavierMartinezAlcant/neuroscience-lab-a-tour-through-the-eyes-of-a-pythonista-pydata-barcelona2017 + title_note: 'The Slides list of the pre-Hugo page named it "Neuroscience Lab, a tour through the eyes of a pythonista", the title of the slides, and credited Javier Martínez Alcántara alone. The video names it as above and credits both speakers.' +- id: web-scraping-with-python + title: Web Scraping with Python + speakers: + - carles-illa + type: talk + language: en + description: 'Web Scraping is widely used to get data from websites automatically. Whether it be contact information, news or selling prices, we rely on web scraping techniques as they allow us to collect large data with minimal effort. + + + In the Python ecosystem we have a lot of different tools for extracting data from web pages, and in this talk we will present some of the most powerful ones. + + + **Abstract** + + + Web Scraping is the process of extracting useful information from the web automatically. + + + It is widely used for various purposes like: + + + - Lead generation + + - Price monitoring on e-commerce sites + + - Product reviews collection to do sentimental analysis + + - Social profiles retrieving for recruiters + + - Scraping blogs & forums to keep up with trends and news + + - Maintaining up-to-date real estate databases + + - News aggregators + + - Reputation monitoring + + - Events listings + + - Websites changes detection + + - Etc. + + + In this talk we will present some of the most powerful tools for extracting data from web pages using Python. We will learn how to use Python to request information from a web server, how to perform basic handling of the server''s response, and how to begin interacting with a website in an automated fashion.' +- id: guillotina-an-async-rest-resource-db-to-manage-millions-of + title: Guillotina - An Async REST Resource DB to manage millions of objects + speakers: + - ramon-navarro-bosch + type: talk + language: en + description: 'Guillotina is a new framework designed to be horizontal scalable, build on top of aiohttp and offering a Resource REST API to store, read and query object oriented datasets with millions of elements. Based on JSON schema types allows to define a Traversal API with strong security and granularity. With an abstracted storage layer its possible to provide support for Couch, Cassandra and Postgres. + + + **Abstract** + + + One of the most common problems on my daily basis data management is a way to store and secure objects with information in a transactional scalable infrastructure. Having an async API that holds security, triggers and transactional operations allows to provide an interface for managing the data that will be processed by the machine learning engines on batch operations. Including async queues of operations allows to provide model inference on the objects on real time operations on objects on the stack. + + + After 15 years on Plone/Zope framework we started to design a new concept using all the lessons learned on content management to provide a CRUD storage layer for big data objects.' + links: + - type: slides + url: https://www.slideshare.net/bloodbare/guillotina-76266421 +- id: lymphos2-organizing-and-sharing-biological-data + title: LympHOS2, Organizing and Sharing Biological Data + speakers: + - oscar-gallardo-roman + type: talk + language: en + description: "The study of the proteome (the set of proteins expressed by a cell,\ntissue, or organism at a defined time and conditions) generates a large\namount of complex data. This data should be processed, stored, curated,\nand made easily available to researchers so it can be studied to obtain\nbiomedical knowledge. In this talk we expose the Python tools we have\nused and developed to accomplish it.\n\nAbstract\n\nAt the [LP-CSIC/UAB](https://proteomica.uab.cat) we use a technology called [Mass Spectrometry](https://en.wikipedia.org/wiki/Mass_spectrometry) to\nstudy the *phospho-proteome of human T-Lymphocytes*; this is, the group\nof proteins that are phosphorilated (modified with phosphate groups) in\nthe human [T cells](https://en.wikipedia.org/wiki/T_cell) during their activation and differentiation as part\nof the [immune response](https://en.wikipedia.org/wiki/Immune_response). The experiments involved in this study\ngenerates a *large* amount of *complex* data:\n\n- Experimental conditions and procedures metadata.\n- The spectra data and metadata obtained from the mass spectrometers\n (usually in proprietary binary formats).\n- Qualitative or identification data, consisting of search results of\n those spectra against human protein sequence databases (using\n multiple search engines, that use different output file-formats)\n linking the spectra with possible peptides (small protein sequence\n fragments) that may or may not contain phosphorylated amino-acids.\n- Semi-quantitative data about the abundance of each possible\n identified peptide.\n- Missing values, identification scores, phosphorylation reassignments,\n and a lot of relationships and inter-linked data...\n\nAnd all this data has to be **processed**, **stored**, **curated**, and\nmade **easily accessible** to researchers in our lab and worldwide, so\nthey can study it to obtain biomedical knowledge about the\nphosphorylation changes in peptides and proteins involved in the signal\ntransduction pathways of T cells after their activation during the\nspecific immune response.\n\nWe have used different Python *packages* to develop different tools and\napplications to accomplish those objectives:\n\n- The [EasierMgf](https://bitbucket.org/lp-csic-uab/easiermgf) front-end application, to extract plain text spectra\n data from proprietary binary mass spectrometer files, was developed\n using the [wxPython](https://wxpython.org/) GUI toolkit.\n- The [ORM](https://en.wikipedia.org/wiki/Object-relational_mapping) from the [django](https://www.djangoproject.com/) framework was used to design and\n interact with the LymPHOS2 [MySQL](https://www.mysql.com/) database, which stores all the\n data and their inter-relationships.\n- Also, different modules from the Python standard library (*json*,\n *xml.etree.ElementTree*, *csv*, *zipfile*) were used to read and\n [import](https://bitbucket.org/lp-csic-uab/lymphosweb/src/c127cd7a88a5dfb0a70b9e3b6243553c6adda6fb/src/LymPHOS_v1_5/lymphos/filters.py) into the database the different files containing the data;\n and to [export](https://bitbucket.org/lp-csic-uab/lymphostools) database data into commonly used file formats for\n the researches to work with.\n- The [PQuantifier](https://bitbucket.org/lp-csic-uab/lymphospquantifier) group of tools was developed to do the statistical\n processing and analysis of the LymPHOS2 semi-quantitative data. It\n uses the [SQLAlchemy](https://www.sqlalchemy.org/) ORM for fast database storage in local\n [SQLite](https://sqlite.org/) files, the [NumPy](https://www.numpy.org/) N-dimensional array package, the\n [SciPy](https://scipy.org/scipylib) scientific computing library for the statistics, the\n [uncertainties](https://pythonhosted.org/uncertainties/) package for calculations with error propagation,\n and the [matplotlib](https://matplotlib.org/) 2D plotting library for some nice plots of\n data distributions.\n- And the full django framework itself was used to develop the\n [LymPHOS2](https://www.lymphos.org) web application. Which also uses the matplotlib library\n to dynamically generate the mass spectra images.\n\nThe final result is the `LymPHOS2 <https://bitbucket.org/lp-csic-uab/lymphosweb/branch/Web_LymPHOS_2>`_ web-oriented database, that\nnowadays (2017) contains 131.908 mass spectra, 15.566 phosphorylation\nsites from 8.273 unique phospho-peptides and 4.937 proteins (which\nrepresent a 45-fold increase over the original LymPHOS database of\n2009); aside from the new quantitative data for 1.975 of the identified\nphospho-peptides, which was not present in the previous version of\nLymPHOS.\n\n**Repositories and Presentation Slides:**\n\n- Bitbucket code repositories: https://bitbucket.org/lp-csic-uab/\n- Presentation Slides (.ODP, .PDF and .PPTX):\n https://bitbucket.org/lp-csic-uab/lymphosdocs/downloads/\n\n**Credits:**\n\nThe exposed work has been carried out at [LP-CSIC/UAB](https://proteomica.uab.cat) from\n[Catalonia](https://en.wikipedia.org/wiki/Catalonia), part of the `Spanish National Research Council (Consejo\nSuperior de Investigaciones Científicas - CSIC)`_ and of `ProteoRed\n(Proteomics National NetWork Platform)`_.\n\nThe *people* who have participated directly in the current work are:\n\n- **Data analysis, bioinformatics and informatics**: *Joaquin Abian*\n and *Óscar Gallardo*.\n- **Mass Spectrometry, experimental design and implementation**:\n *Montserrat Carrascal*, *Nguyen Tien Dung* and *Oriol Vidal-Cortes*.\n- **Sample preparation**: *Montserrat Carrascal*, *Nguyen Tien Dung*,\n *Oriol Vidal-Cortes* and *Vanessa Casas*.\n- **Past collaborators**: *David Ovelleiro* and *Marina Gay*.\n- **Direction**: *Joaquin Abian*." + links: + - type: slides + url: https://bitbucket.org/lp-csic-uab/lymphosdocs/downloads/ + title_note: 'The Slides list of the pre-Hugo page named it "LympHOS2, Organizing and Sharing Biological Data of the Human Lymphocyte Proteome using Python". The video names it as above.' +- id: prototyping-interactive-dashboards-with-jupyter-notebooks + title: Prototyping Interactive Dashboards with Jupyter Notebooks + speakers: + - camilo-cardona + type: talk + language: en + description: 'In this talk, I describe my experience in using jupyter-dashboards, ipywidgets and other libraries to build basic prototypes of data exploration dashboards for datasets related to Internet traffic and packet-switching networks. We''ll go over various examples on how to build and use the widgets to navigate the data, visualize analysis, and evaluate optimization changes. + + + **Abstract** + + + As python programmers, we often use jupyter notebooks as a platform for reproducible data analysis and publication of results. The jupyter ecosystem is still under-utilized for projects that require interactions from non-coder users, such as explorative dashboards or Business intelligence applications. There are other specialised options for these UI/UX interfaces, but integrating them into the analysis pipeline (e.g. Jupyter) is often rather hard. Preferably, we would be able to prototype these interactive applications without leaving our environment. + + + Jupyter-dashboards, ipywidgets, and other typical pydata libraries provide jupyter with the capabilities to create flexible, and rather powerful interactive elements. This toolset can be used in small projects to create the final facing interface for a limited number of end users. For bigger projects, a more robust UI/UX is normally required to support larger number of simultaneous users. However, the jupyter-dashboard/ipywidgets toolset can still be useful in these cases as an end-to-end prototyping platform, allowing us to get feedback from users at early stages of the project, thus helping us better steer our development. + + + In this talk, I share experiences of using this toolset for different use cases related to analysis of Internet traffic and network engineering. I''ll go over examples of how to build widgets to explore the Internet traffic and other network data, while highlighting some of its characteristics. Furthermore, I''ll describe some optimisations performed by network engineers on their traffic, such as load balancing, and how the tools can be used to evaluate them.' + links: + - type: slides + url: https://github.com/jccardonar/pydata_bcn_presentation + title_note: 'The Slides list of the pre-Hugo page named it "Prototyping Interactive Dashboards with Jupyter Notebooks: Examples from Network Engineering". The video names it as above.' +- id: blockchain-and-smart-contracts-explained-and-simplified + title: Blockchain and smart contracts explained (and simplified) + speakers: + - guillem-borrell-nogueras + type: talk + language: en + description: 'Blockchain is the next big thing that will revolutionize everything, but no one knows how. The same can be said about smart contracts. Bitcoin and Ethereum are great technologies, but too complex for most cases. This talk will explain why smart contracts are hard, and why they don''t need to be. Finally, a simple ledger for smart contracts in python (pyledger) will be presented. + + + **Abstract** + + + Smart contracts are an old and simple concept. They are just computer programs that facilitate the negotiation and settlement of contracts by several parties. Their goal is to lower the transaction latency and cost associated with human middlemen. The blockchain technology brought the possibility to sanction contracts when peers do not trust each other, which is necessary for applications like virtual currencies. However, due to the CAP theorem and the cost of the Byzantine consensus, their performance tends to be quite bad. + + + Current smart contract platforms such as Ethereum are general (one can issue any kind of contract), distributed (an updated copy is present at all the nodes within the same network), shared (an arbitrary amount of contracts are served within the same infrastructure) and secure (there is no way to tamper with the stored data). All those properties are undeniably good, but the consequence of keeping all those promises is that the infrastructure is exceedingly complex. Such an extense architecture does not add any functionality to a smart contract, it makes it trustworthy. + + + If one understands the raw concepts behind the Blockchain consensus, and we are willing to sacrifice some of the properties mentioned earlier, one can design and implement a simple ledger for smart contracts like pyledger (pyledger.readthedocs.io). Pyledger was designed as a platform for fast prototyping of smart contracts, and for experimentation, but in some particular cases can be good enough to be used in real-world cases. + + + Finally... Fun time! All the concepts will be exemplified with a Q&A contest implemented as a smart contract where all attendants can play.' +- id: how-to-map-a-protein-structure-into-a-network-graph-to + title: How to map a protein structure into a network graph to understand protein folding + speakers: + - massimo-domenico-sammito + type: talk + language: en + description: 'In all living systems any biological function is carried out by the interactions of proteins. The specific function of a protein is determined by its own 3d shape that can be modeled in a list of single atom coordinates derived from experimental analysis. In our lab we use python to process the information of hundred thousands structures already known to predict common patterns in protein folding. + + + **Abstract** + + + From DNA, the genetic code is translated into proteins being these macro molecular structures in charge to execute specific cellular functions. All proteins are composed by the combination of the same 20 amino acids, indeed, it is the 3D shape and detailed structure that differentiate a protein from another and so their functions. Determining protein structure is fundamental to understand their biological function; modify and alter their structures is the way in which drugs can block or activate a protein activity and doing so preventing or treating diseases. In our lab we are understanding protein and DNA structures to the level of atomic resolution contributing to the biomedical research. We process with python the information of hundred thousands 3D coordinate structures already known and predict patterns that can be used to determine structure of unknown proteins. To achieve this objective, proteins are first reduced to a series of specific 3D vectors (Characteristic Vectors [#]_) and then the geometrical relationships among them are extracted. We make use of biopython and python-igraph libraries to model each structure vectors in a network graph and we use supervised and unsupervised learning to classify and predict structure features. Python-igraph is a wrapper to a C code implementation of a set of graph algorithms of classical use in network analysis. + + + .. [#] Sammito M1, Millán C, Rodríguez DD, de Ilarduya IM, Meindl K, De Marino I, Petrillo G, Buey RM, de Pereda JM, Zeth K, Sheldrick GM, Usón I. Exploiting tertiary structure through local folds for crystallographic phasing. Nat Methods. 2013 Nov;10(11):1099-101. doi: 10.1038/nmeth.2644. Epub 2013 Sep 15.' +- id: python-for-visualization-of-hpc-applications + title: Python for visualization of HPC applications + speakers: + - miguel-zavala-ake + type: talk + language: en + description: This work describes the usage of python in application that makes use of high performance application (HPC). Such applications comprise examples as computational fluid dynamics, where the analysis of large data bases is necessary in order to extract useful information. On the other hand, a common way used in the analysis of data is the visualization. It can be done by libraries as matplotlib or pandas, however more sophisticated 3D visualization can also be performed though vtk and mpi4py libraries, or even though Blender of 3d Max. The two latter case enable the use of high quality rendering. +- id: data-science-for-lazy-people-genetics-will-work-for-you + title: Data science for lazy people... genetics will work for you! + speakers: + - diego-hueltes + type: talk + language: en + description: 'Data science is fun... right? Data cleaning, feature selection, feature preprocessing, feature construction, model selection, parameter optimization, model validation... oh wait... are you sure? What about automating 80% of the work using genetic algorithms that can make better choices than you? TPOT is a tool that automatically creates and optimizes machine learning pipelines. + + + **Abstract** + + + We love Data Science, but sometimes we have to do some manual and repetitive work before starting with the interesting and fun parts, but that will change. TPOT is an open source tool built on top of scikit-learn for creating and optimizing machine learning pipelines. It can be considered a data science assistant. The library will automate from feature selection to parameter optimization, it is also able to do preprocessing or construct new features from existing ones. TPOT tests a huge number of pipelines to provide you with the optimal one, this work is done with genetic algorithms. It is easy to use, has a familiar syntax if you have used Pandas or scikit-learn, and it''s very powerful. Let genetics work for you!' + links: + - type: slides + url: https://slides.com/j-diegohueltesvega/data-science-lazy-people#/ +- id: marketing-data-science + title: Marketing Data Science + speakers: + - joaquin-pais + type: talk + language: en + description: 'Marketing Data Science: how digital marketing needs data science to survive. + + + **Abstract** + + + Digital Marketing is changing the way corporations and brands communicates with customers. The investments in Digital Marketing are skyrocketing around the world in a multi-billion industry. + + + But consumers and customers (specially millenials) does not trust advertising. Different approaches are being made by corporations like Inbound Marketing Strategies. My presentation is about how Digital Marketing needs Data Science in order to better understand the customer needs and generate new niches of interest for companies. Companies investing in Digital Marketing should take a close look at Data Science Platforms like Python in order to better gather inisghts, create segments and personalice a customer experience. + + + I will provide some short examples about how we are using python jupyter notebook environment in order to gain inisghts from customers using IBM Watson API, generating new segmentation and customer experiences.' +- id: using-network-community-clustering-algorithms-to-aid + title: Using network community clustering algorithms to aid determination of protein structures + speakers: + - claudia-millan + type: talk + language: en + description: 'How can you best exploit the information on the protein structures that we already know in order to solve the (many more) that we don''t know? That''s the question we try to solve in our group and this talk will show our use of community clustering on the use case of aiding protein structure solution. + + + **Abstract** + + + The study of proteins is extremely relevant to many fields, ranging from medicine to industrial processes. If a cell was a factory, proteins would be the workers, performing very specific tasks in a production chain, in which a failure at any of the steps might affect the others. In order to really understand the function of proteins, there are a number of biochemical techniques that we can apply, but to get a really accurate description of their mechanisms we need to have information up to their atomic level. Proteins are composed by different combinations of 20 amino acids which form chains and result in an intricate and functional structure. We know the final shape of the protein is dependent from its sequence but we can''t (currently) predict the outcome of a given sequence, so we need experimental techniques to obtain this information. We can''t directly look a protein with a microscope and see its three-dimensional atomic arrangement. There are biophysical techniques that allow us to get low-resolution shapes or surfaces of them, but the only current method that provides atomic detail is x-ray diffraction. In contrast to microscopy, were after illuminating your sample you can, with the appropriate lenses, transform back your reflected rays in an image, in x-ray diffraction we only get the Fourier transform of our protein''s structure, that is, its diffraction pattern, but we lose the phase information from the diffracted rays. This problem, known as the phase problem, is an issue in structure solution, because, compared to the intensities of the diffraction pattern, phases provide much more information about our protein''s structure. Phases can be computed from a coordinates model, so, if there is a structure of a protein that is expected to be similar (in terms of their coordinates) to an unknown one, it can be used to provide initial estimates of the phases and then improve them until the problem structure is solved. + + + Proteins do not adopt random shapes. There are forces that act on them and, according to the chemical properties of the amino acids and the context they have around, they will arrange in particular forms. The first level of structure formed is what we call secondary structure, which is formed of alpha helices and beta strands. These are very general and are present in all kind of proteins. As letters in different books, which are general if looked at independently but can acquire a quite different meaning in ''El Quijote'' than in ''50 Shades of Grey'', these structure fragments alone have a different meaning than when set in a context with other structure elements. Yet, even combinations of a few elements can still be general and frequent, and have a sense, such as the phrase ''Once upon a time'' in so many tales. In the protein case, particular small combinations of alpha helices and beta strands should also appear more frequently and can be studied on their different contexts. In a way, we could say that, protein structures, from a top down view, look quite different between them, but from a bottom up one, when we go to small pieces, they look much more similar. + + + In our group, we try to exploit these properties of protein structures for solving two types of problems. One is a search problem, consisting in understanding which is the best way in which to break down a larger model of a protein similar to an unknown one in order to refine it and get the correct phases and solve the structure. The other one is more of a prediction problem, in which we want to find structural units in the database of solved structures in order to help us interpret them and extract new information from this vast amount of data. In order to solve both problems we need a numerical description of our system than can help us describing its geometrical features in an accurate way. We have developed a description of such secondary structure fragments based on what we call characteristic vectors, that we also employ to represent the relations between such elements. This description can be implemented in a network graph that allows to use community clustering algorithms on it in order to evaluate simultaneously all the relations between the elements of the structure and find its communities. + + + From the technical point of view, the language we use for our development is Python, and the tool in which our graphs are implemented is python-igraph. There are a number of community clustering algorithms available and deciding which is the best for our case and which metrics to use to describe our structures has been an interesting process that we want to share with you. In this talk I will explain our research and development on this topic and I will link the general descriptions to our current and successful use case, possibly leaving open questions on what can we do more!' + links: + - type: slides + url: https://drive.google.com/file/d/0Bzli2ZOV2beTd01ZdHBkWHc5b2M/view +- id: security-for-data-scientists + title: Security for Data Scientists + speakers: + - david-arcos + type: keynote + language: en + description: 'Handling confidential data attracts unwanted attention from hostile attackers. + + + We will go over the basic concepts of security threats, show many examples of real attacks, and focus on how to defend ourselves and secure our data. + + + Keep yourself safe! + + + **Abstract** + + + Main topics: + + + * Myths + + * Why it''s important to be safe + + * Authentication & Password Managers + + * Phishing & 2FA + + * MITM & Encryption + + * Internet tracking & Ad-blockers + + * Internet Of Things + + * Physical Security + + * More Resources' + links: + - type: slides + url: https://www.slideshare.net/DZPM/security-for-data-scientists +- id: an-introduction-to-the-tidyverse + title: An introduction to the tidyverse + speakers: + - jorge-cimentada + type: talk + links: + - type: slides + url: https://github.com/cimentadaj/PyData_2017 +- id: introduction-to-data-analysis-with-pandas + title: Introduction to data analysis with Pandas + speakers: + - eduard-goma + type: talk + links: + - type: slides + url: https://github.com/eduardgoma/pandas-workshop +- id: social-network-analysis-with-python-and-networkx + title: Social Network Analysis with Python and NetworkX + speakers: + - jordi-torrents + type: talk + links: + - type: slides + url: https://github.com/jtorrents/pydata_bcn_NetworkX --- -The [PyData 2017 - Barcelona edition](https://pydata.org/barcelona2017/) took place from May 19th to 21th at [ESADE](https://www.esade.edu/homesite/esp/esadeforum). - -## Media - -You can see all the [photos](https://www.flickr.com/photos/pydata/sets/72157684439580266/) and [videos](https://www.youtube.com/playlist?list=PLGVZCDnMOq0oieXy92cJBwSirA3G2MCU1) from the event. - -## Slides - -This is the list of the slides talks and workshops you can find from the event: - -1. [A Beginners Guide to Weather & Climate Data](https://www.slideshare.net/MargrietGroenendijk/pydata-barcelona-weather-and-climate-data) by Margriet Groenendijk -1. [An introduction to the tidyverse](https://github.com/cimentadaj/PyData_2017) by Jorge Cimentada -1. [Analyzing code contributions to the CPython project using NetworkX and Matplotlib](https://github.com/jtorrents/thesis/blob/master/presentations/pydata_bcn/cpython_code_contributions.pdf) by Jordi Torrents -1. [Data science for lazy people... genetics will work for you!](https://slides.com/j-diegohueltesvega/data-science-lazy-people#/) by Diego Hueltes -1. [DeepCare Chatbot - Generating answers to customers using a hybrid approach of Deep Learning and NLP](https://www.slideshare.net/PascalvanKooten/deepcare-chatbot-generating-answers-to-customers-using-a-hybrid-approach-of-deep-learning-and-nlp) by Pascal van Kooten -1. [Guillotina - An Async REST Resource DB to manage millions of objects](https://www.slideshare.net/bloodbare/guillotina-76266421) by Ramon Navarro Bosch -1. [Happyness inside a job: a social network analysis](https://github.com/Guillem-db/Happiness-inside-a-job-PyDataBcn17) by Guillem Duran Ballester -1. [Increasing the trading prediction by mining aggregated human texting messages](https://drive.google.com/open?id=0B19Xo1zu3JtgZmVDaWVyTk1uN3M) by Yang Liu -1. [Introduction to data analysis with Pandas](https://github.com/eduardgoma/pandas-workshop) by Eduard Goma -1. [LympHOS2, Organizing and Sharing Biological Data of the Human Lymphocyte Proteome using Python](https://bitbucket.org/lp-csic-uab/lymphosdocs/downloads/) by Óscar Gallardo Román -1. [Neuroscience Lab, a tour through the eyes of a pythonista](https://www.slideshare.net/JavierMartinezAlcant/neuroscience-lab-a-tour-through-the-eyes-of-a-pythonista-pydata-barcelona2017) by Javier Martínez Alcántara -1. [Prototyping Interactive Dashboards with Jupyter Notebooks: Examples from Network Engineering](https://github.com/jccardonar/pydata_bcn_presentation) by Camilo Cardona -1. [Security for data scientists](https://www.slideshare.net/DZPM/security-for-data-scientists) by David Arcos -1. [Social Network Analysis with Python and NetworkX](https://github.com/jtorrents/pydata_bcn_NetworkX) by Jordi Torrents -1. [Squeeze (gently) your data](https://speakerdeck.com/francescalted/squeeze-gently-your-big-data) by Francesc Alted -1. [TensorFlow Wide & Deep: Advanced Classification the easy way](https://storage.googleapis.com/yufengg-slides/pydataBCNslides.pdf) by Yufeng Guo -1. [Using network community clustering algorithms to aid determination of protein structures](https://drive.google.com/file/d/0Bzli2ZOV2beTd01ZdHBkWHc5b2M/view) by Claudia Millán +The [PyData 2017 - Barcelona edition](https://pydata.org/barcelona2017/) took place from May 19th to 21th at [ESADE](https://www.esade.edu/homesite/esp/esadeforum). The talks below link to the page of each one, with its video and its slides. The event also published an album of [photos](https://www.flickr.com/photos/pydata/sets/72157684439580266/) and a playlist of its [videos](https://www.youtube.com/playlist?list=PLGVZCDnMOq0oieXy92cJBwSirA3G2MCU1). diff --git a/content/events/pyday_bcn/pyday_bcn_2018.md b/content/events/pyday_bcn/pyday_bcn_2018.md index 7b8f3a8a3..b3f20ee8e 100644 --- a/content/events/pyday_bcn/pyday_bcn_2018.md +++ b/content/events/pyday_bcn/pyday_bcn_2018.md @@ -1,126 +1,324 @@ --- title: "PyDay BCN (2018)" year: 2018 +# The day of this edition, from the Meetup export, which records it per event. +date: 2018-11-24 +# The venue of this edition, from the Meetup export, which records it per event. +venue: "Punt Multimèdia Espanya Industrial" description: "" menu: main: parent: 'PyDay BCN' weight: 8 heroBackground: /images/photos/people-pyday-2016.jpg ---- -<div class="container"> - <div class="row main_content"> - <div class="col-md-9 main_column"> - <p> - We are excited and glad to announce that we are organizing the second edition of PyDay in Barcelona! - </p> - <p> - PyDay Barcelona 2018 is going to take place on <b>November 24th</b> at <a href="https://goo.gl/maps/Ngk6PbN3FuB2" target="_blank">PuntMultimèdia (Espanya Industrial, Sants)</a>, full of FREE workshops, talks and contests for the local Python community and an opportunity to spread the word of its existence to other people that could be interested in Python. - </p> - <h2 class="h3">What is PyDay Barcelona 2018 about?</h2> - <p> - PyDay Barcelona 2018 has the aim of expanding the local Python community. It will be a whole day event, consisting of different level workshops focused on people with a variety of interestss levels and interests. There will be two tracks: beginner and intermediate. Each workshop will be about 80 minutes long. There will be networking opportunities amongst attendees and the sponsoring companies: coffee breaks, open spaces, etc. - </p> - <h2 class="h3">Join the event</h2> - <p> - <a href="https://www.eventbrite.es/e/entradas-pyday-barcelona-2018-50585714233?ref=ebtnebtckt" target="_blank"><img src="https://www.eventbrite.es/custombutton?eid=50585714233" alt="Eventbrite - PyDay Barcelona 2018" /></a> - </p> - <h2 class="h3">Agenda</h2> - <table> - <tbody> - <tr> - <td>09:30</td> - <td colspan="2"><b>Registration & Breakfast</b></td> - </tr> - <tr> - <td>10:00</td> - <td colspan="2">Welcome session - Laura Pérez Mayos</td> - </tr> - <tr> - <td></td> - <td><b>PyBCN Introductory Workshops</b></td> - <td><b>Data and Python Track (I)</b></td> - </tr> - <tr> - <td>10:30</td> - <td>Developing a small application with git - Ignasi Fosch</td> - <td>Introduction to pytorch - Bartek Skorulski</td> - </tr> - <tr> - <td>12:00</td> - <td colspan="2"><b>Coffee break</b></td> - </tr> - <tr> - <td>12:30</td> - <td>Data analysis with Jupyter Notebook, Pandas and Plotly - Natàlia Padilla and Laura Pérez (PyLadiesBCN)</td> - <td>Mirror, mirror on the wall, who is the fairest of them all? (Introduction to OpenCV) - Ismael Benito</td> - </tr> - <tr> - <td>14:00</td> - <td colspan="2"><b>Lunch</b></td> - </tr> - <tr> - <td></td> - <td><b>Web Track</b></td> - <td><b>Data and Python Track (II)</b></td> - </tr> - <tr> - <td>15:00</td> - <td>Python and Elasticsearch - Artur Mindiyarov</td> - <td>Intro to NoSQL DB with PyMongo - Jordi Guix</td> - </tr> - <tr> - <td>16:30</td> - <td>Guillotina - Data framework - Ramon Navarro Bosch</td> - <td>Organizando chistes con NLP - Julio Martínez</td> - </tr> - <tr> - <td>18:00</td> - <td colspan="2">Closing session: Kahoot &- Code Fights Awards</td> - </tr> - </tbody> - </table> - <h3 style="margin-top:10px">Workshops descriptions</h3> - <h4>Developing a small application with git</h4> - <p> - <b>Speaker:</b> Ignasi Fosch (@ignasi-fosch)<br/> - <b>Language:</b> English<br/> - <b>Description:</b> In this workshop, the attendees will participate in collaborative developing a small simple application using git and GitHub for the workflow. The goals of the exercise is to practice some simple concepts about contributing code.<br/> - <b>Level:</b> Beginner<br/> - <b>Requirements:</b> - </p> - <ul> - <li>Git installed</li> - <li>Some virtual environment with Python 3.6 and pytest setup</li> - <li>GitHub account created</li> - </ul> - <h4>Introduction to pytorch</h4> - <p> - <b>Speaker:</b> Bartek Skorulski<br/> - <b>Language:</b> English<br/> - <b>Description:</b> Why is it worth to know pytorch? Pytorch is a machine/deep learning library for python mainly developed by Facebooks’s AI Research Group. SInce pytorch's models are just like other python programs, it quite easy to write and debug them. Hence pytorch is great for research and experiments. Moreover, with new version 1.0, pytorch introduce "script mode" that aims to become also a tool for writing production code. - </p> - <p> - In this short workshop we give a quick and dirty introduction to pytorch. You will have an opportunity to build, train and evaluate few forward feed neural networks. We start with a simple single layer neural networks and finish with convolutional ones.<br/> - <b>Level:</b> Intermediate<br/> - <b>Requirements:</b> - </p> - <ul> - <li>We assume that you are familiar with python, have some basic knowledge about neural network.</li> - <li>You will get the best experience if you bring a notebook with access to python (I'll use version 3.6) with numpy, pandas, jupyter, pytorch, matplotlib, pillow and opencv.</li> - <li><a href="https://bartek-blog.github.io/python/pytorch/conda/2018/11/12/install-pytorch-with-conda.html" target="_blank">Guide to install Pytorch</a>.</li> - </ul> - <h4>Data analysis with Jupyter Notebook, Pandas and Plotly</h4> - <p><b>Speaker:</b> Natàlia Padilla (@nataliasirera) and Laura Pérez (@laura-perez-mayos) (@PyLadiesBCN) <br/> +# The programme of this edition, read from the page the association published +# for it, which this repository keeps frozen at +# static/archives/pybcn.org/pyday-bcn-2018/index.html. Its Agenda table gives +# the time, the track, and the speaker of every session, and its "Workshops +# descriptions" section gives the description, the language, the level, and +# the requirements of each one. Nothing here comes from anywhere else. +# +# Titles and descriptions are copied from that page, typos included: it prints +# "SInce pytorch's models", "Facebooks's AI Research Group", and "a variety of +# interestss levels". +# +# No talk carries a length. The page gives a start time per row and says, in +# prose, that each workshop is "about 80 minutes long". It never prints an end +# time, so none is stored. +# +# The five rows that are not a session are not talks: Registration & Breakfast +# at 09:30, the Welcome session at 10:00, the Coffee break at 12:00, Lunch at +# 14:00, and the Closing session at 18:00. +talks: + - id: developing-a-small-application-with-git + title: "Developing a small application with git" + speakers: [ignasi-fosch] + language: en + type: workshop + description: "In this workshop, the attendees will participate in collaborative developing a small simple application using git and GitHub for the workflow. The goals of the exercise is to practice some simple concepts about contributing code." + - id: introduction-to-pytorch + title: "Introduction to pytorch" + speakers: [bartek-skorulski] + language: en + type: workshop + description: "Why is it worth to know pytorch? Pytorch is a machine/deep learning library for python mainly developed by Facebooks's AI Research Group. SInce pytorch's models are just like other python programs, it quite easy to write and debug them. Hence pytorch is great for research and experiments. Moreover, with new version 1.0, pytorch introduce \"script mode\" that aims to become also a tool for writing production code.\n\nIn this short workshop we give a quick and dirty introduction to pytorch. You will have an opportunity to build, train and evaluate few forward feed neural networks. We start with a simple single layer neural networks and finish with convolutional ones." + - id: data-analysis-with-jupyter-notebook-pandas-and-plotly + title: "Data analysis with Jupyter Notebook, Pandas and Plotly" + speakers: [natalia-padilla, laura-perez-mayos] + language: en + type: workshop + description: "A hands-on session where you will learn how to analyze data with Jupyter Notebook, Pandas and Plotly. This will be a guided workshop, suitable for both experienced users and beginners with an interest in data analysis." + - id: mirror-mirror-on-the-wall-introduction-to-opencv + title: "Mirror, mirror on the wall, who is the fairest of them all? (Introduction to OpenCV)" + speakers: [ismael-benito] + language: en + type: workshop + description: "An introduction to OpenCV for NumPy-Scipy-Matplotlib stack users. Starting with Anaconda pre-compiled versions, specially from Menpo project (https://anaconda.org/menpo/opencv3). Covering inputs and outputs, from basic image handling, such as: 'imread', 'imshow', 'imwrite', etc; to video streams. Some basics in color treatment and thresholding techniques. Also, fundamentals of image warping and cropping. Finally, a small project to be able to find a specific object, for example a QR Code, in a scene and trimmed it." + - id: python-and-elasticsearch + title: "Python and Elasticsearch" + speakers: [artur-mindiyarov] + language: en + type: workshop + description: "Elasticsearch is one of the best open-source, cross-platform, distributed and scalable search engine. In this workshop we are going to learn basics of Elasticsearch and use it to built our own search solution." + # The numbered session plan the page prints between the description and + # the level is not the description, so it stays in the body only. + - id: intro-to-nosql-db-with-pymongo + title: "Intro to NoSQL DB with PyMongo" + speakers: [jordi-guix] + language: en + type: workshop + description: "Learn how to access and manage big data with Python. How to access to DB, basic CRUD operations (Create, Read, Update, Delete) and overview of advance operations. Get the [workshop materials](https://github.com/giffy)." + - id: guillotina-data-framework + title: "Guillotina - Data framework" + speakers: [ramon-navarro-bosch] + language: en + type: workshop + description: "A walkthrough from creating a data REST API with your custom model and structure to an interactive interface to consume and manage it. Security and custom rich object models to create micro-services that handles large volume information. We also will cover how to interact with it to compute models using its internal API and Jupyter." + - id: organizando-chistes-con-nlp + title: "Organizando chistes con NLP" + speakers: [julio-martinez] + language: es + type: workshop + description: "Haciendo un repaso global de diferentes técnicas de NLP clásicas y modernas, vamos a organizar una colección de chistes en castellano. Habrá una introducción general con slides (30 minutos) y luego una serie de ejercicios con un notebook de Jupyter." + +# The page names no room. What it names is the track of each column of the +# agenda table, and the two columns change track after lunch: the left one +# runs the introductory workshops in the morning and the web track in the +# afternoon, the right one the two halves of the data track. These four are +# the headings the table prints, so they are what a talk points at. +rooms: + - id: pybcn-introductory-workshops + name: "PyBCN Introductory Workshops" + - id: data-and-python-track-i + name: "Data and Python Track (I)" + - id: web-track + name: "Web Track" + - id: data-and-python-track-ii + name: "Data and Python Track (II)" + +# The grid, one row per session of the day, in the order the agenda table +# prints it: by time, and then by the column order of rooms above. A slot is +# when and where; the talk it names is what was said. The two were one list +# until this edition was converted, and the eight later editions already carry +# them apart. +# +# level, requirements and installation sit on the slot and not on the talk, +# because they are what the session asked of whoever walked into it. level is +# the one level the frozen page prints under each workshop description, which +# is not the python_level and topic_level pair that the editions from 2020 on +# carry: the source names one level and not two. requirements is a list here +# and a single string on those later editions, because the page prints the +# requirements of a workshop as separate lines. +# +# No slot carries a track_length other than 1: the table runs two columns all +# day and no session spanned both. No slot carries a duration_minutes either, +# because no session has a length to put on it: the page gives a start time +# per row and says, in prose, that each workshop is "about 80 minutes long". +# +# The five rows of the table that are not a session are not slots of this +# list: Registration & Breakfast at 09:30, the Welcome session at 10:00, the +# Coffee break at 12:00, Lunch at 14:00, and the Closing session at 18:00. +# They are in the table the body of this page prints, verbatim, and nothing +# reads them from here. +# +# This page declares no eventTimes, so no grid is rendered from this list. The +# programme a reader sees is that same frozen table. The list is here because +# a photo of the gallery joins to a talk by id, and because the nine photo +# days still to import need one shape for a programme and not two. +agenda: + - start: "10:30" + track_length: 1 + room: pybcn-introductory-workshops + talk: developing-a-small-application-with-git + level: beginner + requirements: + - "Git installed" + - "Some virtual environment with Python 3.6 and pytest setup" + - "GitHub account created" + - start: "10:30" + track_length: 1 + room: data-and-python-track-i + talk: introduction-to-pytorch + level: intermediate + requirements: + - "We assume that you are familiar with python, have some basic knowledge about neural network." + - "You will get the best experience if you bring a notebook with access to python (I'll use version 3.6) with numpy, pandas, jupyter, pytorch, matplotlib, pillow and opencv." + - "[Guide to install Pytorch](https://bartek-blog.github.io/python/pytorch/conda/2018/11/12/install-pytorch-with-conda.html)." + - start: "12:30" + track_length: 1 + room: pybcn-introductory-workshops + talk: data-analysis-with-jupyter-notebook-pandas-and-plotly + level: beginner + # The page prints an "Installation" label under the requirements of + # this one workshop, with two options. Both are kept, under + # installation. + requirements: + - "a laptop + Jupyter + Pandas + Plotly + an appetite for learning!" + installation: + - "Option 1: Install Anaconda https://www.anaconda.com/download/" + - "Option 2: Execute on the terminal: pip install jupyter pandas plotly" + - start: "12:30" + track_length: 1 + room: data-and-python-track-i + talk: mirror-mirror-on-the-wall-introduction-to-opencv + level: intermediate + # The requirements end on a colon: the page then prints a conda block + # and an apt block, which stay in the body of this page and not here. + requirements: + - "A laptop with a Miniconda/Anaconda distribution. You must create an environment:" + - start: "15:00" + track_length: 1 + room: web-track + talk: python-and-elasticsearch + level: intermediate + requirements: + - "Google account to use Google Colaboratory" + - "Knowledge of Python" + - start: "15:00" + track_length: 1 + room: data-and-python-track-ii + talk: intro-to-nosql-db-with-pymongo + level: beginner + # The page prints "(to be announced)" and then announces three + # requirements under it. Both halves are what the source says. + requirements: + - "(to be announced)" + - "Laptop with Internet access" + - "Google Account with access to Google Drive (to use Google Colab)" + - "Web browser" + - start: "16:30" + track_length: 1 + room: web-track + talk: guillotina-data-framework + level: intermediate + requirements: + - "Docker with elasticsearch, postgres and redis images" + - "Python packages: guillotina, guillotina_elasticsearch, guillotina_rediscache" + - "https://github.com/guillotinaweb/guillotina_processing repo downloaded and docker image built" + - start: "16:30" + track_length: 1 + room: data-and-python-track-ii + talk: organizando-chistes-con-nlp + level: intermediate + requirements: + - "Python 3" + - "jupyter" + - "scikit-learn" + - "spacy (with Spanish model installed)" + +# The index of sections in the sidebar, like every other edition. +layout: event +--- +<p> +We are excited and glad to announce that we are organizing the second edition of PyDay in Barcelona! +</p> +<p> +PyDay Barcelona 2018 is going to take place on <b>November 24th</b> at <a href="https://goo.gl/maps/Ngk6PbN3FuB2" target="_blank">PuntMultimèdia (Espanya Industrial, Sants)</a>, full of FREE workshops, talks and contests for the local Python community and an opportunity to spread the word of its existence to other people that could be interested in Python. +</p> +<h2 class="h3">What is PyDay Barcelona 2018 about?</h2> +<p> +PyDay Barcelona 2018 has the aim of expanding the local Python community. It will be a whole day event, consisting of different level workshops focused on people with a variety of interestss levels and interests. There will be two tracks: beginner and intermediate. Each workshop will be about 80 minutes long. There will be networking opportunities amongst attendees and the sponsoring companies: coffee breaks, open spaces, etc. +</p> +<h2 class="h3">Join the event</h2> +<p> +<a href="https://www.eventbrite.es/e/entradas-pyday-barcelona-2018-50585714233?ref=ebtnebtckt" target="_blank"><img src="https://www.eventbrite.es/custombutton?eid=50585714233" alt="Eventbrite - PyDay Barcelona 2018" /></a> +</p> +<h2 class="h3">Agenda</h2> +<table> +<tbody> +<tr> +<td>09:30</td> +<td colspan="2"><b>Registration & Breakfast</b></td> +</tr> +<tr> +<td>10:00</td> +<td colspan="2">Welcome session - Laura Pérez Mayos</td> +</tr> +<tr> +<td></td> +<td><b>PyBCN Introductory Workshops</b></td> +<td><b>Data and Python Track (I)</b></td> +</tr> +<tr> +<td>10:30</td> +<td>Developing a small application with git - Ignasi Fosch</td> +<td>Introduction to pytorch - Bartek Skorulski</td> +</tr> +<tr> +<td>12:00</td> +<td colspan="2"><b>Coffee break</b></td> +</tr> +<tr> +<td>12:30</td> +<td>Data analysis with Jupyter Notebook, Pandas and Plotly - Natàlia Padilla and Laura Pérez (PyLadiesBCN)</td> +<td>Mirror, mirror on the wall, who is the fairest of them all? (Introduction to OpenCV) - Ismael Benito</td> +</tr> +<tr> +<td>14:00</td> +<td colspan="2"><b>Lunch</b></td> +</tr> +<tr> +<td></td> +<td><b>Web Track</b></td> +<td><b>Data and Python Track (II)</b></td> +</tr> +<tr> +<td>15:00</td> +<td>Python and Elasticsearch - Artur Mindiyarov</td> +<td>Intro to NoSQL DB with PyMongo - Jordi Guix</td> +</tr> +<tr> +<td>16:30</td> +<td>Guillotina - Data framework - Ramon Navarro Bosch</td> +<td>Organizando chistes con NLP - Julio Martínez</td> +</tr> +<tr> +<td>18:00</td> +<td colspan="2">Closing session: Kahoot &- Code Fights Awards</td> +</tr> +</tbody> +</table> +<h2 style="margin-top:10px">Workshops descriptions</h2> +<h3>Developing a small application with git</h3> +<p> +<b>Speaker:</b> Ignasi Fosch (@ignasi-fosch)<br/> +<b>Language:</b> English<br/> +<b>Description:</b> In this workshop, the attendees will participate in collaborative developing a small simple application using git and GitHub for the workflow. The goals of the exercise is to practice some simple concepts about contributing code.<br/> +<b>Level:</b> Beginner<br/> +<b>Requirements:</b> +</p> +<ul> +<li>Git installed</li> +<li>Some virtual environment with Python 3.6 and pytest setup</li> +<li>GitHub account created</li> +</ul> +<h3>Introduction to pytorch</h3> +<p> +<b>Speaker:</b> Bartek Skorulski<br/> +<b>Language:</b> English<br/> +<b>Description:</b> Why is it worth to know pytorch? Pytorch is a machine/deep learning library for python mainly developed by Facebooks’s AI Research Group. SInce pytorch's models are just like other python programs, it quite easy to write and debug them. Hence pytorch is great for research and experiments. Moreover, with new version 1.0, pytorch introduce "script mode" that aims to become also a tool for writing production code. +</p> +<p> +In this short workshop we give a quick and dirty introduction to pytorch. You will have an opportunity to build, train and evaluate few forward feed neural networks. We start with a simple single layer neural networks and finish with convolutional ones.<br/> +<b>Level:</b> Intermediate<br/> +<b>Requirements:</b> +</p> +<ul> +<li>We assume that you are familiar with python, have some basic knowledge about neural network.</li> +<li>You will get the best experience if you bring a notebook with access to python (I'll use version 3.6) with numpy, pandas, jupyter, pytorch, matplotlib, pillow and opencv.</li> +<li><a href="https://bartek-blog.github.io/python/pytorch/conda/2018/11/12/install-pytorch-with-conda.html" target="_blank">Guide to install Pytorch</a>.</li> +</ul> +<h3>Data analysis with Jupyter Notebook, Pandas and Plotly</h3> +<p><b>Speaker:</b> Natàlia Padilla (@nataliasirera) and Laura Pérez (@laura-perez-mayos) (@PyLadiesBCN) <br/> <b>Language:</b> English<br/> <b>Description:</b> A hands-on session where you will learn how to analyze data with Jupyter Notebook, Pandas and Plotly. This will be a guided workshop, suitable for both experienced users and beginners with an interest in data analysis.<br/> <b>Level:</b> Beginner<br/> <b>Requirements:</b> a laptop + Jupyter + Pandas + Plotly + an appetite for learning!<br/> <b>Installation:</b><br/> -• Option 1: Install Anaconda <a href="https://www.anaconda.com/download/" target="_blank">https://www.anaconda.com/download/</a><br/> +• Option 1: Install Anaconda <a href="https://www.anaconda.com/download/" target="_blank">anaconda.com/download</a><br/> • Option 2: Execute on the terminal: pip install jupyter pandas plotly</p> -<h4>Mirror, mirror on the wall, who is the fairest of them all? (Introduction to OpenCV)</h4> +<h3>Mirror, mirror on the wall, who is the fairest of them all? (Introduction to OpenCV)</h3> <p><b>Speaker:</b> Ismael Benito (@ismansiete)<br/> <b>Language:</b> English<br/> <b>Description:</b> An introduction to OpenCV for NumPy-Scipy-Matplotlib stack users. Starting with Anaconda pre-compiled versions, specially from Menpo project (<a href="https://anaconda.org/menpo/opencv3" target="_blank">https://anaconda.org/menpo/opencv3</a>). Covering inputs and outputs, from basic image handling, such as: 'imread', 'imshow', 'imwrite', etc; to video streams. Some basics in color treatment and thresholding techniques. Also, fundamentals of image warping and cropping. Finally, a small project to be able to find a specific object, for example a QR Code, in a scene and trimmed it.<br/> @@ -139,7 +337,7 @@ pip install pyzbar qrcode scikit-video <pre><code>apt install -y libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev libswscale-dev apt install -y libtbb2 libtbb-dev libjpeg-dev libpng-dev libtiff-dev libjasper-dev libdc1394-22-dev </code></pre> -<h4>Python and Elasticsearch</h4> +<h3>Python and Elasticsearch</h3> <p><b>Speaker:</b> Artur Mindiyarov <br/> <b>Language:</b> English<br/> <b>Description:</b> Elasticsearch is one of the best open-source, cross-platform, distributed and scalable search engine. In this workshop we are going to learn basics of Elasticsearch and use it to built our own search solution.<br/> @@ -149,7 +347,7 @@ apt install -y libtbb2 libtbb-dev libjpeg-dev libpng-dev libtiff-dev libjasper-d <li>Google account to use Google Colaboratory</li> <li>Knowledge of Python</li> </ul> -<h4>Intro to NoSQL DB with PyMongo</h4> +<h3>Intro to NoSQL DB with PyMongo</h3> <p><b>Speaker:</b> Jordi Guix<br/> <b>Language:</b> English<br/> <b>Description:</b> Learn how to access and manage big data with Python. How to access to DB, basic CRUD operations (Create, Read, Update, Delete) and overview of advance operations.<br/> @@ -188,7 +386,7 @@ Get the <a href="https://github.com/giffy" target="_blank">workshop materials</a <li>Google Account with access to Google Drive (to use Google Colab)</li> <li>Web browser</li> </ul> -<h4>Guillotina - Data framework</h4> +<h3>Guillotina - Data framework</h3> <p><b>Speaker:</b> Ramon Navarro Bosch (@bloodbare)<br/> <b>Language:</b> English<br/> <b>Description:</b> A walkthrough from creating a data REST API with your custom model and structure to an interactive interface to consume and manage it. Security and custom rich object models to create micro-services that handles large volume information. We also will cover how to interact with it to compute models using its internal API and Jupyter.<br/> @@ -199,7 +397,7 @@ Get the <a href="https://github.com/giffy" target="_blank">workshop materials</a <li>Python packages: guillotina, guillotina_elasticsearch, guillotina_rediscache</li> <li><a href="https://github.com/guillotinaweb/guillotina_processing" target="_blank">https://github.com/guillotinaweb/guillotina_processing</a> repo downloaded and docker image built</li> </ul> -<h4>Organizando chistes con NLP</h4> +<h3>Organizando chistes con NLP</h3> <p><b>Speaker:</b> Julio Martínez (@liopic)<br/> <b>Language:</b> Spanish<br/> <b>Description:</b> Haciendo un repaso global de diferentes técnicas de NLP clásicas y modernas, vamos a organizar una colección de chistes en castellano. Habrá una introducción general con slides (30 minutos) y luego una serie de ejercicios con un notebook de Jupyter.<br/> @@ -212,16 +410,11 @@ Get the <a href="https://github.com/giffy" target="_blank">workshop materials</a <li>spacy (with Spanish model installed)</li> </ul> <h2>Sponsors</h2> -<p>Do you want to sponsor this event? -Contact us at <a href="mailto:pyday-bcn-2018@googlegroups.com">pyday-bcn-2018@googlegroups.com</a>.</p> <h2 class="h3">Platinum</h2> -<p><img src="/archives/pybcn.org/pyday-bcn-2018/kiwicom.png" style="height: 150px; margin-right: 20px;"> -<img src="/archives/pybcn.org/pyday-bcn-2018/onna.png" style="height: 140px"></p> +<p><img src="/archives/pybcn.org/pyday-bcn-2018/kiwicom.png" style="height: 150px; margin-right: 20px;" alt="Kiwicom logo"> +<img src="/archives/pybcn.org/pyday-bcn-2018/onna.png" style="height: 140px" alt="Onna logo"></p> <h2 class="h3">Gold</h2> -<p><img src="/archives/pybcn.org/pyday-bcn-2018/kernel_analytics.png" height="80" style="margin-right: 20px; height: 80px; margin-bottom: 10px;"> -<img src="/archives/pybcn.org/pyday-bcn-2018/travelperk.png" style="height: 80px"> -<img src="/archives/pybcn.org/pyday-bcn-2018/kschool.png" style="height: 80px; margin-right: 20px"> -<img src="/archives/pybcn.org/pyday-bcn-2018/psf.png" style="height: 80px"></p> - </div> - </div> - </div> +<p><img src="/archives/pybcn.org/pyday-bcn-2018/kernel_analytics.png" height="80" style="margin-right: 20px; height: 80px; margin-bottom: 10px;" alt="Kernel Analytics logo"> +<img src="/archives/pybcn.org/pyday-bcn-2018/travelperk.png" style="height: 80px" alt="TravelPerk logo"> +<img src="/archives/pybcn.org/pyday-bcn-2018/kschool.png" style="height: 80px; margin-right: 20px" alt="KSchool logo"> +<img src="/archives/pybcn.org/pyday-bcn-2018/psf.png" style="height: 80px" alt="Python Software Foundation logo"></p> diff --git a/content/events/pyday_bcn/pyday_bcn_2019.md b/content/events/pyday_bcn/pyday_bcn_2019.md index c0e2b490b..bc207c687 100644 --- a/content/events/pyday_bcn/pyday_bcn_2019.md +++ b/content/events/pyday_bcn/pyday_bcn_2019.md @@ -1,19 +1,244 @@ --- title: "PyDay BCN (2019)" year: 2019 +# The day of this edition, from the Meetup export, which records it per event. +date: 2019-11-16 +# The venue of this edition, from the Meetup export, which records it per event. +venue: "Universitat de Barcelona" description: "" menu: main: parent: 'PyDay BCN' weight: 7 heroBackground: /images/photos/people-pyday-2019.jpg ---- -<div class="container"> - <div class="row main_content"> - <div class="col-md-9 main_column"> - <p><strong>This event has ended!</strong> You can see some photos <a href="https://drive.google.com/drive/folders/1kODXtBARnTbZmQwVW1Qx2EvBCDSqhZjX?usp=sharing" target="_blank">here</a>.</p> -<p><img src="/archives/pybcn.org/pyday-bcn-2019/Foto%20de%20grup%20-%20small.jpg" style="width:100%"/></p> +# This page is on layouts/_default/event.html, like the editions from 2020 +# on, so it gets the sticky index of sections down the left of the page. It +# was on layouts/_default/single.html, which renders the body and the +# gallery and nothing else, so the page had no way to jump to its own +# gallery. The index lists what this file declares: About the event, and +# Gallery. There is no Schedule entry, because the grid needs eventTimes +# and numTracks and this page carries neither (see the comment on agenda below). PyDay BCN 2016 and 2018 +# are still on single.html and still have no index. +layout: event + +# The programme of this edition, read from the printed agenda that the live +# thread on X photographed (tweet 1195637939285430272, the photo on this page). +# The Google Calendar embed that held it is gone, and the Meetup description +# never carried it, so that photograph is the source. Titles are copied from +# the sheets, typos included: the sheets print "Decoradores en evolucion" and +# "Un caso practico" without their accents. +# +# The sheets name no speaker at all. The four that are named here come from the +# thread, which announced them. The other eleven are unknown, and that is what +# the source says. The caption of one photo credits the handle @bustawin for +# SQLAlchemy from 0 to proficient, but a handle is not a name, so that talk +# carries no speaker until somebody says who it is. +talks: + # The two keynotes. The printed sheets announce the opening one in all three + # tracks and give it no title, and the closing one is not on them at all: the + # thread tweeted it at 20:03, well after the 18:30 the sheets end at. David + # Arcos supplied both titles, which is why they are plain and not quoted. + - id: opening-keynote + title: "Opening keynote" + speakers: [laura-perez-mayos] + type: keynote + source: "https://x.com/PyBCN/status/1195623896537554944" + - id: closing-keynote + title: "Closing keynote" + speakers: [david-arcos] + type: keynote + source: "https://x.com/PyBCN/status/1195779452829097984" + - id: arquitectura-limpia-para-microservicios + title: "Arquitectura limpia para microservicios: Un caso practico" + duration_minutes: 90 + language: es + type: workshop + source: "https://x.com/PyBCN/status/1195638580137406464" + - id: fast-bayesian-ab-and-multivariate-testing + title: "Fast Bayesian A/B and multivariate testing" + duration_minutes: 45 + language: en + type: talk + - id: tell-me-why + title: "Tell me Why" + duration_minutes: 90 + language: en + type: workshop + - id: tips-for-optimize-django-database-queries + title: "Tips for optimize Django database queries" + duration_minutes: 90 + language: en + type: workshop + - id: deep-learning-for-image-classification-using-tensorflow + title: "Deep Learning for Image Classification using TensorFlow" + duration_minutes: 75 + language: en + type: workshop + source: "https://x.com/PyBCN/status/1195638268727042051" + - id: decoradores-en-evolucion + title: "Decoradores en evolucion" + duration_minutes: 60 + language: es + type: workshop + source: "https://x.com/PyBCN/status/1195662968203153410" + - id: the-magic-of-pyspark + title: "The magic of PySpark" + duration_minutes: 105 + language: en + type: workshop + - id: sqlalchemy-from-0-to-proficient + title: "SQLAlchemy from 0 to proficient" + duration_minutes: 90 + language: en + type: workshop + source: "https://x.com/PyBCN/status/1195729652893077504" + - id: migracode + title: "Migracode: the first code school for youth migrants and refugees in Barcelona" + duration_minutes: 30 + language: en + type: talk + - id: keep-your-repo-clean + title: "Keep your repo clean" + speakers: [hector-canto] + duration_minutes: 45 + language: es + type: talk + source: "https://x.com/PyBCN/status/1195639258599563264" + - id: refactoring-a-web-application-with-python + title: "Refactoring a Web Application with Python" + duration_minutes: 90 + language: en + type: workshop + source: "https://x.com/PyBCN/status/1195663218259243010" + - id: building-interactive-data-visualizations-with-plotly-and-dash + title: "Building Interactive Data Visualizations with Plotly and Dash" + speakers: [anna-fedotova] + duration_minutes: 90 + language: en + type: workshop + source: "https://x.com/PyBCN/status/1195729247731630080" + - id: quick-data-exploration-with-jupyter-and-ipywidgets + title: "Quick data exploration with Jupyter and ipywidgets" + duration_minutes: 90 + language: en + type: workshop + source: "https://x.com/PyBCN/status/1195729783734202368" + +# The rooms the sheets name. Three parallel tracks, one level each. +rooms: + - id: b6 + name: "B6" + track: Advanced + - id: b5 + name: "B5" + track: Intermediate + - id: b3 + name: "B-3" + track: Beginner + +# The grid, one row per session of the day, in the order the sheets print it: +# by time, and then by the track order of rooms above. A slot is when and +# where; the talk it names is what was said. The two were one list until this +# edition was converted, and the eight later editions already carry them +# apart. +# +# level is the one level the sheets give a session, which is the level of its +# track. It is not the python_level and topic_level pair that the editions +# from 2020 on carry, because the source names one level and not two. +# +# No slot carries a track_length other than 1: the three tracks ran in +# parallel all day and no session spanned two of them. +# +# The hand-drawn arrow on the sheet swapped the two B5 slots, 10:00 and +# 16:30. The comment that records it is on both of them, where the time it +# corrects now lives. +# +# This page declares no eventTimes, so no grid is rendered from this list. +# The programme a reader sees is the Google Calendar embed in the body, which +# is what the association published. The list is here because a photo of the +# gallery joins to a talk by id, and because the nine photo days still to +# import need one shape for a programme and not two. +agenda: + # The sheets print the opening keynote in all three tracks at 9:30, so it is + # one slot across the grid. The closing keynote has no slot: it is not on + # them, and the thread gives the time of the tweet, not of the session. + - start: "9:30" + track_length: 3 + room: b6 + talk: opening-keynote + - start: "10:00" + track_length: 1 + room: b6 + talk: arquitectura-limpia-para-microservicios + level: advanced + - start: "10:00" + track_length: 1 + room: b5 + talk: deep-learning-for-image-classification-using-tensorflow + # The printed sheet has these two the other way round, with a hand-drawn + # arrow swapping them. The thread confirms the arrow, not the print. + level: intermediate + - start: "10:00" + track_length: 1 + room: b3 + talk: migracode + level: beginner + - start: "10:30" + track_length: 1 + room: b3 + talk: keep-your-repo-clean + level: beginner + - start: "12:00" + track_length: 1 + room: b6 + talk: fast-bayesian-ab-and-multivariate-testing + level: advanced + - start: "12:00" + track_length: 1 + room: b5 + talk: decoradores-en-evolucion + level: intermediate + - start: "12:00" + track_length: 1 + room: b3 + talk: refactoring-a-web-application-with-python + level: beginner + - start: "14:30" + track_length: 1 + room: b6 + talk: tell-me-why + level: advanced + - start: "14:30" + track_length: 1 + room: b5 + talk: the-magic-of-pyspark + level: intermediate + - start: "14:30" + track_length: 1 + room: b3 + talk: building-interactive-data-visualizations-with-plotly-and-dash + level: beginner + - start: "16:30" + track_length: 1 + room: b6 + talk: tips-for-optimize-django-database-queries + level: advanced + - start: "16:30" + track_length: 1 + room: b5 + talk: sqlalchemy-from-0-to-proficient + # The printed sheet has these two the other way round, with a hand-drawn + # arrow swapping them. The thread confirms the arrow, not the print. + level: intermediate + - start: "16:30" + track_length: 1 + room: b3 + talk: quick-data-exploration-with-jupyter-and-ipywidgets + level: beginner + +--- +<p><img src="/archives/pybcn.org/pyday-bcn-2019/Foto%20de%20grup%20-%20small.jpg" style="width:100%" alt="The group photograph of PyDay BCN 2019, in the cloister of the Universitat de Barcelona" /></p> <h2>Archived content</h2> <p>We are excited to announce that we are organizing the third edition of PyDay in Barcelona!</p> <p>PyDay Barcelona 2019 is going to take place on <strong>November 16th</strong> <em>fgin Universitat de Barcelona</em>, a full day full of FREE python-related activities for the Python community. Over the last two editions, PyDay has become a great opportunity to share our love for Python and engage users, companies and newcomers into it!</p> @@ -34,36 +259,33 @@ heroBackground: /images/photos/people-pyday-2019.jpg <h2>Sponsors</h2> <h3>Venue</h3> <center> -<img src="/archives/pybcn.org/pyday-bcn-2019/ub.jpg" style="width: 350px; margin: 20px 20px auto;"> -<img src="/archives/pybcn.org/pyday-bcn-2019/psf.png" style="width: 350px; margin: 20px 20px auto;"> +<img src="/archives/pybcn.org/pyday-bcn-2019/ub.jpg" style="width: 350px; margin: 20px 20px auto;" alt="Universitat de Barcelona logo"> +<img src="/archives/pybcn.org/pyday-bcn-2019/psf.png" style="width: 350px; margin: 20px 20px auto;" alt="Python Software Foundation logo"> </center><h3>Platinum</h3> <center> -<img src="/archives/pybcn.org/pyday-bcn-2019/upcloud.png" style="width: 180px; margin: 20px 20px auto;"> -<img src="/archives/pybcn.org/pyday-bcn-2019/kiwicom.png" style="width: 150px; margin: 20px 20px auto;"> -<img src="/archives/pybcn.org/pyday-bcn-2019/invisiblebits.png" style="width: 180px; margin: 20px 20px auto;"> -<img src="/archives/pybcn.org/pyday-bcn-2019/chartboost.png" style="width: 180px; margin: 20px 20px auto;"> -<img src="/archives/pybcn.org/pyday-bcn-2019/king.png" style="width: 130px; margin: 20px 20px auto;"> -<img src="/archives/pybcn.org/pyday-bcn-2019/qustodio.png" style="width: 190px; margin: 20px 20px auto;"> +<img src="/archives/pybcn.org/pyday-bcn-2019/upcloud.png" style="width: 180px; margin: 20px 20px auto;" alt="UpCloud logo"> +<img src="/archives/pybcn.org/pyday-bcn-2019/kiwicom.png" style="width: 150px; margin: 20px 20px auto;" alt="Kiwi.com logo"> +<img src="/archives/pybcn.org/pyday-bcn-2019/invisiblebits.png" style="width: 180px; margin: 20px 20px auto;" alt="Invisible Bits logo"> +<img src="/archives/pybcn.org/pyday-bcn-2019/chartboost.png" style="width: 180px; margin: 20px 20px auto;" alt="Chartboost logo"> +<img src="/archives/pybcn.org/pyday-bcn-2019/king.png" style="width: 130px; margin: 20px 20px auto;" alt="King logo"> +<img src="/archives/pybcn.org/pyday-bcn-2019/qustodio.png" style="width: 190px; margin: 20px 20px auto;" alt="Qustodio logo"> </center><h3>Coffee Sponsor</h3> <center> -<img src="/archives/pybcn.org/pyday-bcn-2019/affectv.png" style="width: 100px; margin: 20px 20px auto;"> +<img src="/archives/pybcn.org/pyday-bcn-2019/affectv.png" style="width: 100px; margin: 20px 20px auto;" alt="Affectv logo"> </center><h3>Gold</h3> <center> -<img src="/archives/pybcn.org/pyday-bcn-2019/thoughtworks.png" style="width: 150px; margin: 20px 0px auto;"> -<img src="/archives/pybcn.org/pyday-bcn-2019/bmat.png" style="width: 70px; margin: 20px 20px auto;"> -<img src="/archives/pybcn.org/pyday-bcn-2019/holaluz.png" style="width: 80px; margin: 20px 20px auto;"> +<img src="/archives/pybcn.org/pyday-bcn-2019/thoughtworks.png" style="width: 150px; margin: 20px 0px auto;" alt="ThoughtWorks logo"> +<img src="/archives/pybcn.org/pyday-bcn-2019/bmat.png" style="width: 70px; margin: 20px 20px auto;" alt="BMAT logo"> +<img src="/archives/pybcn.org/pyday-bcn-2019/holaluz.png" style="width: 80px; margin: 20px 20px auto;" alt="Holaluz logo"> <br /> -<img src="/archives/pybcn.org/pyday-bcn-2019/travelperk.png" style="width: 150px; margin: 20px 20px auto;"> -<img src="/archives/pybcn.org/pyday-bcn-2019/elastic.png" style="width: 110px; margin: 20px 10px auto;"> -<img src="/archives/pybcn.org/pyday-bcn-2019/verse.png" style="width: 110px; margin: 20px 20px auto;"> +<img src="/archives/pybcn.org/pyday-bcn-2019/travelperk.png" style="width: 150px; margin: 20px 20px auto;" alt="TravelPerk logo"> +<img src="/archives/pybcn.org/pyday-bcn-2019/elastic.png" style="width: 110px; margin: 20px 10px auto;" alt="Elastic logo"> +<img src="/archives/pybcn.org/pyday-bcn-2019/verse.png" style="width: 110px; margin: 20px 20px auto;" alt="Verse logo"> <br /> -<img src="/archives/pybcn.org/pyday-bcn-2019/fundacion-ci.jpg" style="width: 110px; margin: 20px 20px auto;"> +<img src="/archives/pybcn.org/pyday-bcn-2019/fundacion-ci.jpg" style="width: 110px; margin: 20px 20px auto;" alt="Fundación Cibervoluntarios logo"> </center><h3>Silver</h3> <center> -<img src="/archives/pybcn.org/pyday-bcn-2019/kschool.png" style="width: 100px; margin: 20px 20px auto;"> -<img src="/archives/pybcn.org/pyday-bcn-2019/satellogic.png" style="width: 100px; margin: 20px 20px auto;"> -<img src="/archives/pybcn.org/pyday-bcn-2019/blueliv.png" style="width: 100px; margin: 20px 20px auto;"> +<img src="/archives/pybcn.org/pyday-bcn-2019/kschool.png" style="width: 100px; margin: 20px 20px auto;" alt="KSchool logo"> +<img src="/archives/pybcn.org/pyday-bcn-2019/satellogic.png" style="width: 100px; margin: 20px 20px auto;" alt="Satellogic logo"> +<img src="/archives/pybcn.org/pyday-bcn-2019/blueliv.png" style="width: 100px; margin: 20px 20px auto;" alt="Blueliv logo"> </center> - </div> - </div> - </div> From 143c093f07070e25300bd81a66c620d50f71ab0d Mon Sep 17 00:00:00 2001 From: David Arcos <david.arcos@gmail.com> Date: Thu, 15 Oct 2026 10:01:16 +0200 Subject: [PATCH 6/7] PyDay BCN 2016: the sponsors through the grid, and the day of every edition MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PyDay BCN 2016 named its eleven sponsors in prose, five of them with no record and no logo. The five get a record under content/sponsors/ (AtlaSense, Claranet, MongoDB, Punt Multimèdia, Schibsted Spain) and a logo under the theme assets, and the page lists all eleven through sponsor_levels, the grid every other edition uses. The logos of the two whose host no longer answers still link to the site the sponsor paid for: a host that does not answer today is a fact about that host, and the record of what was agreed is not ours to drop (David Arcos, 2026-10-14). The page also carries its three days, 15 to 17 September 2016, and its venue, and takes layouts/_default/event.html so the sponsors render. Hacktoberfest 2018 gets its day, 21 October 2018, its venue, Kernel Analytics, and its four organizers from the frozen copy of the site of the day under static/archives/hacktoberfestbarcelona.com/, which the menu entry of the page already pointed at. An earlier comment on the page said no source gave the day; the source was the page this one links to. No agenda, on purpose: the frozen page lists hours and names no speaker and no talk, so a programme would invent a grid the day did not have. --- .../events/other_events/hacktoberfest_2018.md | 31 +++++- content/events/pyday_bcn/pyday_bcn_2016.md | 103 +++++++++++------- content/sponsors/atlasense.md | 6 + content/sponsors/claranet.md | 6 + content/sponsors/mongodb.md | 6 + content/sponsors/punt-multimedia.md | 6 + content/sponsors/schibsted-spain.md | 6 + .../assets/images/sponsors/atlasense.png | Bin 0 -> 13052 bytes .../assets/images/sponsors/claranet.png | Bin 0 -> 9444 bytes .../assets/images/sponsors/mongodb.png | Bin 0 -> 11811 bytes .../images/sponsors/punt-multimedia.png | Bin 0 -> 10993 bytes .../images/sponsors/schibsted-spain.png | Bin 0 -> 9479 bytes 12 files changed, 126 insertions(+), 38 deletions(-) create mode 100644 content/sponsors/atlasense.md create mode 100644 content/sponsors/claranet.md create mode 100644 content/sponsors/mongodb.md create mode 100644 content/sponsors/punt-multimedia.md create mode 100644 content/sponsors/schibsted-spain.md create mode 100644 themes/pybcn_theme/assets/images/sponsors/atlasense.png create mode 100644 themes/pybcn_theme/assets/images/sponsors/claranet.png create mode 100644 themes/pybcn_theme/assets/images/sponsors/mongodb.png create mode 100644 themes/pybcn_theme/assets/images/sponsors/punt-multimedia.png create mode 100644 themes/pybcn_theme/assets/images/sponsors/schibsted-spain.png diff --git a/content/events/other_events/hacktoberfest_2018.md b/content/events/other_events/hacktoberfest_2018.md index 0ab3d45bb..85b17ecd8 100644 --- a/content/events/other_events/hacktoberfest_2018.md +++ b/content/events/other_events/hacktoberfest_2018.md @@ -1,10 +1,39 @@ --- title: "Hacktoberfest (2018)" year: 2018 -description: "" +# The day, the venue, and the organizers come from the frozen copy of the +# site of the day, static/archives/hacktoberfestbarcelona.com/, which the +# menu entry below already points at. Its title line reads "Hacktoberfest +# BCN | 21 October 2018, Barcelona", and the page names Kernel Analytics +# at Balmes 89 as the place and the four people below as the organizers. +# An earlier comment here said no source gave the day. It was wrong: the +# source was the page this one links to. +heroBackground: /archives/hacktoberfestbarcelona.com/images/backgrounds/bg7.jpg +layout: event +date: 2018-10-21 +venue: "Kernel Analytics" +description: "Hacktoberfest is an annual event across the world to encourage developers to contribute to open source projects. Join us, give back to open source and meet fellow open source enthusiasts." + +# No agenda, on purpose. The frozen page lists hours (a welcome talk and +# breakfast at 10.00, project pitches at 10.15, a tutorial for beginners +# at 10.30, and work from 10.45) but names no speaker and no talk. Writing +# that as a programme would invent a grid the day did not have, so the +# frozen page keeps it and this one links there. +people_sections: + - title: Organizers + id: organizers + levels: + - people_per_line: 4 + people: + - giorgio-polvara + - ignasi-fosch + - israel-saeta-perez + - laura-perez-mayos menu: main: parent: 'Other events' url: https://pybcn.org/archives/hacktoberfestbarcelona.com/ weight: 2 --- + +The site of the day is kept frozen in this repository, with the full agenda, the sponsors, and the frequently asked questions as they were published: [Hacktoberfest BCN 2018](/archives/hacktoberfestbarcelona.com/). diff --git a/content/events/pyday_bcn/pyday_bcn_2016.md b/content/events/pyday_bcn/pyday_bcn_2016.md index dd0c53521..ae602519b 100644 --- a/content/events/pyday_bcn/pyday_bcn_2016.md +++ b/content/events/pyday_bcn/pyday_bcn_2016.md @@ -1,12 +1,78 @@ --- title: "PyDay BCN (2016)" year: 2016 +# The first day of this edition, from the Meetup export, which records it per +# event. The edition ran two days: the XXL meetup on Thursday 15 and the +# workshop day on Saturday 17, with nothing on the Friday between them. +date: 2016-09-15 +# The last day of this edition. The archived site under /archives/ gives it: +# "September 17th, Saturday" on its PyDay page. The photographs agree: the ids +# of the four posts of the photos block decode (X snowflake epoch) to 19:14, +# 19:44, and 20:29 on Thursday 15, and the fourth to Friday 16 at 13:20, +# saying "See you tomorrow in our workshops!". The Friday post is the one +# outside the first day; the day it points at is the Saturday. +end_date: 2016-09-17 +# The venue of this edition, from the Meetup export, which records it per event. +venue: "Universitat de Barcelona" description: "" menu: main: parent: 'PyDay BCN' weight: 9 + +# The index of sections in the sidebar, like every other edition. +layout: event heroBackground: /images/photos/people-pyday-2016.jpg + +# The sponsors and collaborators of the edition, as the archived site under +# /archives/pybcn.org/pyday-bcn-2016/ lists them, by its own levels and in its +# own order, each resolved to a record of content/sponsors/. Five of the +# eleven had no record and were named in sponsors_text until 2026-10-14: +# Punt Multimèdia, Claranet, Schibsted Spain, AtlaSense, and MongoDB. Their +# records carry the name as the archived page writes it, the @320 logo of +# the archived page, and its site over https (bin/check-content rejects an +# http site). The hosts of Schibsted Spain and AtlaSense no longer resolve +# (measured 2026-10-14); check-content says a site that does not answer +# over https is for its owner to fix, so the link stays. The venue level +# follows the 2025 page, which lists Canòdrom among the organizers. This +# edition has no programme: the archive holds none, and bin/check-content +# notes the gap. +sponsors_text: | + The sponsors and collaborators of the first PyDay, by the levels of the archived site of the edition. Also on the archived site: + + - [The sponsorship offer of PyDay BCN 2016](/archives/pybcn.org/pyday-bcn-2016/sponsorship.html) + - [Backend Developer at BMAT Music Innovation, a job offer of a sponsor](/archives/pybcn.org/pyday-bcn-2016/bmat-music-innovation/backend-developer.html) +sponsor_levels: + - name: Venues + sponsors_per_line: 3 + sponsors: + - punt-multimedia + - ub + - name: Platinum + sponsors_per_line: 2 + sponsors: + - psf + - claranet + - name: Gold + sponsors_per_line: 2 + sponsors: + - schibsted-spain + - bmat + - name: Silver + sponsors_per_line: 3 + sponsors: + - atlasense + - name: Collaborators + sponsors_per_line: 3 + sponsors: + - skyscanner + - mongodb + - name: Thanks to + sponsors_per_line: 3 + sponsors: + - pyladiesbcn + - pythones + --- We are excited and glad to announce that we are organizing our first big event related to Python. @@ -17,40 +83,3 @@ We count with an incredible group of volunteers, sponsors, and contributing enti Thanks to all them. We really hope you'll have a great time attending to these!! - -## {{< icon "fa-rocket" >}} Sponsors and collaborators {#sponsors-and-collaborators} - -### {{< icon "fa-university" >}} Venues {#venues} - -- [![Punt Multimèdia](/archives/pybcn.org/pyday-bcn-2016/punt-multimedia/punt_multimedia_logo@320.png)](/archives/pybcn.org/pyday-bcn-2016/punt-multimedia/index.html) -- [![Facultat de Matemàtiques i Informàtia of Universitat de Barcelona](/archives/pybcn.org/pyday-bcn-2016/facultat-matematiques-informatica/universitat_barcelona@320.png)](/archives/pybcn.org/pyday-bcn-2016/facultat-matematiques-informatica/index.html) - -### {{< icon "fa-certificate" >}} Platinum {#platinum} - -- [![Python Software Foundation](/archives/pybcn.org/pyday-bcn-2016/python-software-foundation/python-software-foundation-logo@320.png)](/archives/pybcn.org/pyday-bcn-2016/python-software-foundation/index.html) -- [![Claranet](/archives/pybcn.org/pyday-bcn-2016/claranet/claranet_logo@320.png)](/archives/pybcn.org/pyday-bcn-2016/claranet/index.html) - -### {{< icon "fa-certificate" >}} Gold {#gold} - -- [![Schibsted Spain](/archives/pybcn.org/pyday-bcn-2016/schibsted-spain/schibsted_logo@320.png)](/archives/pybcn.org/pyday-bcn-2016/schibsted-spain/index.html) -- [![BMAT Music Innovation](/archives/pybcn.org/pyday-bcn-2016/bmat-music-innovation/logo-bmat@320.png)](/archives/pybcn.org/pyday-bcn-2016/bmat-music-innovation/index.html) - -### {{< icon "fa-certificate" >}} Silver {#silver} - -- [![AtlaSense](/archives/pybcn.org/pyday-bcn-2016/atlasense/atlasense_logo@320.png)](/archives/pybcn.org/pyday-bcn-2016/atlasense/index.html) - -### {{< icon "fa-cube" >}} Collaborators {#collaborators} - -- [![Skyscanner](/archives/pybcn.org/pyday-bcn-2016/skyscanner/skyscanner_logo@160.png)](/archives/pybcn.org/pyday-bcn-2016/skyscanner/index.html) -- [![MongoDB](/archives/pybcn.org/pyday-bcn-2016/mongodb/mongodb_logo@160.png)](/archives/pybcn.org/pyday-bcn-2016/mongodb/index.html) - -### {{< icon "fa-thumbs-up" >}} Thanks to ... {#thanks-to} - -- [![PyLadies BCN](/archives/pybcn.org/pyday-bcn-2016/pyladies-bcn/pyladieslogo@160.png)](/archives/pybcn.org/pyday-bcn-2016/pyladies-bcn/index.html) -- [![Asociación Python España](/archives/pybcn.org/pyday-bcn-2016/asociacion-python-espana/python-espana-logo@160.png)](/archives/pybcn.org/pyday-bcn-2016/asociacion-python-espana/index.html) - -### [Willing to see your company here?](/archives/pybcn.org/pyday-bcn-2016/sponsorship.html) {#sponsorship} - -## {{< icon "fa-industry" >}} Job Offers from our sponsors {#job-offers} - -- [Backend Developer at BMAT Music Innovation](/archives/pybcn.org/pyday-bcn-2016/bmat-music-innovation/backend-developer.html) diff --git a/content/sponsors/atlasense.md b/content/sponsors/atlasense.md new file mode 100644 index 000000000..9a16d3a32 --- /dev/null +++ b/content/sponsors/atlasense.md @@ -0,0 +1,6 @@ +--- +id: atlasense +name: AtlaSense +logo_image: atlasense.png +site: https://atlasense.com +--- diff --git a/content/sponsors/claranet.md b/content/sponsors/claranet.md new file mode 100644 index 000000000..50879b805 --- /dev/null +++ b/content/sponsors/claranet.md @@ -0,0 +1,6 @@ +--- +id: claranet +name: Claranet +logo_image: claranet.png +site: https://www.claranet.es +--- diff --git a/content/sponsors/mongodb.md b/content/sponsors/mongodb.md new file mode 100644 index 000000000..15356a58d --- /dev/null +++ b/content/sponsors/mongodb.md @@ -0,0 +1,6 @@ +--- +id: mongodb +name: MongoDB +logo_image: mongodb.png +site: https://mongodb.com +--- diff --git a/content/sponsors/punt-multimedia.md b/content/sponsors/punt-multimedia.md new file mode 100644 index 000000000..c59d8a9da --- /dev/null +++ b/content/sponsors/punt-multimedia.md @@ -0,0 +1,6 @@ +--- +id: punt-multimedia +name: Punt Multimèdia +logo_image: punt-multimedia.png +site: https://www.puntmultimedia.org +--- diff --git a/content/sponsors/schibsted-spain.md b/content/sponsors/schibsted-spain.md new file mode 100644 index 000000000..f3f0c1efa --- /dev/null +++ b/content/sponsors/schibsted-spain.md @@ -0,0 +1,6 @@ +--- +id: schibsted-spain +name: Schibsted Spain +logo_image: schibsted-spain.png +site: https://www.schibsted.es +--- diff --git a/themes/pybcn_theme/assets/images/sponsors/atlasense.png b/themes/pybcn_theme/assets/images/sponsors/atlasense.png new file mode 100644 index 0000000000000000000000000000000000000000..4fa4c70bb96624d42f259ae302354d8fb1c65335 GIT binary patch literal 13052 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 H9r?ciSK>Ss literal 0 HcmV?d00001 diff --git a/themes/pybcn_theme/assets/images/sponsors/claranet.png b/themes/pybcn_theme/assets/images/sponsors/claranet.png new file mode 100644 index 0000000000000000000000000000000000000000..a931e9de55eddca24f1adba1bbaceb96164bcc72 GIT binary patch literal 9444 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 M4LwM`njPYQ03SxPn*aa+ literal 0 HcmV?d00001 diff --git a/themes/pybcn_theme/assets/images/sponsors/mongodb.png b/themes/pybcn_theme/assets/images/sponsors/mongodb.png new file mode 100644 index 0000000000000000000000000000000000000000..5d402d2cf5c97d9f2bb90748b5dbb0e60abf2181 GIT binary patch literal 11811 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 literal 0 HcmV?d00001 diff --git a/themes/pybcn_theme/assets/images/sponsors/punt-multimedia.png b/themes/pybcn_theme/assets/images/sponsors/punt-multimedia.png new file mode 100644 index 0000000000000000000000000000000000000000..e4031b290387493dac64b990573da4e53742c9d3 GIT binary patch literal 10993 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 Cd+%ld literal 0 HcmV?d00001 diff --git a/themes/pybcn_theme/assets/images/sponsors/schibsted-spain.png b/themes/pybcn_theme/assets/images/sponsors/schibsted-spain.png new file mode 100644 index 0000000000000000000000000000000000000000..e029d71478e122ebeef1e0d5802538c353fa2b2f GIT binary patch literal 9479 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 T7s`}<G5}~n^wsNBZR7qAw%)xn literal 0 HcmV?d00001 From 535cb9f50bd1da457b5c7bb3b53183b7b0c8fdbe Mon Sep 17 00:00:00 2001 From: David Arcos <david.arcos@gmail.com> Date: Thu, 15 Oct 2026 10:01:16 +0200 Subject: [PATCH 7/7] Check the schedule a page declares, and the dates of its days bin/check-content reads the three lists the pages carry now, because the join between them fails in silence: a slot that names a talk the page does not define renders as an empty block, which looks like a gap in the programme and not like a mistake. What it rejects: a page that still carries events, the model agenda and talks replaced; a room with no id or no name, or an id used twice; a talk with no type or an unknown one, a language that is not en, es or ca, a list of languages in another order, a duration that is not a whole number, a link with no type or no address, and the free-text speaker field; a speaker id with no record behind it; a talk id used twice in one file, which leaves the second talk unreachable; a slot whose start is not a quoted H:MM string (YAML 1.1 reads an unquoted 9:00 as the integer 540), with no track_length, naming a room or a talk the page does not declare, or with no talk and no type or length of its own. It also checks end_date: it is a date, date is there too, and end_date is later than date, because the date partial treats an end_date it cannot use as absent and a two day edition turns back into one day in silence. A talk with no speaker is a warning, not an error, with a count per page: the source of PyDay BCN 2019 names nobody for 11 of its 15 sessions, and a count that grows is the sign that a source was read carelessly. The speakers of a talk count as a listing for the orphan check, so a person credited by a programme and by no people block is no longer reported. The summary line counts the talks and the pages that declare them: 168 talks on 11 pages in this tree. AGENTS.md says what the three lists are and that a time is a quoted string, and CONTRIBUTING.md adds end_date to what the check fails on. --- AGENTS.md | 22 ++- CONTRIBUTING.md | 2 +- bin/check-content | 441 ++++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 429 insertions(+), 36 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 6ad0e87a0..b818be14d 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -93,6 +93,26 @@ problem somebody else has to find. the talk and meetup records. Writing them into a person's front matter guarantees they will eventually contradict the data. +**A programme is two lists, not one.** An event page carries `agenda` (the grid: +`start`, `track_length`, `room`, and either a `talk` id or its own `label` and +`type`), `talks` (the content: `title`, `speaker`, `description`, `language`, +`topic`, `duration_minutes`, `links`), and `rooms` (`id` and `name`). They are +separate because one talk can take several slots, and because a photo of the +gallery links to a talk by id, which a row of a grid cannot give it. The colour +of a block and the end of a slot are computed, not stored: see +`partials/agenda_entry.html`. **A time is always a quoted string.** YAML 1.1 +reads an unquoted `9:00` as the integer 540, sexagesimal, so Hugo renders it +right and every Python checker reads a number. + +**`language` takes `en`, `es` or `ca`,** or a list of them for a session given in +two. It was free text and carried seven spellings of those three languages, +which is how one page printed both `Catalan` and `Català`. **A list is written +in that order, `en`, `es`, `ca`.** The archive held `[en, es]` once and +`[es, en]` three times for the same pair, and the page printed "English / +Spanish" and "Spanish / English", because `partials/agenda_entry.html` prints +the codes in the order the list gives them. `bin/check-content` rejects any +other order. + **A person attribution requires human verification.** Talk records carry `source` and `confidence`. **Only a human-verified record may create a person page or link a speaker name.** A record with `confidence: medium` or `low` renders the @@ -184,7 +204,7 @@ The checks, which are what a pull request has to pass: | Script | What it rejects | |---|---| -| `bin/check-content` | A broken reference, a photo that is not square, a source far larger than the build asks for, a field that no longer exists | +| `bin/check-content` | A broken reference, a photo that is not square, a source far larger than the build asks for, a field that no longer exists, an `end_date` that is not a date or not later than `date` | | `bin/check-html-safety` | Dangerous raw HTML in content, with an allowlist for the legitimate embeds | | `bin/check-rendered` | The same, on the built pages, plus any `http://` URL. Run it against a directory you built, never against `public/` while a dev server is writing there | diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7eb00b302..2b1c2ab52 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -150,7 +150,7 @@ What each check is for: | Check | Fails when | |---|---| | Build the site | Hugo cannot build, or emits a warning | -| `bin/check-content` | Front matter does not parse, a person `id` does not match its filename, an id is duplicated, a declared photo is missing, an event references a person or sponsor that does not exist, a social URL has the wrong shape, or a field is empty. It warns, without failing, about a photo that is too small or has no colour | +| `bin/check-content` | Front matter does not parse, a person `id` does not match its filename, an id is duplicated, a declared photo is missing, an event references a person or sponsor that does not exist, a social URL has the wrong shape, a field is empty, or an `end_date` is not later than `date`. It warns, without failing, about a photo that is too small or has no colour | | `bin/check-html-safety` | Content carries raw HTML that turns a content change into script execution, a redirect, a credential prompt, or a page overlay. See [Content safety check](README.md#content-safety-check) | | `bin/check-rendered` | The built pages carry that same markup, which catches a template that produces it even when no content file does, or they link to anything over `http`. See [Rendered page check](README.md#rendered-page-check) | | `bin/canon.py --selftest` | The one normalization of imported text stops being idempotent, or changes what it strips | diff --git a/bin/check-content b/bin/check-content index 96ccba572..ccbd6fb37 100755 --- a/bin/check-content +++ b/bin/check-content @@ -6,6 +6,10 @@ match its filename, a duplicate id, a page that lists a person or sponsor id with no page behind it, a declared photo with no file behind it, and a remote photo_url. It warns about a person photo with no colour in it. +For the days it checks end_date, which an event carries when it ran more +than one day: it is a date, and it is later than date. The template prints +one day for an end_date it cannot use, so the mistake is silent on the page. + Exit code 1 if any error is found. Warnings do not fail the build. Usage: @@ -270,6 +274,94 @@ def report_small(small): f"the grid. Smallest: {shown}. Replacing the file is the only fix.") +_talk_ids = {} + + +def talk_ids_of(path, data, people): + """Return the talk ids of one page, reporting a duplicate or a bad speaker. + + A photo finds its talk by id inside its own file, and so does a slot of + the agenda, so two talks under one id leave the second unreachable: every + photo of it shows the title of the first, and so does every slot. + + This used to run from check_gallery only, which skips a page with no + photos block. Two of the ten files that carry a programme have one, so + the speaker ids of 21 talks were checked and the other 113 were not, and + those 113 were exactly the ones that needed it: they credited a speaker + as free text, which an id check cannot see at all. The walk now runs for + every page that declares talks, from check_agenda, and check_gallery asks + it for the ids it needs. The result is kept per path so the two callers + report each mistake once. + """ + if path in _talk_ids: + return _talk_ids[path] + talks = data.get("talks") or [] + if not talks: + # Not kept: there is nothing to report twice, and a page with no + # programme would otherwise count towards the coverage figure below. + return set() + talk_ids = set() + unnamed = [] + for position, talk in enumerate(talks, start=1): + if not isinstance(talk, dict): + error(path, f"'talks' holds {talk!r} at position {position}, " + f"which is not a talk") + continue + talk_id = talk.get("id") + title = talk.get("title") or talk_id or f"position {position}" + if talk_id in talk_ids: + error(path, f"talk '{title}' repeats the id '{talk_id}', which an " + f"earlier talk of this file already uses. A photo " + f"points at a talk by id, so the second talk is " + f"unreachable. Give it an id of its own.") + elif talk_id: + talk_ids.add(talk_id) + + # speaker, singular, was free text: one string with the names of + # everyone who gave the talk. No template reads it any more, so a + # file that still carries one shows no speaker at all on the block + # and in the modal, and the id check below never sees those names. + if "speaker" in talk: + error(path, f"talk '{title}' carries 'speaker' " + f"{talk['speaker']!r}, the free-text field that " + f"'speakers' replaced. Nothing renders it, so the " + f"block and the modal credit nobody. Use speakers, a " + f"list of ids of content/people/.") + + speakers = talk.get("speakers") or [] + if not speakers: + unnamed.append(title) + for ref in speakers: + if not isinstance(ref, str): + error(path, f"talk '{title}' lists {ref!r} as a speaker, " + f"which is not an id") + elif ref not in people: + error(path, f"talk '{title}' lists unknown speaker id " + f"'{ref}'. Add content/people/{ref}.md, or fix " + f"the id: the gallery prints an id it cannot " + f"find as the id with its hyphens taken out.") + report_unnamed(path, unnamed, talks) + _talk_ids[path] = talk_ids + return talk_ids + + +def report_unnamed(path, unnamed, talks): + """A talk with no speaker is correct when the source names nobody. + + It is still worth a figure on every run. The printed agenda of PyDay BCN + 2019 names no speaker at all, and the thread announced only some of the + sessions, so eleven of its fifteen talks credit nobody and a reader of + the gallery sees the title alone. A count that grows is the sign that a + source was read carelessly. + """ + if not unnamed: + return + shown = ", ".join(f"'{title}'" for title in unnamed[:3]) + warn(path, f"no speaker for {len(unnamed)} of the {len(talks)} talks, so " + f"a photo of one of them shows the title alone: {shown}. " + f"Correct when the source names nobody.") + + # One form per network, so a reader of the files can tell at a glance that two # links point at the same place, and so nobody has to wonder whether # es.linkedin.com and www.linkedin.com are the same profile. The hosts are the @@ -557,6 +649,12 @@ def check_listings(people, sponsors): pages were listed by name, so a rename switched that check off in silence. Returns the set of person ids that some page lists, for the orphan check. + The speakers of the talks count: a talk credits a person by id, the page + prints the name of that person record on the block and in the detail + modal, and partials/appearances_index.html gives the person that event as + an appearance. The ids themselves are checked in check_talk_ids, which + reports an unknown one with the title of its talk, so this walk only + collects the ones that resolve. """ listed_people = set() for path in sorted(CONTENT.rglob("*.md")): @@ -573,49 +671,321 @@ def check_listings(people, sponsors): error(path, f"'{key}' references unknown {noun} id '{ref}'") elif kind == "people": listed_people.add(ref) + for talk in data.get("talks") or []: + if not isinstance(talk, dict): + continue + for ref in talk.get("speakers") or []: + if isinstance(ref, str) and ref in people: + listed_people.add(ref) return listed_people -# The colour classes agenda.scss defines for an entry of the schedule. The -# entry's color value lands in the class attribute as it is, so a missing or -# misspelt value gets the fallback background instead of a brand colour. -AGENDA_COLOURS = {"blue", "green", "grey", "orange", "pink", "purple", "red", "yellow"} +# The types partials/event_types.html knows. A slot that holds no talk names +# its own type, and an unknown one renders no icon and only warns at build +# time, which nobody reads. +ENTRY_TYPES = {"workshop", "talk", "lightning", "keynote", "panel", "group", + "coffee", "lunch", "photo", "qa"} + +# The closed vocabulary of the language field. It used to be free text and +# carried seven spellings of these three languages. +# +# A list, for a session given in two languages, is written in this order. The +# archive held "en, es" once and "es, en" three times for the same pair, and +# the page printed "English / Spanish" and "Spanish / English" for it, because +# partials/agenda_entry.html prints the codes in the order the list gives +# them. The order below is the one AGENTS.md and the label table of that +# partial already declare, so there is one order and not two. +LANGUAGE_ORDER = ("en", "es", "ca") +LANGUAGES = set(LANGUAGE_ORDER) + + +def check_agenda(people): + """Check the schedule of an event page: its rooms, its talks, its grid. + + The page carries the grid (agenda) apart from the content (talks), + joined by a talk id, and that join fails in silence: a slot that names a + talk the page does not define renders as an empty block, which looks + like a gap in the programme and not like a mistake. + + The colour of a block is no longer checked here, because it is no longer + in the content. partials/agenda_entry.html gives every room of an event + one colour of the palette agenda.scss defines. The old check demanded a + colour on every entry, which is how the archive ended up with 157 of + them that meant nothing. + """ + for path in sorted(CONTENT.rglob("*.md")): + data = front_matter(path) + if data is None: + continue + if data.get("events"): + error(path, "carries 'events', the schedule model that 'agenda' " + "and 'talks' replaced. The template no longer reads " + "it, so the whole schedule of this page is missing " + "from the built site.") + rooms = check_rooms(path, data) + talks = check_talks(path, data, people) + for position, slot in enumerate(data.get("agenda") or [], start=1): + check_slot(path, position, slot, rooms, talks) + + +def check_rooms(path, data): + """Return the room ids of one page, reporting a missing or repeated id.""" + found = set() + for position, room in enumerate(data.get("rooms") or [], start=1): + if not isinstance(room, dict): + error(path, f"'rooms' holds {room!r} at position {position}, " + f"which is not a room") + continue + room_id = room.get("id") + if not room_id: + error(path, f"room {position} has no id. A slot of the agenda " + f"names its room by id, and the colour of the block " + f"comes from it.") + elif room_id in found: + error(path, f"room {position} repeats the id '{room_id}'. Two " + f"records under one id leave the second unreachable.") + else: + found.add(room_id) + if not str(room.get("name") or "").strip(): + error(path, f"room '{room_id}' has no name. The name is what the " + f"block of the grid prints.") + return found -def check_agenda(): - """Every entry of a schedule must carry one of the agenda colour classes.""" - for path in sorted(CONTENT.rglob("*.md")): +def check_talks(path, data, people): + """Return the talk ids of one page, checking the fields the grid reads.""" + found = talk_ids_of(path, data, people) + for position, talk in enumerate(data.get("talks") or [], start=1): + if not isinstance(talk, dict): + continue # talk_ids_of already reports this one + talk_id = talk.get("id") + title = talk.get("title") or talk_id or f"position {position}" + language = talk.get("language") + codes = [language] if isinstance(language, str) else language or [] + for code in codes: + if code not in LANGUAGES: + error(path, f"talk '{title}' has language '{code}'. Use " + f"{', '.join(LANGUAGE_ORDER)}, or a list of " + f"them for a session given in two.") + known = [code for code in codes if code in LANGUAGES] + if len(known) > 1: + expected = [code for code in LANGUAGE_ORDER if code in known] + if known != expected: + error(path, f"talk '{title}' lists its languages as " + f"{known}. A list is written in the order " + f"{list(LANGUAGE_ORDER)}, because the page prints " + f"the codes in the order the list gives them: two " + f"orders print the same pair two ways. Use " + f"{expected}.") + if talk.get("type") not in ENTRY_TYPES: + error(path, f"talk '{title}' has type '{talk.get('type')}', which " + f"is not one of: {', '.join(sorted(ENTRY_TYPES))}") + # Optional: the printed programme of PyDay BCN 2018 gives no length + # at all, so none of its talks stores one. A value that is there has + # to be a number, because the end of the slot is computed from it. + if "duration_minutes" in talk and not isinstance(talk["duration_minutes"], int): + error(path, f"talk '{title}' has duration_minutes " + f"{talk['duration_minutes']!r}, which is not a whole " + f"number of minutes. The end of the slot is computed " + f"from it.") + check_links(path, f"talk '{title}'", talk.get("links")) + return found + + +def check_links(path, label, links): + for position, link in enumerate(links or [], start=1): + if not isinstance(link, dict): + error(path, f"{label} holds {link!r} as link {position}, which " + f"is not a link") + continue + if not str(link.get("url") or "").startswith("http"): + error(path, f"{label} has link {position} with url " + f"{link.get('url')!r}, which is not an address") + if not link.get("type"): + error(path, f"{label} has link {position} with no type. Only a " + f"video gets its own line on the block; everything " + f"else is listed under Repository.") + + +def as_date(value): + """The date a front matter value holds, or None when it holds none. + + An unquoted 2016-09-17 arrives as a date from the YAML parser, a quoted + one as a string, and a value with a time as a datetime. Hugo reads all + three the same way, so all three count. + """ + if isinstance(value, datetime.datetime): + return value.date() + if isinstance(value, datetime.date): + return value + if isinstance(value, str): + try: + return datetime.date.fromisoformat(value.strip()) + except ValueError: + return None + return None + + +def check_dates(): + """An event that ran more than one day carries end_date, its last day. + + date is the first day and end_date the last, both YAML dates, and + partials/event_date.html prints the two as one range. The partial + treats an end_date that is not after date as absent, so a mistake in + the key turns a two day edition back into one day in silence: the page + builds and reads right. This says it: when end_date is there, it is a + date, date is there too, and end_date is strictly later than date. A + one day event has no end_date at all. + + Report, never crash: a value that is not a date is an error with the + value in it, and the rest of the check runs. + """ + for path in sorted((CONTENT / "events").rglob("*.md")): data = front_matter(path) - if data is None or not data.get("events"): + if data is None or "end_date" not in data: continue - for entry in data["events"]: - if not isinstance(entry, dict): - error(path, f"'events' holds {entry!r}, which is not an entry") - continue - colour = entry.get("color") - title = entry.get("title") or entry.get("speaker") or "?" - if not colour: - error(path, f"agenda entry '{title}' has no color; use one of: " - f"{', '.join(sorted(AGENDA_COLOURS))}") - elif colour not in AGENDA_COLOURS: - error(path, f"agenda entry '{title}' has color '{colour}', which is " - f"not one of: {', '.join(sorted(AGENDA_COLOURS))}") + raw_end = data["end_date"] + end = as_date(raw_end) + if end is None: + error(path, f"end_date is {raw_end!r}, which is not a date. Write " + f"the last day of the event as YYYY-MM-DD, or remove " + f"the key for an event of one day.") + continue + raw_start = data.get("date") + start = as_date(raw_start) + if start is None: + error(path, f"end_date {end} needs a date to be the end of, and " + f"date is {raw_start!r}. Write the first day as " + f"YYYY-MM-DD.") + continue + if end == start: + error(path, f"end_date {end} is the same day as date. An event of " + f"one day carries no end_date: remove the key.") + elif end < start: + error(path, f"end_date {end} is before date {start}. end_date is " + f"the last day of the event, so it is later than " + f"date.") + + +def check_slot(path, position, slot, rooms, talks): + """Check one row of the grid: where it sits, and what fills it.""" + if not isinstance(slot, dict): + error(path, f"'agenda' holds {slot!r} at position {position}, which " + f"is not a slot") + return + where = f"agenda slot {position}" + start = slot.get("start") + # An unquoted 9:00 is the integer 540 in YAML 1.1, sexagesimal. Hugo's + # parser reads it as a string and the page looks right, so nothing but + # this says the value is not what the file appears to hold. + if not isinstance(start, str) or not re.fullmatch(r"\d{1,2}:\d{2}", start): + error(path, f"{where} has start {start!r}. A start is a quoted H:MM " + f"string: YAML 1.1 reads an unquoted 9:00 as the integer " + f"540.") + else: + where = f"agenda slot {position} ({start})" + if not isinstance(slot.get("track_length"), int): + error(path, f"{where} has track_length " + f"{slot.get('track_length')!r}, which is not a number of " + f"tracks. The block spans that many columns.") + room = slot.get("room") + if room is not None and room not in rooms: + known = ", ".join(sorted(rooms)) or "none" + error(path, f"{where} names room '{room}', which this page does not " + f"declare. Use one of: {known}.") + talk = slot.get("talk") + if talk is not None and talk not in talks: + known = ", ".join(sorted(talks)) or "none" + error(path, f"{where} names talk '{talk}', which this page does not " + f"declare. The block renders empty, which reads as a gap " + f"in the programme. Use one of: {known}.") + if slot.get("speaker") is not None: + error(path, f"{where} carries 'speaker' {slot['speaker']!r}, the " + f"free-text field that 'speakers' replaced. Nothing " + f"renders it. Use speakers, a list of ids of " + f"content/people/, or leave the slot with none: the " + f"organising committee of an edition is not a person.") + if talk is None: + if slot.get("type") not in ENTRY_TYPES: + error(path, f"{where} holds no talk and has type " + f"{slot.get('type')!r}. A slot with no talk is a row " + f"of the day and names its own type, one of: " + f"{', '.join(sorted(ENTRY_TYPES))}") + if not isinstance(slot.get("duration_minutes"), int): + error(path, f"{where} holds no talk and has duration_minutes " + f"{slot.get('duration_minutes')!r}. With no talk to " + f"read it from, the slot carries its own length.") + check_links(path, where, slot.get("links")) + + +# What a row of /people/ can show about a person, apart from the name: the +# photo, the social links, the position, and the body of the file. A record +# with none of the four, and with no page crediting it either, is a row of a +# bare name. See themes/pybcn_theme/layouts/people/list.html. +PERSON_CONTENT_FIELDS = ("photo", "github", "linkedin", "twitter", "site", + "pybcn_position") + + +def body(path): + """The text under the front matter, which is the bio of a person file.""" + text = path.read_text(encoding="utf-8").lstrip("") + match = FRONT_MATTER.match(text) + return (text[match.end():] if match else text).strip() def check_orphans(people, listed_people): - """A person page no listing points at renders, but nobody can reach it. - - The check compares against the ids check_listings collected from the - front matter keys, so only a real listing counts. The old check searched - the text of every page with a word-boundary regex, and a regex boundary - sits between a letter and a hyphen: 'ricardo' matched inside - 'ricardo-ander-egg' and 'jordi' inside 'jordi-bosch', so those two pages - passed with no listing at all. Prose that happens to contain an id does - not count as a reference either. + """A person record the site publishes and can say nothing about. + + This used to report a person no listing points at, because the page of + that person rendered and nothing linked to it. That is no longer the + state: /people/ lists every file of the section, so every record has an + inbound link and a row by being in the folder, and the row links to the + page of the person, /people/<id>/, which came back with the Archive + (config.toml has the history). Being unlisted no longer hides a record; + it only empties its row and its page. + + So the error this looks for now is a row with nothing in it: no page + credits the record, and the file carries no photo, no social link, no + position, and no bio. The name is then the whole row, which is a + published claim that this person was part of the association with + nothing behind it. Either the programme that names them is missing, and + crediting the talk fixes the row, or the file is a leftover and goes. + + The uncredited records are reported together as one note, not one + warning each. They are not a defect of the file: most of them hold a + photo, a bio, or both, and what is missing is the page that says where + they served. One line names them all, so a reader sees the shape of the + gap instead of a line per record that each says a part of it. + + listed_people is the set check_listings collected from the front matter + keys and from the speakers of the talks, so only a real listing counts. + A page that carries a programme and no people_sections, PyData Barcelona + 2017, PyDay BCN 2018, or PyDay BCN 2019, reaches its speakers through + the talks alone. An earlier version searched the text of every page with + a word-boundary regex, and a regex boundary sits between a letter and a + hyphen: 'ricardo' matched inside 'ricardo-ander-egg' and 'jordi' inside + 'jordi-bosch', so those two pages passed with no listing at all. Prose + that happens to contain an id does not count as a reference either. """ - for page_id, path in people.items(): - if page_id not in listed_people: - warn(path, f"person '{page_id}' is not listed by any event or page") + uncredited = [] + for page_id, path in sorted(people.items()): + if page_id in listed_people: + continue + uncredited.append(page_id) + data = front_matter(path) or {} + if any(data.get(field) for field in PERSON_CONTENT_FIELDS): + continue + if body(path): + continue + warn(path, f"person '{page_id}' holds a name and nothing else, and no " + f"event or page credits it, so its row on /people/ is the " + f"name alone. Credit the talk or the page the person " + f"belongs to, or delete the file.") + if uncredited: + note(f"{len(uncredited)} person records are credited by no event and " + f"no page, so their row on /people/ and their own page carry no " + f"role, no year and no event: {', '.join(uncredited)}. A record is credited by the " + f"people block of a page, or by the speakers of a talk.") SECURITY_TXT = ROOT / "static" / ".well-known" / "security.txt" @@ -700,7 +1070,8 @@ def main(): check_social(people, sponsors) check_sources() listed_people = check_listings(people, sponsors) - check_agenda() + check_agenda(people) + check_dates() check_orphans(people, listed_people) check_security_txt() check_association() @@ -710,7 +1081,9 @@ def main(): for line in errors: print(f"ERROR {line}") - print(f"\n{len(people)} people, {len(sponsors)} sponsors checked.") + talks = sum(len(ids) for ids in _talk_ids.values()) + print(f"\n{len(people)} people, {len(sponsors)} sponsors, " + f"{talks} talks on {len(_talk_ids)} pages checked.") print(f"{len(errors)} errors, {len(warnings)} warnings.") return 1 if errors else 0