refactor: restructure monorepo for clean portfolio layout

- Move timesfm-forecast into apps/ directory
- Flatten Udacity portfolio projects from deep URL-encoded paths
  into data-engineering/01-XX numbered directories
- Remove old My-Data-Engineering-Portifolio/ parent directory
- Rewrite root README.md: professional overview with badges,
  project table, and repo structure diagram
- Create data-engineering/README.md with per-project descriptions
- Add README.md for 02-cassandra-modeling (was missing)
- Add README.md for 05-airflow-pipelines (was missing)
- Normalize capstone readme.md -> README.md
- Update .gitignore: add *.cfg, *.env, *.zip, *.sas7bdat,
  Jupyter checkpoints, IDE dirs; remove uv.lock exclusion
- Add dwh.cfg.example and dl.cfg.example credential templates
- Untrack real credential files (dwh.cfg, dl.cfg)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@gabriel.pereira
2026-03-26 16:48:50 -03:00
parent 5c4e6075e1
commit 6796398924
160 changed files with 308 additions and 34 deletions

View File

@@ -0,0 +1,694 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"editable": true
},
"outputs": [],
"source": [
"%load_ext sql"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"editable": true
},
"outputs": [
{
"data": {
"text/plain": [
"'Connected: student@sparkifydb'"
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%sql postgresql://student:student@127.0.0.1/sparkifydb"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"editable": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" * postgresql://student:***@127.0.0.1/sparkifydb\n",
"5 rows affected.\n"
]
},
{
"data": {
"text/html": [
"<table>\n",
" <tr>\n",
" <th>songplay_id</th>\n",
" <th>start_time</th>\n",
" <th>user_id</th>\n",
" <th>level</th>\n",
" <th>song_id</th>\n",
" <th>artist_id</th>\n",
" <th>session_id</th>\n",
" <th>location</th>\n",
" <th>user_agent</th>\n",
" </tr>\n",
" <tr>\n",
" <td>0</td>\n",
" <td>2018-11-30 12:22:07</td>\n",
" <td>91</td>\n",
" <td>free</td>\n",
" <td>None</td>\n",
" <td>None</td>\n",
" <td>829</td>\n",
" <td>Dallas-Fort Worth-Arlington, TX</td>\n",
" <td>Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)</td>\n",
" </tr>\n",
" <tr>\n",
" <td>1</td>\n",
" <td>2018-11-30 01:08:41</td>\n",
" <td>73</td>\n",
" <td>paid</td>\n",
" <td>None</td>\n",
" <td>None</td>\n",
" <td>1049</td>\n",
" <td>Tampa-St. Petersburg-Clearwater, FL</td>\n",
" <td>&quot;Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_4) AppleWebKit/537.78.2 (KHTML, like Gecko) Version/7.0.6 Safari/537.78.2&quot;</td>\n",
" </tr>\n",
" <tr>\n",
" <td>2</td>\n",
" <td>2018-11-30 01:12:48</td>\n",
" <td>73</td>\n",
" <td>paid</td>\n",
" <td>None</td>\n",
" <td>None</td>\n",
" <td>1049</td>\n",
" <td>Tampa-St. Petersburg-Clearwater, FL</td>\n",
" <td>&quot;Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_4) AppleWebKit/537.78.2 (KHTML, like Gecko) Version/7.0.6 Safari/537.78.2&quot;</td>\n",
" </tr>\n",
" <tr>\n",
" <td>3</td>\n",
" <td>2018-11-30 01:17:05</td>\n",
" <td>73</td>\n",
" <td>paid</td>\n",
" <td>None</td>\n",
" <td>None</td>\n",
" <td>1049</td>\n",
" <td>Tampa-St. Petersburg-Clearwater, FL</td>\n",
" <td>&quot;Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_4) AppleWebKit/537.78.2 (KHTML, like Gecko) Version/7.0.6 Safari/537.78.2&quot;</td>\n",
" </tr>\n",
" <tr>\n",
" <td>4</td>\n",
" <td>2018-11-30 01:20:56</td>\n",
" <td>73</td>\n",
" <td>paid</td>\n",
" <td>None</td>\n",
" <td>None</td>\n",
" <td>1049</td>\n",
" <td>Tampa-St. Petersburg-Clearwater, FL</td>\n",
" <td>&quot;Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_4) AppleWebKit/537.78.2 (KHTML, like Gecko) Version/7.0.6 Safari/537.78.2&quot;</td>\n",
" </tr>\n",
"</table>"
],
"text/plain": [
"[(0, datetime.datetime(2018, 11, 30, 12, 22, 7), 91, 'free', 'None', 'None', 829, 'Dallas-Fort Worth-Arlington, TX', 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)'),\n",
" (1, datetime.datetime(2018, 11, 30, 1, 8, 41), 73, 'paid', 'None', 'None', 1049, 'Tampa-St. Petersburg-Clearwater, FL', '\"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_4) AppleWebKit/537.78.2 (KHTML, like Gecko) Version/7.0.6 Safari/537.78.2\"'),\n",
" (2, datetime.datetime(2018, 11, 30, 1, 12, 48), 73, 'paid', 'None', 'None', 1049, 'Tampa-St. Petersburg-Clearwater, FL', '\"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_4) AppleWebKit/537.78.2 (KHTML, like Gecko) Version/7.0.6 Safari/537.78.2\"'),\n",
" (3, datetime.datetime(2018, 11, 30, 1, 17, 5), 73, 'paid', 'None', 'None', 1049, 'Tampa-St. Petersburg-Clearwater, FL', '\"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_4) AppleWebKit/537.78.2 (KHTML, like Gecko) Version/7.0.6 Safari/537.78.2\"'),\n",
" (4, datetime.datetime(2018, 11, 30, 1, 20, 56), 73, 'paid', 'None', 'None', 1049, 'Tampa-St. Petersburg-Clearwater, FL', '\"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_4) AppleWebKit/537.78.2 (KHTML, like Gecko) Version/7.0.6 Safari/537.78.2\"')]"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%sql SELECT * FROM songplays LIMIT 5;"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"editable": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" * postgresql://student:***@127.0.0.1/sparkifydb\n",
"1 rows affected.\n"
]
},
{
"data": {
"text/html": [
"<table>\n",
" <tr>\n",
" <th>count</th>\n",
" </tr>\n",
" <tr>\n",
" <td>532</td>\n",
" </tr>\n",
"</table>"
],
"text/plain": [
"[(532,)]"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%sql SELECT count(*) FROM songplays"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"editable": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" * postgresql://student:***@127.0.0.1/sparkifydb\n",
"5 rows affected.\n"
]
},
{
"data": {
"text/html": [
"<table>\n",
" <tr>\n",
" <th>user_id</th>\n",
" <th>first_name</th>\n",
" <th>last_name</th>\n",
" <th>gender</th>\n",
" <th>level</th>\n",
" </tr>\n",
" <tr>\n",
" <td>92</td>\n",
" <td>Ryann</td>\n",
" <td>Smith</td>\n",
" <td>F</td>\n",
" <td>free</td>\n",
" </tr>\n",
" <tr>\n",
" <td>57</td>\n",
" <td>Katherine</td>\n",
" <td>Gay</td>\n",
" <td>F</td>\n",
" <td>free</td>\n",
" </tr>\n",
" <tr>\n",
" <td>86</td>\n",
" <td>Aiden</td>\n",
" <td>Hess</td>\n",
" <td>M</td>\n",
" <td>free</td>\n",
" </tr>\n",
" <tr>\n",
" <td>74</td>\n",
" <td>Braden</td>\n",
" <td>Parker</td>\n",
" <td>M</td>\n",
" <td>free</td>\n",
" </tr>\n",
" <tr>\n",
" <td>30</td>\n",
" <td>Avery</td>\n",
" <td>Watkins</td>\n",
" <td>F</td>\n",
" <td>paid</td>\n",
" </tr>\n",
"</table>"
],
"text/plain": [
"[(92, 'Ryann', 'Smith', 'F', 'free'),\n",
" (57, 'Katherine', 'Gay', 'F', 'free'),\n",
" (86, 'Aiden', 'Hess', 'M', 'free'),\n",
" (74, 'Braden', 'Parker', 'M', 'free'),\n",
" (30, 'Avery', 'Watkins', 'F', 'paid')]"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%sql SELECT * FROM users LIMIT 5;"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {
"editable": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" * postgresql://student:***@127.0.0.1/sparkifydb\n",
"1 rows affected.\n"
]
},
{
"data": {
"text/html": [
"<table>\n",
" <tr>\n",
" <th>count</th>\n",
" </tr>\n",
" <tr>\n",
" <td>96</td>\n",
" </tr>\n",
"</table>"
],
"text/plain": [
"[(96,)]"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%sql SELECT count(*) FROM users"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {
"editable": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" * postgresql://student:***@127.0.0.1/sparkifydb\n",
"5 rows affected.\n"
]
},
{
"data": {
"text/html": [
"<table>\n",
" <tr>\n",
" <th>song_id</th>\n",
" <th>title</th>\n",
" <th>artist_id</th>\n",
" <th>year</th>\n",
" <th>duration</th>\n",
" </tr>\n",
" <tr>\n",
" <td>SOMZWCG12A8C13C480</td>\n",
" <td>I Didn&#x27;t Mean To</td>\n",
" <td>ARD7TVE1187B99BFB1</td>\n",
" <td>0</td>\n",
" <td>218.93179</td>\n",
" </tr>\n",
" <tr>\n",
" <td>SOUDSGM12AC9618304</td>\n",
" <td>Insatiable (Instrumental Version)</td>\n",
" <td>ARNTLGG11E2835DDB9</td>\n",
" <td>0</td>\n",
" <td>266.39628</td>\n",
" </tr>\n",
" <tr>\n",
" <td>SOIAZJW12AB01853F1</td>\n",
" <td>Pink World</td>\n",
" <td>AR8ZCNI1187B9A069B</td>\n",
" <td>1984</td>\n",
" <td>269.81832</td>\n",
" </tr>\n",
" <tr>\n",
" <td>SOHKNRJ12A6701D1F8</td>\n",
" <td>Drop of Rain</td>\n",
" <td>AR10USD1187B99F3F1</td>\n",
" <td>0</td>\n",
" <td>189.57016</td>\n",
" </tr>\n",
" <tr>\n",
" <td>SOCIWDW12A8C13D406</td>\n",
" <td>Soul Deep</td>\n",
" <td>ARMJAGH1187FB546F3</td>\n",
" <td>1969</td>\n",
" <td>148.03546</td>\n",
" </tr>\n",
"</table>"
],
"text/plain": [
"[('SOMZWCG12A8C13C480', \"I Didn't Mean To\", 'ARD7TVE1187B99BFB1', 0, 218.93179),\n",
" ('SOUDSGM12AC9618304', 'Insatiable (Instrumental Version)', 'ARNTLGG11E2835DDB9', 0, 266.39628),\n",
" ('SOIAZJW12AB01853F1', 'Pink World', 'AR8ZCNI1187B9A069B', 1984, 269.81832),\n",
" ('SOHKNRJ12A6701D1F8', 'Drop of Rain', 'AR10USD1187B99F3F1', 0, 189.57016),\n",
" ('SOCIWDW12A8C13D406', 'Soul Deep', 'ARMJAGH1187FB546F3', 1969, 148.03546)]"
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%sql SELECT * FROM songs LIMIT 5;"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {
"editable": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" * postgresql://student:***@127.0.0.1/sparkifydb\n",
"1 rows affected.\n"
]
},
{
"data": {
"text/html": [
"<table>\n",
" <tr>\n",
" <th>count</th>\n",
" </tr>\n",
" <tr>\n",
" <td>71</td>\n",
" </tr>\n",
"</table>"
],
"text/plain": [
"[(71,)]"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%sql SELECT count(*) FROM songs"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {
"editable": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" * postgresql://student:***@127.0.0.1/sparkifydb\n",
"5 rows affected.\n"
]
},
{
"data": {
"text/html": [
"<table>\n",
" <tr>\n",
" <th>artist_id</th>\n",
" <th>name</th>\n",
" <th>location</th>\n",
" <th>latitude</th>\n",
" <th>longitude</th>\n",
" </tr>\n",
" <tr>\n",
" <td>AR8ZCNI1187B9A069B</td>\n",
" <td>Planet P Project</td>\n",
" <td></td>\n",
" <td>None</td>\n",
" <td>None</td>\n",
" </tr>\n",
" <tr>\n",
" <td>AR10USD1187B99F3F1</td>\n",
" <td>Tweeterfriendly Music</td>\n",
" <td>Burlington, Ontario, Canada</td>\n",
" <td>None</td>\n",
" <td>None</td>\n",
" </tr>\n",
" <tr>\n",
" <td>ARMJAGH1187FB546F3</td>\n",
" <td>The Box Tops</td>\n",
" <td>Memphis, TN</td>\n",
" <td>35.14968</td>\n",
" <td>-90.04892</td>\n",
" </tr>\n",
" <tr>\n",
" <td>ARKFYS91187B98E58F</td>\n",
" <td>Jeff And Sheri Easter</td>\n",
" <td></td>\n",
" <td>None</td>\n",
" <td>None</td>\n",
" </tr>\n",
" <tr>\n",
" <td>ARD0S291187B9B7BF5</td>\n",
" <td>Rated R</td>\n",
" <td>Ohio</td>\n",
" <td>None</td>\n",
" <td>None</td>\n",
" </tr>\n",
"</table>"
],
"text/plain": [
"[('AR8ZCNI1187B9A069B', 'Planet P Project', '', None, None),\n",
" ('AR10USD1187B99F3F1', 'Tweeterfriendly Music', 'Burlington, Ontario, Canada', None, None),\n",
" ('ARMJAGH1187FB546F3', 'The Box Tops', 'Memphis, TN', 35.14968, -90.04892),\n",
" ('ARKFYS91187B98E58F', 'Jeff And Sheri Easter', '', None, None),\n",
" ('ARD0S291187B9B7BF5', 'Rated R', 'Ohio', None, None)]"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%sql SELECT * FROM artists LIMIT 5;"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {
"editable": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" * postgresql://student:***@127.0.0.1/sparkifydb\n",
"1 rows affected.\n"
]
},
{
"data": {
"text/html": [
"<table>\n",
" <tr>\n",
" <th>count</th>\n",
" </tr>\n",
" <tr>\n",
" <td>69</td>\n",
" </tr>\n",
"</table>"
],
"text/plain": [
"[(69,)]"
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%sql SELECT count(*) FROM artists"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {
"editable": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" * postgresql://student:***@127.0.0.1/sparkifydb\n",
"5 rows affected.\n"
]
},
{
"data": {
"text/html": [
"<table>\n",
" <tr>\n",
" <th>start_time</th>\n",
" <th>hour</th>\n",
" <th>day</th>\n",
" <th>week</th>\n",
" <th>month</th>\n",
" <th>year</th>\n",
" <th>weekday</th>\n",
" </tr>\n",
" <tr>\n",
" <td>2018-11-30 00:22:07.796000</td>\n",
" <td>0</td>\n",
" <td>30</td>\n",
" <td>48</td>\n",
" <td>11</td>\n",
" <td>2018</td>\n",
" <td>4</td>\n",
" </tr>\n",
" <tr>\n",
" <td>2018-11-30 01:08:41.796000</td>\n",
" <td>1</td>\n",
" <td>30</td>\n",
" <td>48</td>\n",
" <td>11</td>\n",
" <td>2018</td>\n",
" <td>4</td>\n",
" </tr>\n",
" <tr>\n",
" <td>2018-11-30 01:12:48.796000</td>\n",
" <td>1</td>\n",
" <td>30</td>\n",
" <td>48</td>\n",
" <td>11</td>\n",
" <td>2018</td>\n",
" <td>4</td>\n",
" </tr>\n",
" <tr>\n",
" <td>2018-11-30 01:17:05.796000</td>\n",
" <td>1</td>\n",
" <td>30</td>\n",
" <td>48</td>\n",
" <td>11</td>\n",
" <td>2018</td>\n",
" <td>4</td>\n",
" </tr>\n",
" <tr>\n",
" <td>2018-11-30 01:20:56.796000</td>\n",
" <td>1</td>\n",
" <td>30</td>\n",
" <td>48</td>\n",
" <td>11</td>\n",
" <td>2018</td>\n",
" <td>4</td>\n",
" </tr>\n",
"</table>"
],
"text/plain": [
"[(datetime.datetime(2018, 11, 30, 0, 22, 7, 796000), 0, 30, 48, 11, 2018, 4),\n",
" (datetime.datetime(2018, 11, 30, 1, 8, 41, 796000), 1, 30, 48, 11, 2018, 4),\n",
" (datetime.datetime(2018, 11, 30, 1, 12, 48, 796000), 1, 30, 48, 11, 2018, 4),\n",
" (datetime.datetime(2018, 11, 30, 1, 17, 5, 796000), 1, 30, 48, 11, 2018, 4),\n",
" (datetime.datetime(2018, 11, 30, 1, 20, 56, 796000), 1, 30, 48, 11, 2018, 4)]"
]
},
"execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%sql SELECT * FROM time LIMIT 5;"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {
"editable": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" * postgresql://student:***@127.0.0.1/sparkifydb\n",
"1 rows affected.\n"
]
},
{
"data": {
"text/html": [
"<table>\n",
" <tr>\n",
" <th>count</th>\n",
" </tr>\n",
" <tr>\n",
" <td>6820</td>\n",
" </tr>\n",
"</table>"
],
"text/plain": [
"[(6820,)]"
]
},
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%sql SELECT count(*) FROM time"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.3"
}
},
"nbformat": 4,
"nbformat_minor": 4
}