<jupyter_start><jupyter_text>Příklad o limonádě (nebo čemkoli prodejném)* témata: Ekonomie, křivka poptávky, kvadratická funkce, interpolace funkce v Pythonu. Zadání* Rozhodneš se míchat limonádu a prodávat ji na ulici.* Otázka je, kolik si za ni říct, abys maximalizoval zisk?* V ekonomii se tímto zabývá *křivka poptávky*, která nám dává do souvislosti vztah mezi cenou produktu a poptávkou po něm.* Začněme nejjednodušším případem, kdy křivka poptávky vypadá následovně:<jupyter_code>from IPython.display import Image
Image('../../resource/fig/poptavka_lim.png', retina=True)<jupyter_output><empty_output><jupyter_text>* Význam je, že při navýšení ceny limonády (posun po ose x doprava), méně lidí si ji bude ochotno koupit. Poptávka se snižuje.* Při ceně 100 si limonádu nekoupí už nikdo.* Naopak zadarmo (cena=0) se zbavíš všech limonád.* Vyrobit limonádu je celkem levné ale zadarmo to není, cena výroby bude 10 peněz.* Počáteční investice do odšťavňovače citrónů je 1000 peněz. Otázky* Jakou si zvolíš cenu limonády, abys měl co největší profit ze 100 limonád?* Když si vezmeme za příklad změřenou poptávku z experimentu na lidech, vyděláme víc, či míň? ------ Pokud je toto tvůj první Jupyter Notebook:* Buňka (cell) se provede kombinací `Shift-Enter`, musíš v ní mít ale kurzor.* Po úspěšném proběhnutí buňky se objeví nalevo od ní "pořadové" číslo průběhu.* Provedení buňky a vytvoření nové prázdné pod ní, použij `Alt-Enter`.* Jakýkoli text za znakem  je komentář a Python ho ignoruje až do konce řádku.* Pozor: Pokud proběhneš prázdnou buňku, která má pod sebou výstup jako nápovědu, nápověda ti zmizí, proto `Alt-Enter`.------<jupyter_code># importuj staré dobré moduly
import numpy as np
import matplotlib.pyplot as plt

# pokročilý trik, který umožňuje měnit parametry vašich grafů pro celý sešit
import matplotlib as mpl
mpl.rcParams['figure.figsize'] = [8,6] # velikost grafu
mpl.rcParams['lines.linewidth'] = 3  # tloušťka čáry
mpl.rcParams['lines.markersize'] = 10  # velikokost bodů v grafu
mpl.rcParams['xtick.labelsize'] = 12  # velikost fontu popisků osových bodů x
mpl.rcParams['ytick.labelsize'] = 12 # velikost fontu popisků osových bodů y
mpl.rcParams['axes.labelsize'] = 'larger'  # velikost fontu názvu os

# odkomentováním příkazu vypíšete všechny nastavitelné vlastnosti
# svobodě Python meze rozhodně neklade:)
# mpl.rcParams.keys() 
# definuj osu ceny limonády
cena = 
# Jaká je rovnice naší poptávky (ve tvaru popt = a*cena + b) ze zadání?
# Pro výpočet a,b můžeš využít dvou bodů, 
# které protínají osy x(popt=0) a y(cena=0).
a = 
b =<jupyter_output><empty_output><jupyter_text>* Pozor, graf vyjadřuje zlomek prodaných limonád, lze ho tedy chápat jako poptávku po jedné limonádě.* Reálně s každou další limonádou si můžete představit že zájem o ni klesá, lidé jsou přelimonádovělí.* My ale jsme malí živnostníci ve světě s 8 000 000 000 lidí (zákazníků), pro N limonád tedy vynásobíme poptavku N-krát.* Jinými slovy, jsme malí páprdové, kteří nemůžou způsobit saturaci trhu s limonádou.<jupyter_code># Celkem tedy se poptávka po 100 limonádách rovná:
popt =<jupyter_output><empty_output><jupyter_text>Poptávka nám říká jaký zlomek limonády se nám při dané ceně podaří prodat<jupyter_code># Tvůj příjem ze 100 vyrobených limonád tedy je?
prijem = 
# Jaké jsou tvé výdaje?
investice = 
vyroba = 
vydaje = 
# Konečně ten čistý zisk
zisk = 
# čistý zisk vykreslíme



plt.axhline(0, color='k', lw=0.5)
plt.axvline(0, color='k', lw=0.5)
plt.xlabel('Cena 1 limonády [peníz]')
plt.ylabel('Čistý zisk [peníz]')
plt.show()<jupyter_output><empty_output><jupyter_text>* Dává to smysl. Nulová cena znamená, že všechny limonády rozdáme zadarmo a zahučíme investici 1000 a dalších 100 x 10 za výrobní náklady. Celkem tedy 2000.* Maximální cena 100 znamená to samé, jen s výhodou, že nám všechny limonády zbydou a můžeme je aspoň vypít.---  Z osové symetrie paraboly je vidět, že maximum musí nastat při ceně přesně v půli mezi 0 a 100, tedy cena=50.<jupyter_code># Kolik ale prodáme limonád při ceně?
# Zbylý zlomek limonád je 1-popt
1-(a*50 + b)<jupyter_output><empty_output><jupyter_text>To je celkem překvapivé, protože vyděláme nejvíc, pokud nám polovina limonád zbyde.---  Jak řešení hledat obecně?* Můžeme postupovat podobně jako u příkladu s pizzou a vytvořit si funkci a využít funkci podobnou `fsolve()`, jen hledající extrémy funkce (minima a maxima) a ne kořeny rovnic.* Tou funkci je `minimize()` z modulu `scipy.optimize`* Funkce ale tentokrát musí pojmout mnoho vstupů, protože zisk je závislý na:    (cena, investice, náklad_za_kus, počet_kusů)    My zvolíme ne ideálně přesný postup, zato ale rychlý a jednoduchý.Budume hledat maximum našeho pole zisku.<jupyter_code># Což je stejné jako hledat očima pokud si vypíšeme pole zisk

# V Pythonu k tomu použijte funkci max()

# Abychom získali cenu, tj. hodnotu x, která náleží zisku 500, použijte funkci np.argmax()<jupyter_output><empty_output><jupyter_text>!!! POZOR!!!---Toto je ošemetný výsledek, protože se zdá být dobře. ALE* `np.argmax()` nám vrací pozici (index), na kterém se nachází hodnota max zisku 500<jupyter_code># Takže musíme teď najít hodnotu pole *cena*, na indexu 50

# Najednou se obě operace dají spojit do:<jupyter_output><empty_output><jupyter_text>Stejné, ale jen proto, že jsme si v prvním řádku vytvořili pole o 101 bodech rovnoměrně rozdělených mezi 0 a 100* tedy na pozici 50, je cena 50, a to je náhoda.* Při jakémkoli jiné definici pole *cena* by `np.argmax()` vydal špatnou hodnotu<jupyter_code># pro zajímavost
type(np.argmax(cena))  # toto je 'int', tedy přirozené číslo
type(cena[50])  # toto je 'float', tedy reálné číslo<jupyter_output><empty_output><jupyter_text>!!! POZOR 2!!!---* `minimize()` z modulu `scipy.optimize` je lepší metodou, protože je řešení přesné.* Ano opravdu `minimize()`, přestože hledáme maximum zisku, trikem je že budete minimalizovat funkci -zisk.* použitím `max()` jsme hledali maximum našeho pole, které jsme spočítali jen pro naše na začátku vybrané ceny.* Přesnost `max()` tedy závisí na četnosti našich hodnot v *cena*, tzv. samplingu. ------* Každý podnik prahne po znalosti křivky poptávky, protože optimalizuje vydělávání peněz z jakéhokoli produktu.* V praxi se tímto problémem zabývají výzkumy vašich útrat z minulosti, průzkumy zákaznických preferencí, a také třeba aukce. Ty všechny zkoumají vaši ochotu za něco platit (anglicky Willingness to pay, WTP), což je v podstatě křivka poptávky. Vezměme si jeden konkrétní příklad, kdy [<NAME> dokázali změřit poptávku po amerických stejcích v roce 2004](https://onlinelibrary.wiley.com/doi/full/10.1111/j.0092-5853.2004.00592.x) * Rozdělili skupinu dobrovolníků na dvě:* Obou se tázali na stejný soubor otázek ohledně preferencí stejků, jedna skupina si na konci musela na základě svých odpovědí svůj nejoblíbenější stejk koupit, narozdíl od druhé skupiny, která nemusela nakonec koupit nic.* Tím se zohledňuje fakt, že lidé lehce řeknou, že by si něco koupili pokud si to nemusí koupit teď a tady.* Takže máme dvě skupiny, tu, která si nemusí koupit stejk označíme *_hyp* (hypotetická).* Skupinu, která musí nakonec koupit stejk označíme *_non_hyp* (non-hypotetická). Digitalizoval jsem pro vás jejich grafy<jupyter_code># publikace má jen několik málo bodů
x = np.array([1/7, 2/7, 3/7, 4/7, 5/7, 6/7, 1])*100

# osa y
data_hyp = np.array([1, 0.91, 0.63, 0.26, 0.1, 0.05, 0])
data_non_hyp = np.array([0.9, 0.68, 0.4, 0.17, 0.08, 0.04, 0])
# proto jsem interpoloval hodnoty i mezi těmi původními
# Více o této metodě je zde https://numpy.org/doc/stable/reference/generated/numpy.interp.html
# Přesto, interpolace je pokročilým tématem na jindy
from scipy import interpolate

# Ve zkratce, hledáme hodnoty funkce mezi body, které jsme opravdu změřili
# Body, ve kteých chci znát hodnoty funkce jsou:
cena_nova = np.linspace(1/7*100, 100, 201)

# interpolace pro obě skupiny
f_hyp = interpolate.interp1d(x, data_hyp, kind='cubic')
f_non_hyp = interpolate.interp1d(x, data_non_hyp, kind='cubic')

# poptávku získáme aplikací f_ na naši novou osu x, cena_nova
popt_hyp = f_hyp(cena_nova)
popt_non_hyp = f_non_hyp(cena_nova)
# vykreslete graf bodů ze studie (x, data_hyp), jako body
# a interpolovaná data, (cena_nova, popt_hyp, popt_non_hyp) jako čáry


plt.axhline(0, color='k', lw=0.5)
plt.axvline(0, color='k', lw=0.5)
plt.xlabel('Cena')
plt.ylabel('Poptávka')
plt.legend()
plt.show()<jupyter_output><empty_output><jupyter_text>To zjevě funguje, a také dává smysl zvlnění závislosti:* Při nízké ceně se poptávka zplošťuje, každý, kdo má chuť na steak si ho při tak malé ceně dopřeje.* A jistě jsou všude lidé, kteří na cenu stejku ani nemusí hledět a koupí si ho skoro bez ohledu na cenu, to je ten pozvolný pokles k nule poptávky.* Nakonec si všimněte, že hypotetická poptávka je všude větší než ta nehypotetická. Lidé jsou méně pozitivní ke stejku, pokud si ho opravdu musí koupit.--- Otázka: Pokud uvážíme stejné křivky pro naši limonádu, vyděláme teď více či méně než původně?* Postup zůstane stejný, jen musíme vše počítat s novou osou x, *cena_nova** Technicky v poptávce nevystupuje cena jako taková, takže se již nejedná o kvadratickou rovnici.* Tím, že naše nová poptávka není žádnou známou funkcí, na papíře bychom tuto úlohu těžko řešili.* S Pythonem to však provedeme úplně stejně jako prvně.<jupyter_code># poptávka po 100 limonádách
popt_hyp_100 = 
popt_non_hyp_100 = 
# příjem stejně jako původně
prijem_hyp = 
prijem_non_hyp = 
# výdaje se nemění
# zisk
zisk_hyp = 
zisk_non_hyp = 
# Teď si můžeš původní a nové zisky vykreslit pro porovnání

plt.axhline(0, color='k', lw=0.5)
plt.axvline(0, color='k', lw=0.5)
plt.xlabel('Cena 1 limonády [peníz]')
plt.ylabel('Čistý zisk [peníz]')
plt.legend()
plt.show()<jupyter_output><empty_output><jupyter_text>Funkce zisku již není kvadratickou funkcí* Nicméně stále můžeme najít cenu limonády, při které budeme mít maximální zisk.<jupyter_code># použití print k vypsání optimálního profitu a při jaké ceně to je
print(f'Maximální zisk pro skupinu hyp je {round(np.max(zisk_hyp))} \
při ceně 1 limonády {cena_nova[np.argmax(zisk_hyp)]}')
# Non-hyp skupina
print(f'Maximální zisk pro skupinu non-hyp je {round(np.max(zisk_non_hyp))} \
při ceně 1 limonády {cena_nova[np.argmax(zisk_non_hyp)]}')<jupyter_output>Maximální zisk pro skupinu non-hyp je -34.0 při ceně 1 limonády 31.857142857142858
{'fraction_non_alphanumeric': 0.08562040974101276, 'fraction_numerical': 0.022129880170081176, 'mean_word_length': 5.182198327359617, 'pattern_counts': {'":': 0, '<': 45, '<?xml version=': 0, '>': 45, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '11', 'dir': 'jupyter-structured-clean-dedup', 'id': '116600', 'license': 'MIT', 'n_tokens_mistral': 4849, 'n_tokens_neox': 4761, 'n_words': 1350, 'path': 'cz/01_kvadraticka/kvadraticka_poptavka_zadani.ipynb', 'repo_name': 'palec87/pymarad-pilot', 'size': '10360'}