import%20marimo%0A%0A__generated_with%20%3D%20%220.9.3%22%0Aapp%20%3D%20marimo.App(width%3D%22medium%22)%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20__()%3A%0A%20%20%20%20import%20marimo%20as%20mo%0A%20%20%20%20return%20(mo%2C)%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20__(mo)%3A%0A%20%20%20%20mo.md(%0A%20%20%20%20%20%20%20%20r%22%22%22%0A%20%20%20%20%20%20%20%20%23%20Classes%20e%20objetos%0A%0A%20%20%20%20%20%20%20%20Link%20para%20apresenta%C3%A7%C3%A3o%20%5Baqui%5D(https%3A%2F%2Fwww.inf.puc-rio.br%2F~bclaro%2Fcourses%2Fpython-intro%2Fpresentations%2Foop-slides-mit.pdf)%20%E2%80%94%20slides%20do%20curso%20%5B6.001%20do%20MIT%5D(https%3A%2F%2Focw.mit.edu%2Fcourses%2F6-0001-introduction-to-computer-science-and-programming-in-python-fall-2016%2F)%20sob%20licen%C3%A7a%20Creative%20Commons.%0A%20%20%20%20%20%20%20%20%22%22%22%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20__()%3A%0A%20%20%20%20%5B1%2C2%2C3%5D.__str__()%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20__()%3A%0A%20%20%20%20_xs%20%3D%20%5B1%2C2%2C3%5D%0A%20%20%20%20_ys%20%3D%20_xs.copy()%0A%20%20%20%20list.append(_xs%2C%204)%0A%20%20%20%20_ys.append(4)%0A%20%20%20%20_xs%20%3D%3D%20_ys%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20__()%3A%0A%20%20%20%20int.__add__(1%2C%202)%20%3D%3D%201%20%2B%202%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20__()%3A%0A%20%20%20%20list.__getitem__(%5B1%2C2%2C3%5D%2C%201)%20%3D%3D%20%5B1%2C2%2C3%5D%5B1%5D%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20__(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%23%20Exerc%C3%ADcios%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20__(mo)%3A%0A%20%20%20%20mo.md(%0A%20%20%20%20%20%20%20%20r%22%22%22%0A%20%20%20%20%20%20%20%20%23%23%23%23%20Ex.%20cc%0A%0A%20%20%20%20%20%20%20%20Implemente%20uma%20classe%20para%20contas%20correntes%2C%20com%20os%20m%C3%A9todos%20%60get_saldo%60%2C%20%60deposita%60%20(incrementa%20o%20saldo%20da%20conta)%2C%20%60saque%60%20(decrementa%20o%20saldo%20da%20conta)%2C%20e%20%60transfere_para%60%20(transfere%20parte%20do%20saldo%20da%20conta%20para%20uma%20conta%20par%C3%A2metro)%2C%20al%C3%A9m%20dos%20m%C3%A9todos%20%60__init__%60%20(que%20tem%20como%20par%C3%A2metro%20o%20saldo%20inicial%20da%20conta)%20e%20%60__str__%60%20(que%20deve%20retornar%20uma%20string%20indicando%20que%20o%20objeto%20%C3%A9%20uma%20conta%20corrente%2C%20mostrando%20o%20saldo%20da%20conta).%20Voc%C3%AA%20tamb%C3%A9m%20deve%20incluir%20um%20atributo%20%60_saldo%60%20para%20armazenar%20o%20saldo%20da%20conta.%0A%0A%20%20%20%20%20%20%20%20-%20Os%20m%C3%A9todos%20para%20saque%20e%20transfer%C3%AAncia%20n%C3%A3o%20devem%20permitir%20%5B*overdraft*%5D(https%3A%2F%2Fen.wikipedia.org%2Fwiki%2FOverdraft).%0A%0A%20%20%20%20%20%20%20%20**Nota**%3A%20naturalmente%2C%20esta%20n%C3%A3o%20%C3%A9%20uma%20implementa%C3%A7%C3%A3o%20realista.%20Para%20lidar%20com%20valores%20financeiros%2C%20usamos%20n%C3%BAmeros%20%5Bdecimais%5D(https%3A%2F%2Fdocs.python.org%2F3%2Flibrary%2Fdecimal.html)%2C%20e%20as%20transa%C3%A7%C3%B5es%20seriam%20feitas%20e%20armazenadas%20com%20um%20gerenciador%20de%20banco%20de%20dados%2C%20garantindo%20a%20consist%C3%AAncia%20dos%20dados%20%E2%80%94%20impedindo%20problemas%20semelhantes%20a%20%5Besse%5D(https%3A%2F%2Fwww.vice.com%2Fen%2Farticle%2Fthis-australian-bartender-dan-saunders-found-an-atm-bank-glitch-hack-and-blew-16-million-dollars%2F).%0A%20%20%20%20%20%20%20%20%22%22%22%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20__()%3A%0A%20%20%20%20class%20CC()%3A%0A%20%20%20%20%20%20%20%20def%20__init__(self%2C%20saldo)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20...%0A%20%20%20%20%20%20%20%20def%20saldo(self)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%200%0A%20%20%20%20%20%20%20%20def%20__str__(self)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20%22%22%0A%20%20%20%20%20%20%20%20def%20deposita(self%2C%20montante)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20...%0A%20%20%20%20%20%20%20%20def%20saque(self%2C%20montante)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20...%0A%20%20%20%20%20%20%20%20def%20transfere_para(self%2C%20cc%2C%20montante)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20...%0A%20%20%20%20return%20(CC%2C)%0A%0A%0A%40app.cell%0Adef%20__(SuaCC)%3A%0A%20%20%20%20fulano%20%3D%20SuaCC(0)%20%23%20inicializa%20conta%20com%200%20dinheiros%0A%20%20%20%20cicrana%20%3D%20SuaCC(100)%0A%20%20%20%20print(%22Saldo%20inicial%20igual%20a%20100%3A%22%2C%20cicrana.get_saldo()%20%3D%3D%20100)%0A%20%20%20%20cicrana.transfere_para(fulano%2C%2050)%0A%20%20%20%20print(%22Saldos%20iguais%20ap%C3%B3s%20transfer%C3%AAncia%3A%22%2C%20cicrana.get_saldo()%20%3D%3D%20fulano.get_saldo())%0A%20%20%20%20cicrana.transfere_para(cicrana%2C%2050)%0A%20%20%20%20print(%22Transfer%C3%AAncia%20para%20si%20n%C3%A3o%20muda%20nada%3A%22%2C%20cicrana.get_saldo()%20%3D%3D%2050)%0A%20%20%20%20cicrana.deposita(50)%0A%20%20%20%20print(%22Dep%C3%B3sito%20aumenta%20saldo%3A%22%2C%20cicrana.get_saldo()%20%3E%20fulano.get_saldo())%0A%20%20%20%20cicrana.saque(60)%0A%20%20%20%20print(%22Saque%20diminui%20saldo%3A%22%2C%20cicrana.get_saldo()%20%3C%20fulano.get_saldo())%0A%20%20%20%20print(%22Implementou%20m%C3%A9todo%20__str__%3A%20%22%2C%20cicrana)%0A%20%20%20%20return%20cicrana%2C%20fulano%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20__()%3A%0A%20%20%20%20%23%20solu%C3%A7%C3%A3o%0A%20%20%20%20class%20SuaCC()%3A%0A%20%20%20%20%20%20%20%20def%20__init__(self%2C%20saldo)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20self._saldo%20%3D%20saldo%0A%20%20%20%20%20%20%20%20def%20__set_saldo(self%2C%20saldo)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20m%C3%A9todo%20auxiliar%2C%20n%C3%A3o%20necessariamente%20precisa%20ser%20implementado%0A%20%20%20%20%20%20%20%20%20%20%20%20self._saldo%20%3D%20saldo%0A%20%20%20%20%20%20%20%20def%20__str__(self)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20f%22%3CCC%20saldo%3A%7Bself.get_saldo()%7D%3E%22%0A%20%20%20%20%20%20%20%20def%20get_saldo(self)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20self._saldo%0A%20%20%20%20%20%20%20%20def%20deposita(self%2C%20montante)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20montante%20%3E%200%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20self.__set_saldo(self.get_saldo()%20%2B%20montante)%0A%20%20%20%20%20%20%20%20def%20saque(self%2C%20montante)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20s%20%3D%20self.get_saldo()%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20s%20%3E%3D%20montante%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20self.__set_saldo(s%20-%20montante)%0A%20%20%20%20%20%20%20%20def%20transfere_para(self%2C%20cc%2C%20montante)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20isinstance(cc%2C%20SuaCC)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20s%20%3D%20self.get_saldo()%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20montante%20%3C%3D%20s%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20self.saque(montante)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20cc.deposita(montante)%0A%20%20%20%20return%20(SuaCC%2C)%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20__(mo)%3A%0A%20%20%20%20mo.md(%0A%20%20%20%20%20%20%20%20r%22%22%22%0A%20%20%20%20%20%20%20%20%23%23%23%23%20Ex.%20fra%C3%A7%C3%A3o%0A%0A%20%20%20%20%20%20%20%20Crie%20um%20novo%20tipo%20para%20representar%20fra%C3%A7%C3%B5es%2C%20cuja%20representa%C3%A7%C3%A3o%20interna%20inclui%20dois%20atributos%3A%20%60numerator%60%20(%60int%60)%20e%20%60denominator%60%20(%60int%60).%20Implemente%20m%C3%A9todos%20para%20adi%C3%A7%C3%A3o%20e%20subtra%C3%A7%C3%A3o%20de%20fra%C3%A7%C3%B5es%2C%20al%C3%A9m%20de%20convers%C3%A3o%20para%20float%2C%20represent%C3%A7%C3%A3o%20como%20string%20(m%C3%A9todo%20%60__str__%60)%2C%20e%20invers%C3%A3o.%0A%0A%20%20%20%20%20%20%20%20Este%20exerc%C3%ADcio%20foi%20proposto%20nos%20%5Bslides%5D(https%3A%2F%2Fwww.inf.puc-rio.br%2F~bclaro%2Fcourses%2Fpython-intro%2Fpresentations%2Foop-slides-mit.pdf)%20do%20curso%20%5B6.001%20do%20MIT%5D(https%3A%2F%2Focw.mit.edu%2Fcourses%2F6-0001-introduction-to-computer-science-and-programming-in-python-fall-2016%2F)%20sob%20licen%C3%A7a%20Creative%20Commons.%0A%20%20%20%20%20%20%20%20%22%22%22%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20__()%3A%0A%20%20%20%20class%20Fraction()%3A%0A%20%20%20%20%20%20%20%20def%20__init__(self%2C%20num%2C%20denom)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20...%0A%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20def%20__str__(self)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20...%0A%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20def%20__add__(self)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20...%0A%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20def%20__sub__(self)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20...%0A%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20def%20__float__(self)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20...%0A%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20def%20invert(self)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20...%0A%0A%20%20%20%20return%20(Fraction%2C)%0A%0A%0A%40app.cell%0Adef%20__(YourFraction)%3A%0A%20%20%20%20f1%20%3D%20YourFraction(1%2C4)%0A%20%20%20%20f2%20%3D%20YourFraction(3%2C4)%0A%20%20%20%20f3%20%3D%20f1%20%2B%20f2%20%23%20c%20is%20a%20Fraction%20object%0A%20%20%20%20print(f3)%0A%20%20%20%20print(float(f3))%0A%20%20%20%20print(YourFraction.__float__(f3))%0A%20%20%20%20print(float(f2.inverse()))%0A%20%20%20%20%23f4%20%3D%20YourFraction(3.14%2C%202.7)%20%23%20assertion%20error%0A%20%20%20%20%23print(f1*f2)%20%23%20error%2C%20did%20not%20define%20how%20to%20multiply%20two%20Fraction%20objects%0A%20%20%20%20print(f3%20-%20f2%20%3D%3D%20f1)%0A%20%20%20%20return%20f1%2C%20f2%2C%20f3%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20__()%3A%0A%20%20%20%20%23%20solu%C3%A7%C3%A3o%0A%20%20%20%20class%20YourFraction(object)%3A%0A%20%20%20%20%20%20%20%20%22%22%22%0A%20%20%20%20%20%20%20%20A%20number%20represented%20as%20a%20fraction%0A%20%20%20%20%20%20%20%20%22%22%22%0A%20%20%20%20%20%20%20%20def%20__init__(self%2C%20num%2C%20denom)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%22%22%22%20num%20and%20denom%20are%20integers%20%22%22%22%0A%20%20%20%20%20%20%20%20%20%20%20%20assert%20type(num)%20%3D%3D%20int%20and%20type(denom)%20%3D%3D%20int%2C%20%22ints%20not%20used%22%0A%20%20%20%20%20%20%20%20%20%20%20%20self.numerator%20%3D%20num%0A%20%20%20%20%20%20%20%20%20%20%20%20self.denominator%20%3D%20denom%0A%20%20%20%20%20%20%20%20def%20__str__(self)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%22%22%22%20Returns%20a%20string%20representation%20of%20self%20%22%22%22%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20str(self.numerator)%20%2B%20%22%2F%22%20%2B%20str(self.denominator)%0A%20%20%20%20%20%20%20%20def%20__add__(self%2C%20other)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%22%22%22%20Returns%20a%20new%20fraction%20representing%20the%20addition%20%22%22%22%0A%20%20%20%20%20%20%20%20%20%20%20%20top%20%3D%20self.numerator%20*%20other.denominator%20%2B%20self.denominator%20*%20other.numerator%0A%20%20%20%20%20%20%20%20%20%20%20%20bott%20%3D%20self.denominator%20*%20other.denominator%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20YourFraction(top%2C%20bott)%0A%20%20%20%20%20%20%20%20def%20__sub__(self%2C%20other)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%22%22%22%20Returns%20a%20new%20fraction%20representing%20the%20subtraction%20%22%22%22%0A%20%20%20%20%20%20%20%20%20%20%20%20top%20%3D%20self.numerator%20*%20other.denominator%20-%20self.denominator%20*%20other.numerator%0A%20%20%20%20%20%20%20%20%20%20%20%20bott%20%3D%20self.denominator%20*%20other.denominator%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20YourFraction(top%2C%20bott)%0A%20%20%20%20%20%20%20%20def%20__float__(self)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%22%22%22%20Returns%20a%20float%20value%20of%20the%20fraction%20%22%22%22%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20self.numerator%20%2F%20self.denominator%0A%20%20%20%20%20%20%20%20def%20inverse(self)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%22%22%22%20Returns%20a%20new%20fraction%20representing%201%2Fself%20%22%22%22%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20YourFraction(self.denominator%2C%20self.numerator)%0A%0A%20%20%20%20return%20(YourFraction%2C)%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20__(mo)%3A%0A%20%20%20%20mo.md(%0A%20%20%20%20%20%20%20%20r%22%22%22%0A%20%20%20%20%20%20%20%20%23%23%23%23%20Ex.%20%60__getitem__%60%0A%0A%20%20%20%20%20%20%20%20Algumas%20pessoas%20podem%20considerar%20contraintuitivo%20a%20indexa%C3%A7%C3%A3o%20de%20uma%20lista%20%60xs%60%20em%20Python%20ser%20de%20%600%60%20a%20%60len(xs)%20-%201%60%20e%20n%C3%A3o%20de%20%601%60%20a%20%60len(xs)%60.%20Felizmente%2C%20%C3%A9%20poss%C3%ADvel%20criar%20uma%20nova%20classe%20%60List1%60%20que%20possui%20esse%20comportamento%2C%20especificando%20o%20m%C3%A9todo%20%5B%60__getitem__%60%5D(https%3A%2F%2Fdocs.python.org%2F3%2Freference%2Fdatamodel.html%23object.__getitem__)%20apropriado.%20Defina%20a%20classe%20%60List1%60%20com%20o%20comportamento%20desejado%2C%20lhe%20dando%20um%20atributo%20%60_data%60%20que%20armazena%20a%20lista%20Python%20base%2C%20e%20os%20m%C3%A9todos%20de%20lista%20desejados%2C%20entre%20eles%20%60__getitem__%60.%20A%20sua%20implementa%C3%A7%C3%A3o%20ser%C3%A1%20mais%20ou%20menos%20completa%20de%20acordo%20com%20o%20n%C3%BAmero%20e%20qualidade%20dos%20m%C3%A9todos%20implementados%2C%20por%20exemplo%20o%20%60__getitem__%60%20pode%20receber%20como%20argumentos%20inteiros%20positivos%2C%20%5Bslices%5D(https%3A%2F%2Fdocs.python.org%2F3%2Flibrary%2Ffunctions.html%23slice)%20(que%20permitem%20a%20nota%C3%A7%C3%A3o%20%60xs%5B1%3A3%5D%60)%2C%20inteiros%20negativos%2C%20etc.%20Nesse%20exerc%C3%ADcio%2C%20basta%20implementar%20a%20vers%C3%A3o%20mais%20b%C3%A1sica%20de%20%60__getitem__%60%2C%20que%20funciona%20para%20inteiros%20positivos%2C%20mas%20como%20desafio%20outros%20m%C3%A9todos%20podem%20ser%20implementados%2C%20e%20a%20implementa%C3%A7%C3%A3o%20de%20%60__getitem__%60%20pode%20ser%20expandida%20para%20lidar%20com%20%5Bslices%5D(https%3A%2F%2Fdocs.python.org%2F3%2Flibrary%2Ffunctions.html%23slice)%20e%20inteiros%20negativos.%0A%20%20%20%20%20%20%20%20%22%22%22%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20__()%3A%0A%20%20%20%20class%20List1()%3A%0A%20%20%20%20%20%20%20%20def%20__init__(self%2C%20iterable)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20self._data%20%3D%20...%0A%0A%20%20%20%20%20%20%20%20def%20__getitem__(self%2C%20ix)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20...%0A%20%20%20%20return%20(List1%2C)%0A%0A%0A%40app.cell%0Adef%20__(SuaList1)%3A%0A%20%20%20%20SuaList1(%5B1%2C%202%2C%203%5D)%5B1%5D%2C%20SuaList1(%5B1%2C%202%2C%203%5D)%5B2%5D%2C%20SuaList1(%5B1%2C%202%2C%203%5D)%5B3%5D%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20__()%3A%0A%20%20%20%20%23%20solu%C3%A7%C3%A3o%0A%20%20%20%20class%20SuaList1()%3A%0A%20%20%20%20%20%20%20%20def%20__init__(self%2C%20iterable)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20self._data%20%3D%20list(iterable)%0A%0A%20%20%20%20%20%20%20%20def%20__getitem__(self%2C%20ix)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20ls%20%3D%20self._data%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20ix%20%3C%201%20or%20ix%20%3E%20len(ls)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20raise%20IndexError%0A%20%20%20%20%20%20%20%20%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20ls%5Bix%20-%201%5D%0A%20%20%20%20return%20(SuaList1%2C)%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20__(mo)%3A%0A%20%20%20%20mo.md(%0A%20%20%20%20%20%20%20%20r%22%22%22%0A%20%20%20%20%20%20%20%20%23%23%23%23%20Ex.%20list-set%0A%0A%20%20%20%20%20%20%20%20Re-implemente%20o%20tipo%20set%20de%20Python%20usando%20listas.%20Lembre-se%20de%20que%0A%20%20%20%20%20%20%20%20podemos%20ver%20um%20set%20%24s%24%20como%20uma%20lista%20cujos%20elementos%20s%C3%A3o%20%C3%BAnicos.%0A%0A%20%20%20%20%20%20%20%20Abaixo%20fornecemos%20a%20classe%20LSet%20respons%C3%A1vel%20pela%20reimplementa%C3%A7%C3%A3o%3B%0A%20%20%20%20%20%20%20%20voc%C3%AA%20deve%20preencher%20os%20m%C3%A9todos%20vazios.%20Note%20que%20todos%20os%20m%C3%A9todos%0A%20%20%20%20%20%20%20%20da%20classe%20%24LSet%24%20s%C3%A3o%20tamb%C3%A9m%20m%C3%A9todos%20de%20set%2C%20o%20tipo%20de%20conjuntos%20de%0A%20%20%20%20%20%20%20%20Python.%20O%20comportamento%20dos%20m%C3%A9todos%20de%20LSet%20deve%20ser%20igual%20aos%20dos%0A%20%20%20%20%20%20%20%20m%C3%A9todos%20correspondentes%20de%20set%2C%20salvo%20o%20uso%20de%20exce%C3%A7%C3%B5es%2Ferros%2C%20cuja%20implementa%C3%A7%C3%A3o%20%C3%A9%20opcional.%0A%0A%20%20%20%20%20%20%20%20Naturalmente%2C%20suas%20solu%C3%A7%C3%B5es%20n%C3%A3o%20devem%20usar%20os%20m%C3%A9todos%20de%20set%20em%0A%20%20%20%20%20%20%20%20momento%20algum%3B%20n%C3%A3o%20vale%20converter%20um%20LSet%20para%20um%20set%20e%20ent%C3%A3o%0A%20%20%20%20%20%20%20%20chamar%20o%20m%C3%A9todo%20correspondente.%0A%0A%20%20%20%20%20%20%20%20**Observe%20como%20a%20cria%C3%A7%C3%A3o%20de%20uma%20classe%20nos%20permite%20esconder%20a%20forma%20de%20implementa%C3%A7%C3%A3o%20do%20novo%20tipo%20de%20conjuntos.%20Se%20quis%C3%A9ssemos%20modificar%20a%20implementa%C3%A7%C3%A3o%20%E2%80%94%20para%20uma%20mais%20r%C3%A1pida%2C%20por%20exemplo%20%E2%80%94%20sua%20interface%20seria%20a%20mesma.%20Como%20o%20c%C3%B3digo%20para%20criar%20e%20manipular%20conjuntos%20n%C3%A3o%20mudaria%2C%20o%20c%C3%B3digo%20dos%20usu%C3%A1rios%20da%20classe%20n%C3%A3o%20precisa%20ser%20modificado%20de%20forma%20alguma.**%0A%20%20%20%20%20%20%20%20%22%22%22%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20__()%3A%0A%20%20%20%20class%20LSet%3A%0A%20%20%20%20%20%20%20%20def%20__init__(self%2C%20iterable%3DNone)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%22%22%22LSet%20objects%20have%20a%20single%20attribute%3A%0A%0A%20%20%20%20_data%3A%20the%20set's%20elements%2C%20inside%20a%20list%20whose%20elements%20are%20all%20unique%20and%20sorted%0A%20%20%20%20%22%22%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20TODO%3A%20checar%20se%20os%20elementos%20s%C3%A3o%20%C3%BAnicos%3B%20crie%20uma%20fun%C3%A7%C3%A3o%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20que%20recebe%20uma%20lista%20ordenada%20e%20retorna%20uma%20nova%20lista%20sem%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20duplicatas%20(como%20a%20lista%20est%C3%A1%20ordenada%2C%20voc%C3%AA%20s%C3%B3%20precisa%20de%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20verificar%20se%20o%20elemento%20anterior%20%C3%A9%20igual%20ao%20corrente)%0A%20%20%20%20%20%20%20%20%20%20%20%20self._data%20%3D%20list(sorted(iterable))%20%5C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20iterable%20is%20not%20None%20%5C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20else%20list()%0A%0A%20%20%20%20%20%20%20%20def%20__iter__(self)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20implements%20iteration%20(for%20x%20in%20lset)%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20self._data.__iter__()%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%23%20we%20could%20also%20do%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20for%20m%20in%20self._data%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20%20%20%20%20yield%20m%0A%0A%20%20%20%20%20%20%20%20def%20__eq__(self%2C%20value)%3A%20%23%20defines%20equality%20(%3D%3D)%20for%20LSet%20type%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20isinstance(value%2C%20LSet)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%23%20two%20LSets%20are%20equal%20when%20their%20_data%20is%20the%20same%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%23%20because%20the%20list%20in%20_data%20is%20sorted%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20self._data%20%3D%3D%20value._data%0A%20%20%20%20%20%20%20%20%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%23%20a%20LSet%20can%20only%20be%20equal%20to%20another%20LSet%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20False%0A%0A%20%20%20%20%20%20%20%20def%20__contains__(self%2C%20value)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20implements%20in%20operator%0A%20%20%20%20%20%20%20%20%20%20%20%20...%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20False%0A%0A%20%20%20%20%20%20%20%20def%20__len__(self)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20...%0A%20%20%20%20%20%20%20%20%20%20%20%20return%200%0A%0A%20%20%20%20%20%20%20%20def%20add(self%2C%20value)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20when%20adding%20a%20member%2C%20must%20make%20sure%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20to%20keep%20elements%20in%20order%0A%20%20%20%20%20%20%20%20%20%20%20%20...%0A%0A%20%20%20%20%20%20%20%20def%20__str__(self)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20print(LSet(1%2C2%2C3))%20deve%20ser%20o%20mesmo%20que%20print(%7B1%2C2%2C3%7D)%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%23%20DICA%3A%20use%20str.join%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20DICA%3A%20chame%20__str__%20nos%20membros%20do%20LSet%0A%20%20%20%20%20%20%20%20%20%20%20%20...%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20%22%22%0A%0A%20%20%20%20%20%20%20%20def%20clear(self)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20...%0A%0A%20%20%20%20%20%20%20%20def%20discard(self%2C%20value)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20...%0A%0A%20%20%20%20%20%20%20%20def%20difference(self%2C%20olset)%3A%20%23%20should%20return%20a%20new%20LSet%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20isinstance(olset%2C%20LSet)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20new%20%3D%20LSet()%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20...%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20new%0A%20%20%20%20%20%20%20%20%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%23%20gera%20um%20erro%20de%20tipo%20TypeError%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20raise%20TypeError(%22Other%20object%20is%20not%20a%20LSet%22)%0A%0A%20%20%20%20%20%20%20%20def%20intersection(self%2C%20olset)%3A%20%23%20should%20return%20a%20new%20LSet%0A%20%20%20%20%20%20%20%20%20%20%20%20new%20%3D%20LSet()%0A%20%20%20%20%20%20%20%20%20%20%20%20...%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20new%0A%0A%20%20%20%20%20%20%20%20def%20union(self%2C%20olset)%3A%20%23%20should%20return%20a%20new%20LSet%0A%20%20%20%20%20%20%20%20%20%20%20%20new%20%3D%20LSet()%0A%20%20%20%20%20%20%20%20%20%20%20%20...%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20new%0A%20%20%20%20return%20(LSet%2C)%0A%0A%0A%40app.cell%0Adef%20__(SuaLSet)%3A%0A%20%20%20%20initial_elements%20%3D%20%5B4%2C%203%2C%201%2C%201%2C%206%2C%200%2C%20-1%5D%0A%20%20%20%20a%20%3D%20SuaLSet(initial_elements)%0A%20%20%20%20b%20%3D%20SuaLSet(initial_elements)%0A%20%20%20%20print(%22LSets%20are%20equal%3A%22%2C%20a%20%3D%3D%20b)%0A%20%20%20%20print(%22LSets%20contain%20the%20number%201%3A%22%2C%201%20in%20a%20and%201%20in%20b)%0A%20%20%20%20print(%22LSet%20uses%20set%20notation%3A%22%2C%20a)%0A%20%20%20%20a.add(5)%0A%20%20%20%20n%20%3D%20len(a)%0A%20%20%20%20print(%22LSets%20size%20increase%20after%20new%20element%3A%22%2C%20n%20%3E%20len(b))%0A%20%20%20%20a.add(5)%0A%20%20%20%20print(%22LSet%20size%20doesn't%20increase%20after%20inserting%20existing%20member%3A%22%2C%20len(a)%20%3D%3D%20n)%0A%20%20%20%20a.discard(5)%0A%20%20%20%20print(%22Discarding%20element%20reduces%20set%20length%3A%22%2C%20len(a)%20%3C%20n)%0A%20%20%20%20a.clear()%0A%20%20%20%20print(%22Cleared%20set%20has%20zero%20length%3A%22%2C%20len(a)%20%3D%3D%200)%0A%20%20%20%20c%20%3D%20b.difference(a)%0A%20%20%20%20print(%22Difference%20with%20empty%20LSet%20is%20original%20LSet%3A%22%2C%20c%20%3D%3D%20b)%0A%20%20%20%20d%20%3D%20a.difference(b)%0A%20%20%20%20print(%22Difference%20of%20empty%20LSet%20is%20empty%20LSet%3A%22%2C%20d%20%3D%3D%20a)%0A%20%20%20%20print(%22Difference%20of%20LSet%20with%20itself%20is%20empty%20LSet%3A%22%2C%20b.difference(b)%20%3D%3D%20a)%0A%20%20%20%20print(%22Intersection%20of%20LSet%20with%20itself%20is%20itself%3A%22%2C%20b.intersection(b)%20%3D%3D%20b)%0A%20%20%20%20print(%22Intersection%20of%20LSet%20with%20empty%20LSet%20is%20empty%3A%22%2C%20b.intersection(d)%20%3D%3D%20d)%0A%20%20%20%20print(%22Union%20of%20LSet%20with%20empty%20LSet%20is%20itself%3A%22%2C%20b.union(d)%20%3D%3D%20b)%0A%20%20%20%20return%20a%2C%20b%2C%20c%2C%20d%2C%20initial_elements%2C%20n%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20__(LSet)%3A%0A%20%20%20%20%23%20solu%C3%A7%C3%A3o%0A%20%20%20%20def%20remove_duplicates_ordered(iterable)%3A%0A%20%20%20%20%20%20%20%20res%20%3D%20%5B%5D%0A%20%20%20%20%20%20%20%20if%20iterable%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20res.append(iterable%5B0%5D)%0A%20%20%20%20%20%20%20%20for%20e%20in%20iterable%5B1%3A%5D%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20e%20%3D%3D%20res%5B-1%5D%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20continue%0A%20%20%20%20%20%20%20%20%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20res.append(e)%0A%20%20%20%20%20%20%20%20return%20res%0A%0A%20%20%20%20class%20SuaLSet(LSet)%3A%0A%20%20%20%20%20%20%20%20def%20__init__(self%2C%20iterable%3DNone)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%22%22%22LSet%20objects%20have%20a%20single%20attribute%3A%0A%0A%20%20%20%20_data%3A%20the%20set's%20elements%2C%20inside%20a%20list%20whose%20elements%20are%20all%20unique%20and%20sorted%0A%20%20%20%20%22%22%22%0A%20%20%20%20%20%20%20%20%20%20%20%20self._data%20%3D%20remove_duplicates_ordered(sorted(iterable))%20if%20iterable%20is%20not%20None%20else%20list()%0A%0A%20%20%20%20%20%20%20%20def%20__iter__(self)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20self._data.__iter__()%0A%0A%20%20%20%20%20%20%20%20def%20__eq__(self%2C%20value)%3A%20%23%20defines%20equality%20(%3D%3D)%20for%20LSet%20type%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20isinstance(value%2C%20LSet)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%23%20two%20LSets%20are%20equal%20when%20their%20_data%20is%20the%20same%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%23%20because%20the%20list%20in%20_data%20is%20sorted%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20self._data%20%3D%3D%20value._data%0A%20%20%20%20%20%20%20%20%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%23%20a%20LSet%20can%20only%20be%20equal%20to%20another%20LSet%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20False%0A%0A%20%20%20%20%20%20%20%20def%20__contains__(self%2C%20value)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20implements%20in%20operator%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20m%20in%20self._data%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20m%20%3D%3D%20value%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20True%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20elif%20m%20%3E%20value%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%23%20if%20_data%20is%20ordered%2C%20value%20is%20not%20present%20in%20this%20case%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20break%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20False%0A%0A%20%20%20%20%20%20%20%20def%20__len__(self)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20len(self._data)%0A%0A%20%20%20%20%20%20%20%20def%20add(self%2C%20value)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20when%20adding%20a%20member%2C%20must%20make%20sure%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20to%20keep%20elements%20in%20order%0A%20%20%20%20%20%20%20%20%20%20%20%20members%20%3D%20self._data%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20i%20in%20range(len(members))%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20m%20%3D%20members%5Bi%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20m%20%3D%3D%20value%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%23%20value%20already%20among%20members%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20break%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%23%20insert%20before%20first%20member%20that%20is%20larger%20than%20value%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20elif%20m%20%3E%20value%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20members.insert(i%2C%20value)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20break%0A%20%20%20%20%20%20%20%20%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%23%20insert%20at%20last%20position%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20members.append(value)%0A%0A%0A%20%20%20%20%20%20%20%20def%20__str__(self)%3A%20%23%20print(LSet(1%2C2%2C3))%20deve%20ser%20o%20mesmo%20que%20print(%7B1%2C2%2C3%7D)%0A%20%20%20%20%20%20%20%20%20%20%20%20members%20%3D%20%22%2C%22.join(map(lambda%20x%3A%20x.__str__()%2C%20self._data))%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20f'%7B%7B%7Bmembers%7D%7D%7D'%0A%0A%20%20%20%20%20%20%20%20def%20clear(self)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20self._data%20%3D%20list()%0A%0A%20%20%20%20%20%20%20%20def%20discard(self%2C%20value)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20self._data.remove(value)%0A%0A%20%20%20%20%20%20%20%20def%20difference(self%2C%20olset)%3A%20%23%20should%20return%20a%20new%20LSet%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20isinstance(olset%2C%20LSet)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20new%20%3D%20SuaLSet()%20%23%20Mude%20para%20LSet%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20for%20m%20in%20self._data%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20m%20not%20in%20olset%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20new.add(m)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20new%0A%20%20%20%20%20%20%20%20%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20raise%20TypeError(%22Other%20object%20is%20not%20a%20LSet%22)%0A%0A%20%20%20%20%20%20%20%20def%20intersection(self%2C%20olset)%3A%20%23%20should%20return%20a%20new%20LSet%0A%20%20%20%20%20%20%20%20%20%20%20%20new%20%3D%20SuaLSet()%20%23%20Mude%20para%20LSet%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20m%20in%20self._data%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20m%20in%20olset%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20new.add(m)%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20new%0A%0A%20%20%20%20%20%20%20%20def%20union(self%2C%20olset)%3A%20%23%20should%20return%20a%20new%20LSet%0A%20%20%20%20%20%20%20%20%20%20%20%20new%20%3D%20SuaLSet(olset)%20%23%20Mude%20para%20LSet%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20m%20in%20self._data%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20new.add(m)%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20new%0A%20%20%20%20return%20SuaLSet%2C%20remove_duplicates_ordered%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20__(mo)%3A%0A%20%20%20%20mo.md(%0A%20%20%20%20%20%20%20%20r%22%22%22%0A%20%20%20%20%20%20%20%20%23%23%23%23%20Ex.%20classify-wines%0A%0A%20%20%20%20%20%20%20%20Voc%C3%AA%20administra%20uma%20adega%20de%20vinhos%20raros.%20Os%20vinhos%20s%C3%A3o%20comprados%0A%20%20%20%20%20%20%20%20pelo%20barril%2C%20e%20uma%20pequena%20amostra%20%C3%A9%20retirada%20no%20momento%20da%20aquisi%C3%A7%C3%A3o%0A%20%20%20%20%20%20%20%20para%20an%C3%A1lise%20de%20suas%20caracter%C3%ADsticas.%20Infelizmente%2C%20alguns%20barris%0A%20%20%20%20%20%20%20%20tiveram%20seus%20r%C3%B3tulos%20danificados%2C%20e%20foram%20perdidas%20todas%20as%0A%20%20%20%20%20%20%20%20informa%C3%A7%C3%B5es%20sobre%20os%20vinhos%20neles%20contidos%2C%20exceto%20duas%20de%20suas%0A%20%20%20%20%20%20%20%20caracter%C3%ADsticas%20bioqu%C3%ADmicas.%0A%0A%20%20%20%20%20%20%20%20Voc%C3%AA%20n%C3%A3o%20quer%20abrir%20os%20barris%20prematuramente%2C%20mas%20gostaria%20de%20pelo%0A%20%20%20%20%20%20%20%20menos%20estimar%20seu%20estilo%2C%20isto%20%C3%A9%2C%20se%20eles%20s%C3%A3o%20vinhos%20vermelhos%20ou%0A%20%20%20%20%20%20%20%20brancos.%20Uma%20maneira%20%C3%A9%20%E2%80%9Cestimar%E2%80%9D%20o%20estilo%20a%20partir%20do%20estilo%20dos%0A%20%20%20%20%20%20%20%20vinhos%20mais%20%E2%80%9Cpr%C3%B3ximos%E2%80%9D%2C%20em%20termos%20de%20caracter%C3%ADsticas%20conhecidas.%0A%0A%20%20%20%20%20%20%20%20O%20m%C3%A9todo%20pode%20ser%20descrito%20como%20se%20segue%3A%0A%0A%20%20%20%20%20%20%20%20-%20listar%20todos%20os%20barris%20conhecidos%20e%20suas%20caracter%C3%ADsticas%0A%20%20%20%20%20%20%20%20%20%20bioqu%C3%ADmicas%3B%0A%20%20%20%20%20%20%20%20-%20para%20cada%20barril%20desconhecido%2C%20determinar%20os%20tr%C3%AAs%20barris%20mais%0A%20%20%20%20%20%20%20%20%20%20parecidos%2C%20de%20acordo%20com%20as%20caracter%C3%ADsticas%20bioqu%C3%ADmicas%20dispon%C3%ADveis%3B%0A%20%20%20%20%20%20%20%20-%20classificar%20o%20barril%20desconhecido%20de%20acordo%20com%20o%20estilo%20da%20maioria%0A%20%20%20%20%20%20%20%20%20%20dos%20tr%C3%AAs%20barris%20mais%20parecidos.%0A%0A%20%20%20%20%20%20%20%20Para%20determinar%20se%20dois%20vinhos%20s%C3%A3o%20parecidos%2C%20consideramos%20as%20duas%0A%20%20%20%20%20%20%20%20caracter%C3%ADsticas%20bioqu%C3%ADmicas%20dos%20vinhos%20como%20vetores%20do%20%24%5Cmathbb%7BR%7D%5E2%24%2C%0A%20%20%20%20%20%20%20%20e%20calculamos%20a%20dist%C3%A2ncia%20euclidiana%20entre%20eles%3A%20%0A%20%20%20%20%20%20%20%20%24%24d(u%2C%20v)%20%3D%20%5Csqrt%7B(u_1%20-%20v_1)%5E2%20%2B%20(u_2%20-%20v_2)%5E2%7D%24%24%0A%0A%20%20%20%20%20%20%20%20Quanto%20menor%20a%20dist%C3%A2ncia%20entre%20os%20vetores%20de%20dois%20vinhos%2C%20mais%20parecidos%20eles%20s%C3%A3o.%20Portanto%2C%20os%20tr%C3%AAs%20vinhos%20conhecidos%20mais%20parecidos%20com%20um%20vinho%20desconhecido%20s%C3%A3o%20aqueles%20com%20menores%20valores%20de%20dist%C3%A2ncia%20euclidiana.%0A%0A%20%20%20%20%20%20%20%20Crie%20uma%20classe%20%60WineClassifier%60.%20A%20classe%20deve%20ter%20um%20atributo%20%60_data%60%20que%20armazena%20as%20caracter%C3%ADsticas%20bioqu%C3%ADmicas%20dos%20vinhos%20conhecidos%2C%20um%20atributo%20%60_target%60%20que%20armazena%20os%20estilos%20dos%20vinhos%20conhecidos%20(de%20tal%20modo%20que%20%60self._data%5Bi%5D%60%20corresponda%20%C3%A0s%20caracter%C3%ADsticas%20bioqu%C3%ADmicas%20do%20vinho%20de%20estilo%20%60self._target%5Bi%5D%60%2C%20para%20qualquer%20%60i%60)%2C%20al%C3%A9m%20de%20dois%20m%C3%A9todos%3A%20%0A%0A%20%20%20%20%20%20%20%20-%20%60fit%60%20tem%20dois%20par%C3%A2metros%3A%20uma%20lista%20de%20listas%20de%20dois%20elementos%2C%20cada%20um%20deles%20sendo%20floats%20representando%20caracter%C3%ADsticas%20bioqu%C3%ADmicas%20de%20vinhos%2C%20e%20uma%20lista%20de%20inteiros%20representando%20o%20estilo%20do%20vinho%20(1%20para%20vermelho%20e%200%20para%20branco).%20Este%20%C3%A9%20o%20chamado%20tamb%C3%A9m%20chamado%20de%20conjunto%20de%20treinamento%3B%0A%20%20%20%20%20%20%20%20-%20%60predict%60%20tem%20como%20%C3%BAnico%20par%C3%A2metro%20uma%20lista%20de%20dois%20caracter%C3%ADsticas%20bioqu%C3%ADmicas%20de%20um%20vinho%20de%20estilo%20desconhecido%2C%20e%20prediz%20qual%20%C3%A9%20o%20estilo%20desse%20vinho%20usando%20o%20algoritmo%20descrito%20acima%2C%20apoiado%20nos%20dados%20de%20treinamento%20armazenados%20como%20atributo%20da%20classe.%0A%0A%20%20%20%20%20%20%20%20%23%23%23%23%23%23%20Dica%0A%0A%20%20%20%20%20%20%20%20Para%20encontrar%20os%20tr%C3%AAs%20vinhos%20mais%20parecidos%2C%20voc%C3%AA%20precisar%C3%A1%20ordenar%20a%20lista%20de%20estilos%20de%20acordo%20com%20a%20dist%C3%A2ncia%20entre%20os%20vinhos%20correspondentes.%20Para%20tal%2C%20usamos%20o%20m%C3%A9todo%20%60list.sort%60%2C%20ou%20ent%C3%A3o%20a%20fun%C3%A7%C3%A3o%20%60sorted%60.%20Se%20a%20lista%20em%20quest%C3%A3o%20%C3%A9%20uma%20lista%20de%20listas%2C%20o%20Python%20por%20padr%C3%A3o%20faz%20uma%20compara%C3%A7%C3%A3o%20elemento%20a%20elemento%20dos%20elementos%20da%20lista%2C%20priorizando%20os%20elementos%20que%20vem%20primeiro%20na%20lista%20(o%20nome%20dessa%20ordem%20%C3%A9%20lexicogr%C3%A1fica%2C%20e%20%C3%A9%20a%20ordem%20que%20usamos%20para%20colocar%20uma%20lista%20de%20nomes%20em%20ordem%20alfab%C3%A9tica).%0A%0A%20%20%20%20%20%20%20%20Tanto%20o%20m%C3%A9todo%20%60list.sort%60%20quanto%20a%20fun%C3%A7%C3%A3o%20%60sorted%60%20permitem%20que%20especifiquemos%20uma%20forma%20diferente%20de%20ordenar%20uma%20lista.%20Isso%20nos%20permite%20ordenar%20uma%20lista%20de%20acordo%20com%20crit%C3%A9rios%20pr%C3%B3prios%2C%20veja%20%60help(sorted)%60%20ou%20%60help(list.sort)%60.%20Tamb%C3%A9m%20%C3%A9%20poss%C3%ADvel%20ordenar%20uma%20lista%20de%20acordo%20com%20outra%20lista%2C%20usando%20o%20seguinte%20truque%3A%20a%20lista%20principal%20deve%20ter%20o%20mesmo%20n%C3%BAmero%20de%20elementos%20da%20lista%20auxiliar%20que%20usaremos%20para%20ordenar%3B%20a%20ordena%C3%A7%C3%A3o%20%C3%A9%20feita%20em%20%60range(len(lista_principal))%60%2C%20e%20com%20o%20par%C3%A2metro%20%60key%60%20especificamos%20que%20para%20um%20elemento%20de%20%60range(len(lista_principal))%60%20%E2%80%94%20que%20tamb%C3%A9m%20%C3%A9%20um%20%C3%ADndice%20na%20lista%20auxiliar%2C%20j%C3%A1%20que%20%60len(lista_principal)%20%3D%3D%20len(lista_auxiliar)%60%20%E2%80%94%20usaramos%20o%20elemento%20correspondente%20da%20lista_auxiliar%20como%20base%20da%20compara%C3%A7%C3%A3o.%20Como%20argumento%20%60key%60%20passamos%20ent%C3%A3o%20uma%20fun%C3%A7%C3%A3o%20que%20recebe%20um%20elemento%20da%20lista%20que%20est%C3%A1%20sendo%20ordenada%2C%20e%20retorna%20o%20valor%20que%20queremos%20usar%20para%20compara%C3%A7%C3%A3o%2C%20veja%3A%0A%0A%20%20%20%20%20%20%20%20%60%60%60python%0A%20%20%20%20%20%20%20%20conhecidos_estilos%20%3D%20%5B0%2C%200%2C%201%2C%200%2C%201%2C%201%2C%201%2C%200%2C%200%2C%201%5D%0A%20%20%20%20%20%20%20%20distancias%20%3D%20%5B0.8%2C%201.1%2C%205.2%2C%201.11%2C%202.32%2C%201.87%2C%200.76%2C%200.29%2C%200.14%2C%200.57%5D%0A%0A%20%20%20%20%20%20%20%20indices_ordenados%20%3D%20sorted(range(len(conhecidos_estilos))%2C%20key%3Dlambda%20i%3A%20distancias%5Bi%5D)%0A%20%20%20%20%20%20%20%20conhecidos_estilos%5Bindices_ordenados%5B0%5D%5D%20%23%20estilo%20do%20vinho%20com%20menor%20dist%C3%A2ncia%0A%20%20%20%20%20%20%20%20%60%60%60%0A%20%20%20%20%20%20%20%20%22%22%22%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20__()%3A%0A%20%20%20%20class%20WineClassifier()%3A%0A%20%20%20%20%20%20%20%20def%20__init__(self)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20self._data%20%3D%20list()%0A%20%20%20%20%20%20%20%20%20%20%20%20self._target%20%3D%20list()%0A%0A%20%20%20%20%20%20%20%20def%20fit(self%2C%20X%2C%20y)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20...%0A%0A%20%20%20%20%20%20%20%20def%20predict(self%2C%20x)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20...%0A%20%20%20%20return%20(WineClassifier%2C)%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20__()%3A%0A%20%20%20%20vinhos_conhecidos%20%3D%20%5B%5B0.7%2C%200.56%2C%201.0%5D%2C%20%5B0.88%2C%200.68%2C%201.0%5D%2C%20%5B0.76%2C%200.65%2C%201.0%5D%2C%20%5B0.28%2C%200.58%2C%201.0%5D%2C%20%5B0.7%2C%200.56%2C%201.0%5D%2C%20%5B0.66%2C%200.56%2C%201.0%5D%2C%20%5B0.6%2C%200.46%2C%201.0%5D%2C%20%5B0.65%2C%200.47%2C%201.0%5D%2C%20%5B0.58%2C%200.57%2C%201.0%5D%2C%20%5B0.5%2C%200.8%2C%201.0%5D%2C%20%5B0.58%2C%200.54%2C%201.0%5D%2C%20%5B0.5%2C%200.8%2C%201.0%5D%2C%20%5B0.615%2C%200.52%2C%201.0%5D%2C%20%5B0.61%2C%201.56%2C%201.0%5D%2C%20%5B0.62%2C%200.88%2C%201.0%5D%2C%20%5B0.62%2C%200.93%2C%201.0%5D%2C%20%5B0.28%2C%200.75%2C%201.0%5D%2C%20%5B0.56%2C%201.28%2C%201.0%5D%2C%20%5B0.59%2C%200.5%2C%201.0%5D%2C%20%5B0.32%2C%201.08%2C%201.0%5D%2C%20%5B0.22%2C%200.53%2C%201.0%5D%2C%20%5B0.39%2C%200.65%2C%201.0%5D%2C%20%5B0.43%2C%200.91%2C%201.0%5D%2C%20%5B0.49%2C%200.53%2C%201.0%5D%2C%20%5B0.4%2C%200.63%2C%201.0%5D%2C%20%5B0.39%2C%200.56%2C%201.0%5D%2C%20%5B0.41%2C%200.59%2C%201.0%5D%2C%20%5B0.43%2C%200.91%2C%201.0%5D%2C%20%5B0.71%2C%200.55%2C%201.0%5D%2C%20%5B0.645%2C%200.59%2C%201.0%5D%2C%20%5B0.27%2C%200.45%2C%200.0%5D%2C%20%5B0.3%2C%200.49%2C%200.0%5D%2C%20%5B0.28%2C%200.44%2C%200.0%5D%2C%20%5B0.23%2C%200.4%2C%200.0%5D%2C%20%5B0.23%2C%200.4%2C%200.0%5D%2C%20%5B0.28%2C%200.44%2C%200.0%5D%2C%20%5B0.32%2C%200.47%2C%200.0%5D%2C%20%5B0.27%2C%200.45%2C%200.0%5D%2C%20%5B0.3%2C%200.49%2C%200.0%5D%2C%20%5B0.22%2C%200.45%2C%200.0%5D%2C%20%5B0.27%2C%200.56%2C%200.0%5D%2C%20%5B0.23%2C%200.53%2C%200.0%5D%2C%20%5B0.18%2C%200.63%2C%200.0%5D%2C%20%5B0.16%2C%200.52%2C%200.0%5D%2C%20%5B0.42%2C%200.67%2C%200.0%5D%2C%20%5B0.17%2C%200.55%2C%200.0%5D%2C%20%5B0.48%2C%200.36%2C%200.0%5D%2C%20%5B0.66%2C%200.39%2C%200.0%5D%2C%20%5B0.34%2C%200.53%2C%200.0%5D%2C%20%5B0.31%2C%200.5%2C%200.0%5D%2C%20%5B0.66%2C%200.39%2C%200.0%5D%2C%20%5B0.31%2C%200.35%2C%200.0%5D%2C%20%5B0.26%2C%200.48%2C%200.0%5D%2C%20%5B0.67%2C%200.51%2C%200.0%5D%2C%20%5B0.27%2C%200.47%2C%200.0%5D%2C%20%5B0.25%2C%200.5%2C%200.0%5D%2C%20%5B0.24%2C%200.44%2C%200.0%5D%2C%20%5B0.28%2C%200.53%2C%200.0%5D%2C%20%5B0.27%2C%200.49%2C%200.0%5D%2C%20%5B0.32%2C%200.71%2C%200.0%5D%5D%0A%0A%20%20%20%20vinhos_desconhecidos%20%3D%20%5B%0A%20%20%20%20%5B0.685%2C0.57%5D%2C%0A%20%20%20%20%5B0.655%2C0.66%5D%2C%0A%20%20%20%20%5B0.605%2C0.52%5D%2C%0A%20%20%20%20%5B0.32%2C0.55%5D%2C%0A%20%20%20%20%5B0.675%2C0.54%5D%2C%0A%20%20%20%20%5B0.24%2C0.53%5D%2C%0A%20%20%20%20%5B0.14%2C0.4%5D%2C%0A%20%20%20%20%5B0.25%2C0.44%5D%2C%0A%20%20%20%20%5B0.12%2C0.51%5D%2C%0A%20%20%20%20%5B0.27%2C0.37%5D%2C%0A%20%20%20%20%5D%0A%20%20%20%20return%20vinhos_conhecidos%2C%20vinhos_desconhecidos%0A%0A%0A%40app.cell%0Adef%20__(SuaWineClassifier%2C%20vinhos_conhecidos%2C%20vinhos_desconhecidos)%3A%0A%20%20%20%20clf%20%3D%20SuaWineClassifier()%0A%20%20%20%20X%20%3D%20%5B%5Bf1%2C%20f2%5D%20for%20f1%2C%20f2%2C%20_estilo%20in%20vinhos_conhecidos%5D%0A%20%20%20%20y%20%3D%20%5Bestilo%20for%20_f1%2C%20_f2%2C%20estilo%20in%20vinhos_conhecidos%5D%0A%20%20%20%20%23%23%20alternativamente%2C%0A%20%20%20%20%23%20f1%2C%20f2%2C%20y%20%3D%20zip(*vinhos_conhecidos)%0A%20%20%20%20%23%20X%20%3D%20zip(f1%2C%20f2)%0A%20%20%20%20clf.fit(X%2C%20y)%0A%20%20%20%20%5Bclf.predict(vinho)%20for%20vinho%20in%20vinhos_desconhecidos%5D%0A%20%20%20%20return%20X%2C%20clf%2C%20y%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20__()%3A%0A%20%20%20%20%23%20solu%C3%A7%C3%A3o%0A%20%20%20%20def%20euclidean_distance(x1%2C%20x2)%3A%0A%20%20%20%20%20%20%20%20soma%20%3D%200%0A%20%20%20%20%20%20%20%20for%20i%20in%20range(len(x1))%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20soma%20%3D%20soma%20%2B%20(x1%5Bi%5D%20-%20x2%5Bi%5D)%20**%202%0A%20%20%20%20%20%20%20%20return%20soma%20**%200.5%0A%0A%20%20%20%20class%20SuaWineClassifier()%3A%0A%20%20%20%20%20%20%20%20def%20__init__(self)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20self._data%20%3D%20list()%0A%0A%20%20%20%20%20%20%20%20def%20fit(self%2C%20X%2C%20y)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20self._data%20%3D%20X%0A%20%20%20%20%20%20%20%20%20%20%20%20self._target%20%3D%20y%0A%0A%20%20%20%20%20%20%20%20def%20predict(self%2C%20x%2C%20k%3D3)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20dists%20%3D%20%5B%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20styles%20%3D%20self._target%0A%20%20%20%20%20%20%20%20%20%20%20%20n%20%3D%20len(styles)%0A%20%20%20%20%20%20%20%20%20%20%20%20assert%20n%20%3D%3D%20len(self._data)%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20feats%20in%20self._data%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20dists.append(euclidean_distance(x%2C%20feats))%0A%20%20%20%20%20%20%20%20%20%20%20%20closest_idxs%20%3D%20sorted(range(n)%2C%20key%3Dlambda%20i%3A%20dists%5Bi%5D)%5B%3Ak%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20estimate%20style%20as%20the%20majority%20style%20(style%20is%200%20or%201)%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%23%20you%20could%20just%20use%20%3E%3D%202%20as%20the%20question%20asked%20for%20k%3D3%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20sum(%5Bstyles%5Bi%5D%20for%20i%20in%20closest_idxs%5D)%20%3E%3D%20(k%20%2F%2F%202)%20%2B%201%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%201%0A%20%20%20%20%20%20%20%20%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%200%0A%20%20%20%20return%20SuaWineClassifier%2C%20euclidean_distance%0A%0A%0A%40app.cell%0Adef%20__()%3A%0A%20%20%20%20return%0A%0A%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20app.run()%0A
507c0d47e68d7f025ed30fde8d1f317787f1509bca9610b40c82855440ebaaad