From 5540e921a540da54d426a507ea4f7387e261b2ac Mon Sep 17 00:00:00 2001 From: WADE Date: Sun, 25 May 2025 22:20:09 +0300 Subject: [PATCH 1/4] complete --- README.md | 188 ++---------------- freebies.db | Bin 0 -> 16384 bytes lib/__pycache__/debug.cpython-312.pyc | Bin 0 -> 1056 bytes lib/__pycache__/models.cpython-312.pyc | Bin 0 -> 4696 bytes lib/debug.py | 29 ++- lib/freebies.db | Bin 20480 -> 24576 bytes .../__pycache__/env.cpython-312.pyc | Bin 0 -> 2652 bytes ...f48c_create_companies_devs.cpython-312.pyc | Bin 0 -> 1750 bytes .../7a71dbf71c64_create_db.cpython-312.pyc | Bin 0 -> 704 bytes ...9f81_create_freebies_table.cpython-312.pyc | Bin 0 -> 1638 bytes .../aae737829f81_create_freebies_table.py | 33 +++ lib/models.py | 53 ++++- lib/seed.py | 31 ++- 13 files changed, 156 insertions(+), 178 deletions(-) create mode 100644 freebies.db create mode 100644 lib/__pycache__/debug.cpython-312.pyc create mode 100644 lib/__pycache__/models.cpython-312.pyc create mode 100644 lib/migrations/__pycache__/env.cpython-312.pyc create mode 100644 lib/migrations/versions/__pycache__/5f72c58bf48c_create_companies_devs.cpython-312.pyc create mode 100644 lib/migrations/versions/__pycache__/7a71dbf71c64_create_db.cpython-312.pyc create mode 100644 lib/migrations/versions/__pycache__/aae737829f81_create_freebies_table.cpython-312.pyc create mode 100644 lib/migrations/versions/aae737829f81_create_freebies_table.py diff --git a/README.md b/README.md index b598b7784..747269921 100644 --- a/README.md +++ b/README.md @@ -1,182 +1,34 @@ -# Phase 3 Mock Code Challenge: Freebie Tracker +# Freebie Tracker -## Learning Goals +**Freebie Tracker** is a handy tool designed to help developers keep track of all the freebies they receive — whether swag, giveaways, or promotional items — from companies during hackathons, conferences, or other events. -- Write SQLAlchemy migrations. -- Connect between tables using SQLAlchemy relationships. -- Use SQLAlchemy to run CRUD statements in the database. +## Project Overview -*** +This app models the dynamic relationships between: -## Key Vocab +- **Companies** that distribute freebies, +- **Developers** who collect freebies, +- **Freebies** themselves, which are linked to both a company and a developer. -- **Schema**: the blueprint of a database. Describes how data relates to other - data in tables, columns, and relationships between them. -- **Persist**: save a schema in a database. -- **Engine**: a Python object that translates SQL to Python and vice-versa. -- **Session**: a Python object that uses an engine to allow us to - programmatically interact with a database. -- **Transaction**: a strategy for executing database statements such that - the group succeeds or fails as a unit. -- **Migration**: the process of moving data from one or more databases to one - or more target databases. - -*** +The goal is to provide a structured and intuitive way to record, organize, and query collections of swag. -## Introduction -For this assignment, we'll be working with a freebie domain. -As developers, when you attend hackathons, you'll realize they hand out a lot of -free items (informally called _freebies_, or swag)! Let's make an app for -developers that keeps track of all the freebies they obtain. +## Features -We have three models: `Company`, `Dev`, and `Freebie` +- **Record Transactions:** Log which developer received which item from which company. +- **Company Freebie View:** Display all freebies given out by a specific company. +- **Developer Collection View:** See all freebies collected by a particular developer. +- **Relationship Tracking:** Identify which developers hold freebies from which companies. +- **Freebie Transfers:** Transfer freebies between developers seamlessly. -For our purposes, a `Company` has many `Freebie`s, a `Dev` has many `Freebie`s, -and a `Freebie` belongs to a `Dev` and to a `Company`. -`Company` - `Dev` is a many to many relationship. +### Installation -**Note**: You should draw your domain on paper or on a whiteboard _before you -start coding_. Remember to identify a single source of truth for your data. +```bash +git clone https://github.com/yourusername/python-p3-freebie-tracker.git +cd freebie-tracker -## Instructions +You can explore the domain design and data model here: +[Freebie Tracker Domain Design](https://dbdiagram.io/d/68336bb3b9f7446da31342a0) -To get started, run `pipenv install && pipenv shell` while inside of this -directory. - -Build out all of the methods listed in the deliverables. The methods are listed -in a suggested order, but you can feel free to tackle the ones you think are -easiest. Be careful: some of the later methods rely on earlier ones. - -**Remember!** This mock code challenge does not have tests. You cannot run -`pytest` and you cannot run `learn test`. You'll need to create your own sample -instances so that you can try out your code on your own. Make sure your -relationships and methods work in the console before submitting. - -We've provided you with a tool that you can use to test your code. To use it, -run `python debug.py` from the command line. This will start an `ipdb` session -with your classes defined. You can test out the methods that you write here. You -are also encouraged to use the `seed.py` file to create sample data to test your -models and associations. - -Writing error-free code is more important than completing all of the -deliverables listed- prioritize writing methods that work over writing more -methods that don't work. You should test your code in the console as you write. - -Similarly, messy code that works is better than clean code that doesn't. First, -prioritize getting things working. Then, if there is time at the end, refactor -your code to adhere to best practices. - -**Before you submit!** Save and run your code to verify that it works as you -expect. If you have any methods that are not working yet, feel free to leave -comments describing your progress. - -*** - -## What You Already Have - -The starter code has migrations and models for the initial `Company` and `Dev` -models, and seed data for some `Company`s and `Dev`s. The schema currently looks -like this: - -### companies Table - -| Column | Type | -| ------------- | ------- | -| name | String | -| founding_year | Integer | - -### devs Table - -| Column | Type | -| ------ | ------ | -| name | String | - -You will need to create the migration for the `freebies` table using the -attributes specified in the deliverables below. - -*** - -## Deliverables - -Write the following methods in the classes in the files provided. Feel free to -build out any helper methods if needed. - -Remember: SQLAlchemy gives your classes access to a lot of methods already! -Keep in mind what methods SQLAlchemy gives you access to on each of your -classes when you're approaching the deliverables below. - -### Migrations - -Before working on the rest of the deliverables, you will need to create a -migration for the `freebies` table. - -- A `Freebie` belongs to a `Dev`, and a `Freebie` also belongs to a `Company`. - In your migration, create any columns your `freebies` table will need to - establish these relationships using the right foreign keys. -- The `freebies` table should also have: - - An `item_name` column that stores a string. - - A `value` column that stores an integer. - -After creating the `freebies` table using a migration, use the `seed.py` file to -create instances of your `Freebie` class so you can test your code. - -**After you've set up your `freebies` table**, work on building out the following -deliverables. - -### Relationship Attributes and Methods - -Use SQLAlchemy's `ForeignKey`, `relationship()`, and `backref()` objects to -build relationships between your three models. - -**Note**: The plural of "freebie" is "freebies" and the singular of "freebies" -is "freebie". - -#### Freebie - -- `Freebie.dev` returns the `Dev` instance for this Freebie. -- `Freebie.company` returns the `Company` instance for this Freebie. - -#### Company - -- `Company.freebies` returns a collection of all the freebies for the Company. -- `Company.devs` returns a collection of all the devs who collected freebies - from the company. - -#### Dev - -- `Dev.freebies` returns a collection of all the freebies that the Dev has collected. -- `Dev.companies`returns a collection of all the companies that the Dev has collected - freebies from. - -Use `python debug.py` and check that these methods work before proceeding. For -example, you should be able to retrieve a dev from the database by its -attributes and view their companies with `dev.companies` (based on your seed -data). - -### Aggregate Methods - -#### Freebie - -- `Freebie.print_details()`should return a string formatted as follows: - `{dev name} owns a {freebie item_name} from {company name}`. - -#### Company - -- `Company.give_freebie(dev, item_name, value)` takes a `dev` (an instance of - the `Dev` class), an `item_name` (string), and a `value` as arguments, and - creates a new `Freebie` instance associated with this company and the given - dev. -- Class method `Company.oldest_company()`returns the `Company` instance with - the earliest founding year. - -#### Dev - -- `Dev.received_one(item_name)` accepts an `item_name` (string) and returns - `True` if any of the freebies associated with the dev has that `item_name`, - otherwise returns `False`. -- `Dev.give_away(dev, freebie)` accepts a `Dev` instance and a `Freebie` - instance, changes the freebie's dev to be the given dev; your code should only - make the change if the freebie belongs to the dev who's giving it away diff --git a/freebies.db b/freebies.db new file mode 100644 index 0000000000000000000000000000000000000000..1bfd3ce3935215946274226883dabc23dbaa4252 GIT binary patch literal 16384 zcmeI&&u-H&90zbaDJd;#g9cNDP&IQvY9)q*c!6cX8x>tT(g4~iN>gWx`X^JGR@$*h z9C!xahb!XBi6@viaVBn+cB#g=GU;o{`8kgB^Dm#AqPF|C9VUVWQ9SYz_LAHul#)Hh z2q9Y93u(`qnhvg>)9k_xQ6tZ1pDXDCwep4Nv0h078U!E!0SG_<0uX=z1Rwwb2;>Dm zMryHEuhUO260bKDK`cZs6q76#Oq&}HXO6Mo<}90KjdCgMvzF!XLvAyx<1p)8yZwx% z(}@_lV{atbd&4$g8~Lj{wmLHqvrfFmSUX-DOG{ChVYN^VXpyZ)+^)o6P11+~$_ayKJ%MAL-WhxXWS6l*_wb zkjuSZEH@}OeWh62-lp^B0$lDayPAVu*7H~7tG*Io6Q$go-=oFa&JLZ6#V)HFRs$us z-)j1XH@mrM5KYJZaD3`s2rtgw>GjpfZ*xWeN%UXo0Sy8WfB*y_009U<00Izz00bZa zfmjC~fB*y_009U< z00Izz00bZafeisoQOSe-sCSpDq-G35Uo8HcuYZ-l|Nlq>8U!E!0SG_<0uX=z1Rwwb z2tWV=|E<85s*xwOM9nA&gkVS0Q(bweXyhrSrEU`X0}-=h&mY`Ts#GJ7X{qGwcF)2% GdGrTElHOkc literal 0 HcmV?d00001 diff --git a/lib/__pycache__/debug.cpython-312.pyc b/lib/__pycache__/debug.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ba102ab7f154b32523e36709485afa6d3c030822 GIT binary patch literal 1056 zcmZWo&rcIU6rOFjyW55G!-iiH%_eHJN!vByBrzl?;UHpS@U)j^w)>!4W_RoCwq`k% zi)c6)qlp~#Xy8BbqCynL5H+5>LAZHxrriPw?=XGud+&Yk%{SXmxtxx;9j{E)KBN%( zBZ8jEiF0yWLg*cGkRuV~NtWcLtdy6w(w=O|lE70W<0+QX@zX^0G)t3E3W4It+q_qp zmF2Mp*`3TOqH{#w?xvB|2U2}J3C{i0C(i|m3)vorgkZo?R&OCh=lLEg8MFo+%^Kp& z!#(Eujf)JuoRx=sy>Kzl`$u{;XR|muSTA0zh9SuBWVg9~!Xy-{v0Bjoil87f`5q2| zsrLh~f&G}J=b**Zc?w{=P>@)zN&!bu0e{8y1<)Tt7`lP);Z>k(BjHoxMlfxf=5n_u zEIT$YlWo^`m{zHH*!3%wM{93&gWDX~%@rf80U^e6K#gRO@r2?k=hHhyvn}irY!fhA zn7YCVr#lJ5C>hCkW7=4H{BV|3Yv9E_@U$qoO_9%Q6;Fpu8*$L2h8H+M!cJ`=#S|O+ zK2Vk+K^2q27*o1=n&$dY@sZJtI23*`onIGsXHr!F17|=vpdQr(sC30*>QYxKrY1`> z&4UO#IKoU%bj5@Sm3-_$rNZPY-;MSO5_N?HHYTCK8Znc(6d_ZZ4c-k*=`0&E&GjST z(nTN932#FG9+4+yPH{yTVU9Lovzzj7wwfLii&-rnbmL%yXD(|B5A-aBuZvM`WejY3DX3e&8ppS0N z@9Edt>VZDIS!kRgdv0IWHWtTu=v@#P7 literal 0 HcmV?d00001 diff --git a/lib/__pycache__/models.cpython-312.pyc b/lib/__pycache__/models.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9ea69fef946e0548bf788217db58ece8f03e21df GIT binary patch literal 4696 zcmcgwU2GKB6~1@&Z}xX=V@xmsHnk~UyS4#S48=GoHYOBdNDNi8Dw?i$uI;t=k2`CV zU72d7B9%yqVwbiyilRDwXl>yN`cx`aY9A~0WsRKxqeLxgE46P1Qz_x8=iJ#DuZm}rG*szMLTv_`iRAz`qG@2wS8l@>IDy1Az zN6Hy>rd&}M#Xc$NPI;mpQFkQelsD>yx>Iu{Xw)YW=3>4@_ibvf8TA9l%lwNTn-h@8 zX`;#3iRNX2+m7#yL31UCTOUyS>AB>WRl~l zwBb3E&aq*}4fjBfC(^@)e2(Q}y|G*@LX7}t$yhFtN$VqtEVQdM7Ei`FuqK!~7}J>{ z4UH9!4~?n&nsTwhBvaF|6pQH4jEm*f1M3{lh8X8eQ!7WpqSY`5Hdf=A^aM-eZorgN za0(4h5jQVwQfIlb_6w-Y5JsX@BT-4CQ3uG*i4whC9->K$j@y#ih`P(Y9;?@uu)KMm z-Q$HGALOdt<%v{`=hZP#g{O}*Hke?B#~hP~0inTId`!(|vg4otrpL=RBJSe`ing#e1Z0Nf z?7m4dT0W^5S0=sWeHxcWNL;!cBIFvKq@$J`D~A18dbi36W3Ew40t3*Zf^(HD(Efx7~3Jy0=B%facHrZedXb8d> zegG8!BnqGdfOL&g0*bca3a6FJB(W4c>alq1Uoatgy=B$x8Gehi{svL*DmLseAw0JJ)6hmX%i?D9uYs z^L)pHmae6iu4U!K1Ept4=~-4zmE===A57U=zNk@@FGvV#o683P_8&Tg3<}<^@|nWV zX*c+?6G3r-3hU6(Sk<~H5k~3TffUKZ>iXHkKR&LqNoaAV!90NJIohL<9#wq7dpuUIm8|&|zXmEi^aSo()s~KcMG3 z;1Cf9M~oGgAP|o4f@Y-~a@21j2v=z{9TDOhn$bEe&pYn~7lNPE9+^7`u>97|x9-;- zSynnrawov@5gvxYaRdvipppcRorKDdXeB7$phHxn*X92f-Yf*NP)b1d20`M&9q?Q0 z0`gOOmQZlzNpcxbR>VW#ZZ7XgV@-tojLra%zPsH?^5oZ!tJD+^

545T&*Qd^c1@ zTgP3(;iB+_=iaVimS%5fd3T`!#l%^h0rYEXCe7Nql9_lcsdu;8gF0cZj*;W@f0ECO zeg^2=zoHGw9%fOa*-BfNSKb@Z%o2xD<4JEljoT@)k#lMNGp$<4Io*zYGBQwYQRY0?i%KTf{fv(3- zA$c7MVlYR$Hqj5W4Bl;#W~k`rfglXme;Ev$(92eoE*pA}+R%Fxp|_VlbxW>2Yk;(- zc*QnxSlliMSXkD659G!CoVi}i%9%%VF1qXtTjb*~u9AnDxRbd=K5oC3>>2)wUi;-_ z_reQ`L6)x3MX$|+mlE)N8+eN52b`|b;Qa)ddoU6*aT#NwiPL?M)yV1bWD=h_1&;=K zXj?)n1Z?<&mMM3HaS;PIKoEvpVSWW6nyr0jtMnZ*3(PsJAO^Fof;k8DSVFhh@ZEZy z4_#({B8M|q(|R}-F1W)(Jd+AT=87(9CIaXlCg^Xnb|VOnmUK?l;ANIb>V@rn<~yKm z1N#C@*U?$PH*4xm(TBlp5_Rh)kwRiR`>?t)Jz30A{`@`h#CLg?dVd>QirEbV- z-Ym&)zUZ>H%+S2Q++{%yh)?d*rFtbE>Z!4Yn1EJ%@V08eq-2AHTUh|b*ef=b8CWadQ>Sl5=e^6j4=o2fihYl&cg%V|s-N#)e&zUbbyxA*k9~Dh z+5Z{ogjCbzE%{EbI;4q zW73q*$}TP|%h+mIl9-f}npTvWnv|JZ45QhcgIpa$TopnboqSvsprVr<`D8*eOHy;= z^AdAY6~Y{YoIMdd){X$&bT~TFHQp@5qQ(#gcwaNLp z1&Mi;K+(zX`DE%rLeBnv!68A8K>Z47+3_&P#6$FgsA2^-{~%XScRvMh*GLVBxTZpo ztD9?(tDm!LumV_(MrMj89^()e$3vJvk1H4>8;nqaVmLxI$ObOW%~E`~1bGq@Q_YRd XEsQMFEDSd(eBnnCSY)8E$Uy)AGA4cK delta 94 zcmZoTz}T>Wae}lUD+2=q2*UvLL>*&MRtCLzSzi7h3@m(74E((OJNfGQq&5o*EaTlQ e#dk}P$285{DB08^Db2(pd6U8yeiVU41_}T{Q53rX diff --git a/lib/migrations/__pycache__/env.cpython-312.pyc b/lib/migrations/__pycache__/env.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..362a34c2adc2a6f9885d16ce76d55bf1c9e6b602 GIT binary patch literal 2652 zcmZuz&1)M+6ra_uq}5s<{)pW812c9bJ4$0KZaxa7G{or#p~ZyMg+>>#-W^G+tajDe zk!^(pTJLg^`o_K<6Fj{OImYoSEgLC)eFN=czN7dseC4}G(%_1dmiXy(m(Z{8cd zH^1NNw^T|&@cdrBT)ihF^e0~gkJuG<{{`VO(vdEhs4f%*fy)syQWuM&CyO9UMah#T zGg^-oV*(_7&c!&1*LuTsAbryxK}0y+wkG&qUi_Gus4GPU;w!bmV0SndlX^mr ze=8MJFv~EfA#SWT7J3BIT34Vlc%*`rfLc*lr;o1l%HP~KFSttCFv(5ZDjOA8^%JXN zSfo^@cD~h(JLQdhj zt&ifZ!?23Kyz{x|uUa~`Y|vQvW3Me2VT;|Y zR6`Ahh^nTM22&SJ;_a#uO0eqSWn!8$7|*q^bI)ir46EWL^dn)767RI$mSuu<+nQpS zED;M^gy?XJkLGUNzJ-~M7a`n|YM4Aj_m|vMO%u*<2gjcwD@1EDaz2l}^rUVuFI&an z5gkUo^fuRd86Axp4TkL|YcyFm=>4?wwW*p~mDF1^O=>Q&e(RX4E>l7l4KfY!wR?mXOk=SShAt3mX{OO~2ajhg zb*~i7LP`#PM}uJ%?VUwEeH{h275sdBc0+l0_2#zJ(~+`mDZ7=-Y@eOl8XVploOtr- z^X$bpiD)#omqtooCo$1ZOl&01{ey()__mzs$YX7JY*WVjA}IE`)-xSAyd>+1?2RdL zeJXn6Qk>^Kd=626A4&nJ?-CnAtcxFnYKQnf+;!A?3g*|kQFI~1e(e-=KaH%3e$0pH z0jj0K_<<>bC}_n=P5)Ucml&j`6pzU zlj~OWB;$PF?=#LxeJk2!qS*aMr_qr0KNh-W0SbXO9F15iHEbXXAMzZ|oD~4>0pWO9 zN1pA zI-w=iDJ`l@tIp?>l+!%r^>=$Xa^aQZp|RfwY{{^UKu7s4bLIJ_Y2Jo3-ph)g(?dAz z<8k;!ro72?00uZ%PxlC%+UOAI9DZprro7K?_9OtkVp0sYYw&e`f&uWCMgzHRIo*+m z+w$uiP3gqbR#jggJRL#lM5d5 zhT8Jb)?4GhUVpyu)f+LAQ1)b$&UR9h?bPH(>O9~uk=srVbdnS8Djqias7IBE*E`vMh5v=E;=`pcy=Mq<=N=m`*GeON?4Ox z^Z8ykZQ2zezsihXV#)#LDq%zYmUzXE1IN}E4b3mH*QMTWWB9*{5~pl8#@~RZLpf2n zazNOAFF2KX^>j0a6A)a9Z}*n$^s1Z&n!J jy)+=?b}k}mWc59N*QPl7QW}0Cjs77Gy^u!e1xWZG&}(Xi literal 0 HcmV?d00001 diff --git a/lib/migrations/versions/__pycache__/5f72c58bf48c_create_companies_devs.cpython-312.pyc b/lib/migrations/versions/__pycache__/5f72c58bf48c_create_companies_devs.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8e790ba3bb8ff146d937a1c31118717dc66ca7ae GIT binary patch literal 1750 zcmd5+&u`O66!wpa?U)3y+Oi0cAb_+|#0ED>)0TiZ&}cI7sJpq+!cwgTn0%7z9t zsN4YUJku)E`amw{7q8j`SrIDPz86^7LE#T2h!#R!zl0W?(D89;w$&^(x>Gf~G2Q7- zOxwv03Y(=VYpM!6-KnZQIib%aI4uU&EY-$q^~!j?Qf-u~jpq1dvo?P0_{2nGdQ#W_ z=Fyi$D*3@2Eo6~tA&Y2_vWyicgV7)iPqXA#gh)&`FQ;Ur3rs^X%B9oGN@{ItC}sAw z&Gpn;9T`ym4XpB0*_ZLy3Ne@2k1sCqO63Nk^2La12Jv$-ZjD$-Pu|o}S{<>rI$}rM zjz=vM!&X^;Z9INHYmjgu3Im~>pQHJWlBbdb&#;QraNl*Uj*BS3mWO_(#jfAS(82TO z09k|r-Wg?;@RFc~q;bqBc924gDl@*@_b^pwafId(p~_DYVa{~yB5^#649=m!jE}>J zSPqV!3PT>x$6t+}?;+!w1(DH03&`~Y58=qLeYOzvtPoY|MlgtaKCT4yN|zwiaZrVU z*jErST&H7r&OEUq)~lhhfCz8e(8%_cISO?nVUs6vEErI=A23&l$agH1Z`lZ+F|j1P z1Io<{%NK5+d&7*`<=I>C-szRIch27Z@kwJ1RMXY&z0Qhr$GLmuNh`DJKO&D8A1pq+ z{ySU)C)mF)!TvwN{`;-Jz@hbgE~l&)gq#}VpGlFv5I=+TK?OO5jInV4^HA`+;bZs< z6Wc!&X-jO|3LDK6mybM0c&!nYiL#Uwgbs-xB;`Ojm2qrjH?wFS`qywm^jI|*4&(Sh=uK*$x0l#A=M!Y5Qd@Y|dKH0W~#Q3}l^4A!luQK^Plq1<+2y%r8 ziV(p>DRHGl3YJ_g)kq^+G$3lEi)n~y5`zprYSBN&O zptbXIF?VLk%qQt;=4aDq{SLHq$9mDr7vjv^nT#iaI}Thwbo_8W4(DNb9{SU1;9J%= zX>x?QLYpN&y)kgL_jeGJ^t{<} zW8DZj0VW^dvGg$zutPVR$xOliZ=dNxaj=cy02`D{7i0~NRX0|!gU7S zn$^qE2{+=H&@7I*k(5xSMaJY6ajSh_CS{gGwdG2iaFZP$jN7ty{5MTmQfGNwCMlFH zw+J*)lQyRHp(!T6|Bt;p^P-|;UBYuForzx#wG#oiD#rM`qGRpn1BB1MptD;Ooj%=} XHxHle>>lh#J8Q3FJp5q_IP~)i3jweX literal 0 HcmV?d00001 diff --git a/lib/migrations/versions/__pycache__/aae737829f81_create_freebies_table.cpython-312.pyc b/lib/migrations/versions/__pycache__/aae737829f81_create_freebies_table.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b221dc731eecdf35b2c12f72a138de700c921707 GIT binary patch literal 1638 zcma)6&1)M+6yIG*yQA?cIQ?>HX(CdGRB5HPR~1s#&_iqjNgM~7_M*$O+8Ilm>{n-3 z3Y!pcAW(X0dJ4t{QyK`yhWMEOAxAr4rnwagxg{080s-4j9QG{=MdN75RU|lw}p@}b@C|RDWF0}M7fT{ zCP3m{u2V!3qcF@>z)f$CU_HR)C4zC+#C|!@yB3D<2Rt-=({;)h=G$dm$IW`PrGC5A znjKrP-!382F_jKD5;AshpiiaE zL_oQ%{AP438<`XDLM&wL@tciLrSv~UaZ5TRBFG@V&&R_f77vG**(Im`A8-UWliVLN zj)@H3d*aCKde^P;+qZ5eufTI5S1B!0kk&61O!OlwuL+NswoXFrIu2>k46v;^x{c2> z6L1EW6;(Mc40UUOsfh4UGto_nald9F3JurxbSI3I@>piA!7LStLyBd!t3ikuGSSV4EnB9_3G6mv}!=8X+{pl-1Orl2hm259*iGyic z#-7%^kV*rO9YvTNW3GJ2rvE!5%iOcP_{)_$SN6aM&j9?b_-par^qQ~^SKz9=J-rK> zsrIWivL3F4tGBj)+6CXG+S6<5dV8h4dUpHNE@-9NFW1hkUtGDky0CTfQFWvGxVUrX z+zyya&0jwd9>PE1pYm4sk-cF*Ufii&+5rpuC8;2iPncJ4`~gwoqdBTE^8bH8S}}2j z2#Z8wrz*nu`5+>$H%l1AH(eE=((B(Uq@11#?|2#fW znV^!UA=l6}D(M!syQY!g`#)Q{W%RKflF0}akmNh1r3ha;Sayl-7=4Y^Ber}B5%#cy ze9d*@_aTuFZ@KsioV8svu<-Zf3ucYl(N`IHk>h#(r6BV8{UaPd^%pnw0&w!D%V2Nv a_;P7)@*_q{N0;HhBH+c*F`hpjNAVhDC0D}$ literal 0 HcmV?d00001 diff --git a/lib/migrations/versions/aae737829f81_create_freebies_table.py b/lib/migrations/versions/aae737829f81_create_freebies_table.py new file mode 100644 index 000000000..dc527f8e2 --- /dev/null +++ b/lib/migrations/versions/aae737829f81_create_freebies_table.py @@ -0,0 +1,33 @@ +"""Create freebies table + +Revision ID: aae737829f81 +Revises: 5f72c58bf48c +Create Date: 2025-05-25 21:53:21.720728 + +""" +from alembic import op +import sqlalchemy as sa + + + +revision = 'aae737829f81' +down_revision = '5f72c58bf48c' +branch_labels = None +depends_on = None + + +def upgrade(): + op.create_table( + 'freebies', + sa.Column('id', sa.Integer(), primary_key=True), + sa.Column('item_name', sa.String(), nullable=False), + sa.Column('value', sa.Integer(), nullable=False), + sa.Column('dev_id', sa.Integer(), sa.ForeignKey('devs.id')), + sa.Column('company_id', sa.Integer(), sa.ForeignKey('companies.id')) + ) + + + +def downgrade(): + op.drop_table('freebies') + diff --git a/lib/models.py b/lib/models.py index 2681bee5a..b00a81b23 100644 --- a/lib/models.py +++ b/lib/models.py @@ -1,5 +1,5 @@ from sqlalchemy import ForeignKey, Column, Integer, String, MetaData -from sqlalchemy.orm import relationship, backref +from sqlalchemy.orm import relationship from sqlalchemy.ext.declarative import declarative_base convention = { @@ -9,6 +9,7 @@ Base = declarative_base(metadata=metadata) + class Company(Base): __tablename__ = 'companies' @@ -16,14 +17,62 @@ class Company(Base): name = Column(String()) founding_year = Column(Integer()) + freebies = relationship("Freebie", back_populates="company") + + @property + def devs(self): + return list({f.dev for f in self.freebies}) + + def give_freebie(self, dev, item_name, value): + return Freebie(item_name=item_name, value=value, dev=dev, company=self) + + @classmethod + def oldest_company(cls): + from lib.debug import session + return session.query(cls).order_by(cls.founding_year).first() + def __repr__(self): return f'' + class Dev(Base): __tablename__ = 'devs' id = Column(Integer(), primary_key=True) - name= Column(String()) + name = Column(String()) + + freebies = relationship("Freebie", back_populates="dev") + + @property + def companies(self): + return list({f.company for f in self.freebies}) + + def received_one(self, item_name): + return any(f.item_name == item_name for f in self.freebies) + + def give_away(self, dev, freebie): + if freebie in self.freebies: + freebie.dev = dev def __repr__(self): return f'' + + +class Freebie(Base): + __tablename__ = 'freebies' + + id = Column(Integer, primary_key=True) + item_name = Column(String, nullable=False) + value = Column(Integer, nullable=False) + + dev_id = Column(Integer, ForeignKey('devs.id')) + company_id = Column(Integer, ForeignKey('companies.id')) + + dev = relationship("Dev", back_populates="freebies") + company = relationship("Company", back_populates="freebies") + + def print_details(self): + return f"{self.dev.name} owns a {self.item_name} from {self.company.name}" + + def __repr__(self): + return f"" diff --git a/lib/seed.py b/lib/seed.py index b16becbbb..7ec202353 100644 --- a/lib/seed.py +++ b/lib/seed.py @@ -1,3 +1,30 @@ -#!/usr/bin/env python3 +from models import Base, Company, Dev, Freebie +from debug import session -# Script goes here! + +session.query(Freebie).delete() +session.query(Dev).delete() +session.query(Company).delete() +session.commit() + + +company1 = Company(name="TechCorp", founding_year=2001) +company2 = Company(name="DevWorks", founding_year=1999) + + +dev1 = Dev(name="Alice") +dev2 = Dev(name="Bob") + +session.add_all([company1, company2, dev1, dev2]) +session.commit() + + +freebie1 = company1.give_freebie(dev1, "T-Shirt", 25) +freebie2 = company1.give_freebie(dev2, "Sticker Pack", 5) +freebie3 = company2.give_freebie(dev1, "Coffee Mug", 15) + + +session.add_all([freebie1, freebie2, freebie3]) +session.commit() + +print("Seed data created!") From 2e6dfb0af55281fa07ed0465013c2945f2e05095 Mon Sep 17 00:00:00 2001 From: WADE Date: Sun, 25 May 2025 22:22:38 +0300 Subject: [PATCH 2/4] domain design --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 747269921..bc1decf72 100644 --- a/README.md +++ b/README.md @@ -27,8 +27,8 @@ The goal is to provide a structured and intuitive way to record, organize, and q ```bash git clone https://github.com/yourusername/python-p3-freebie-tracker.git -cd freebie-tracker +cd python-p3-freebie-tracker You can explore the domain design and data model here: -[Freebie Tracker Domain Design](https://dbdiagram.io/d/68336bb3b9f7446da31342a0) +[Freebie Tracker Domain Design] "https://dbdiagram.io/d/68336bb3b9f7446da31342a0" From e1248573031dbf6af4cc712cb0ba451dcfc4e6f1 Mon Sep 17 00:00:00 2001 From: WADE Date: Sun, 25 May 2025 22:23:43 +0300 Subject: [PATCH 3/4] link added --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index bc1decf72..864380f98 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,8 @@ The goal is to provide a structured and intuitive way to record, organize, and q ```bash git clone https://github.com/yourusername/python-p3-freebie-tracker.git cd python-p3-freebie-tracker +``` You can explore the domain design and data model here: -[Freebie Tracker Domain Design] "https://dbdiagram.io/d/68336bb3b9f7446da31342a0" +[Freebie Tracker Domain Design] (https://dbdiagram.io/d/68336bb3b9f7446da31342a0) From 44d59f1e38eca2c58f890a74cd3189d4b26ebe17 Mon Sep 17 00:00:00 2001 From: WADE Date: Sun, 25 May 2025 22:27:58 +0300 Subject: [PATCH 4/4] small changes to readme --- README.md | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 864380f98..d3f44701c 100644 --- a/README.md +++ b/README.md @@ -1,29 +1,28 @@ # Freebie Tracker -**Freebie Tracker** is a handy tool designed to help developers keep track of all the freebies they receive — whether swag, giveaways, or promotional items — from companies during hackathons, conferences, or other events. +**Freebie Tracker** is your developer-sidekick for cataloging swag, giveaways, and promotional treasures snagged from hackathons, conferences, and events. Never lose track of that elusive T-shirt or sticker pack again. ## Project Overview -This app models the dynamic relationships between: +This app elegantly models the real-world relationships between: -- **Companies** that distribute freebies, -- **Developers** who collect freebies, -- **Freebies** themselves, which are linked to both a company and a developer. +- **Companies** dishing out freebies, +- **Developers** eagerly collecting them, +- **Freebies** themselves—linked to both their origin and their proud owners. -The goal is to provide a structured and intuitive way to record, organize, and query collections of swag. +The goal? To provide a clear, intuitive system for logging, organizing, and querying your collection of coveted swag. +## Key Features +- **Transaction Logging:** Effortlessly record which developer scored what item from which company. +- **Company Freebie Catalog:** Instantly view every freebie distributed by any company. +- **Developer Inventory:** Quickly browse all swag owned by a developer. +- **Relationship Mapping:** Reveal who holds freebies from which companies — perfect for competitive bragging rights. +- **Seamless Transfers:** Easily transfer freebies between developers without breaking a sweat. -## Features +## Installation -- **Record Transactions:** Log which developer received which item from which company. -- **Company Freebie View:** Display all freebies given out by a specific company. -- **Developer Collection View:** See all freebies collected by a particular developer. -- **Relationship Tracking:** Identify which developers hold freebies from which companies. -- **Freebie Transfers:** Transfer freebies between developers seamlessly. - - -### Installation +Clone the repo and dive right in: ```bash git clone https://github.com/yourusername/python-p3-freebie-tracker.git