# -*- coding: utf-8 -*-

# ------------------------------------------------------------------------------
# # Gemi yaşam döngüsünün neresindeyiz? Ülkelerin inşa, sahiplik, bayrak ve geri dönüşüm konumunu ölçen bir endeks ve Türkiye'nin yaşam sonu uzmanlaşması, 2014–2025
#
# *Where are we in the ship life cycle? An index of countries' position across shipbuilding, ownership, registration and recycling, and Türkiye's end-of-life specialisation, 2014–2025*
#
# **GOMD Yayınlar · Deniz ekonomisi 02** — https://gomd.pirireis.edu.tr/publications.php?id=me02
#
# Bu not defteri makaledeki **tüm sayıları, tabloları ve şekilleri** üreten kodun Colab sürümüdür. Veri, replikasyon paketinde (11 Kasım 2026 indirmesi) varsa oradan; yoksa özgün sağlayıcıdan (UNCTADstat) indirilir. Bütün sayılar `out/results.json` dosyasına yazılır.
#
# This notebook reproduces **every number, table and figure** of the paper. Data are taken from the replication package (retrieved 11 November 2026) if present; otherwise they are downloaded from the original provider. All numbers are written to `out/results.json`.
#
# *Makale hazırlık aşamasındadır; dergi adı ve tam metin kabulden sonra eklenecektir. / The paper is in preparation; journal name and full text will be added after acceptance.*
# ------------------------------------------------------------------------------

# ------------------------------------------------------------------------------
# ## 0. Kurulum / Setup
# ------------------------------------------------------------------------------
# [Colab Magic] !pip install -q pandas numpy statsmodels scipy matplotlib py7zr

# ------------------------------------------------------------------------------
# ## 1. Veri / Data
# Exact reproduction in Colab: upload the replication package (.zip) from the GOMD Publications page, unzip it, then run the cells.
# ------------------------------------------------------------------------------
VERI_KAYNAGI = 'kaynak'   # Colab'da 'zip' secenegi icin not defterine bakin / see the notebook for the 'zip' option in Colab
# Veri / Data. Paketteki veri varsa onu kullanır (11 Kasım 2026 indirmesi, birebir yeniden üretim);
# yoksa özgün kaynaktan indirir (güncel sürüm; sağlayıcı revizyonları nedeniyle sonuçlar küçük farklar gösterebilir).
# Uses the data shipped in the replication package if present (retrieved 11 Nov 2026, exact reproduction);
# otherwise downloads from the original provider (current release; results may differ slightly after provider revisions).
import os, glob, json, urllib.request
import pandas as pd
os.makedirs('data', exist_ok=True); os.makedirs('out', exist_ok=True); os.makedirs('fig', exist_ok=True)
def _unctad(code):
    d = 'data/US_' + code
    if glob.glob(d + '/*.csv'): return
    arc = d + '.7z'
    if not os.path.exists(arc):
        print('UNCTADstat indiriliyor / downloading:', code)
        req = urllib.request.Request('https://unctadstat-api.unctad.org/bulkdownload/US.%s/US_%s' % (code, code), headers={'User-Agent': 'gomd-replication/1.0'})
        with urllib.request.urlopen(req, timeout=300) as r, open(arc, 'wb') as f: f.write(r.read())
    import py7zr
    with py7zr.SevenZipFile(arc) as z: z.extractall(d)
for _c in ['ShipBuilding', 'ShipScrapping', 'FleetBeneficialOwners', 'MerchantFleet', 'Seafarers']: _unctad(_c)

# ------------------------------------------------------------------------------
# ## 2. Analiz ve şekiller / Analysis and figures
# ------------------------------------------------------------------------------
# Makale 2: Gemi yaşam döngüsünde ülkelerin konumu; Türkiye'nin gemi inşa ve geri dönüşümdeki yeri (UNCTADstat, 2014-2025/2026)
import pandas as pd, numpy as np, glob, json, matplotlib
matplotlib.use('Agg'); import matplotlib.pyplot as plt
import statsmodels.api as sm
D='data/'; O='out/'; F='fig/'; R={}
def L(n):
    d=pd.read_csv(glob.glob(D+n+'/*.csv')[0],low_memory=False,dtype={'Economy':str,'BeneficialOwnership':str,'FlagOfRegistration':str})
    for c in d.columns:
        if c.endswith('Label'): d.loc[d[c].astype(str).str.contains('rkiye'),c]='Türkiye'
    return d
sb=L('US_ShipBuilding').rename(columns={'Economy Label':'eco','Gross Tonnage':'v'}); sc=L('US_ShipScrapping').rename(columns={'Economy Label':'eco','Gross Tonnage':'v'})
B=sb[sb.Economy.str.len()==3].pivot_table(index='eco',columns='Year',values='v').fillna(0); S=sc[sc.Economy.str.len()==3].pivot_table(index='eco',columns='Year',values='v').fillna(0)
Bw=sb[sb.eco=='World'].set_index('Year').v; Sw=sc[sc.eco=='World'].set_index('Year').v; YR=list(Bw.index)
R['world']={int(y):dict(build=float(Bw[y]),scrap=float(Sw[y]),ratio=round(float(Sw[y]/Bw[y]),3)) for y in YR}
bs,ss=B/Bw*100,S/Sw*100
tr=pd.DataFrame({'build_gt':B.loc['Türkiye'],'build_sh':bs.loc['Türkiye'],'scrap_gt':S.loc['Türkiye'],'scrap_sh':ss.loc['Türkiye']}); tr['build_rank']=B.rank(ascending=False).loc['Türkiye']; tr['scrap_rank']=S.rank(ascending=False).loc['Türkiye']
tr.round(3).to_csv(O+'turkiye.csv'); R['tr']={int(y):{k:round(float(v),3) for k,v in r.items()} for y,r in tr.iterrows()}
# 1) LMDI: ülke hacmi = dünya hacmi x pay
def lm(a,b): return (b-a)/np.log(b/a) if a!=b else a
def dec(V,W,c,y0,y1):
    a,b=V.loc[c,y0],V.loc[c,y1]; Lm=lm(a,b); return dict(d=b-a,market=Lm*np.log(W[y1]/W[y0]),share=Lm*np.log((b/W[y1])/(a/W[y0])))
R['lmdi_scrap_tr']={f'{a}-{b}':{k:round(float(v),0) for k,v in dec(S,Sw,'Türkiye',a,b).items()} for a,b in [(2014,2018),(2018,2025),(2014,2025)]}
R['lmdi_build_tr']={f'{a}-{b}':{k:round(float(v),0) for k,v in dec(B,Bw,'Türkiye',a,b).items()} for a,b in [(2014,2018),(2018,2025),(2014,2025)]}
maj=['Bangladesh','India','Pakistan','China','Türkiye']
R['lmdi_scrap_all']={c:{k:round(float(v),0) for k,v in dec(S,Sw,c,2014,2025).items()} for c in maj}
# dönem ortalamaları (ön/son 2019)
pre,post=[y for y in YR if y<=2018],[y for y in YR if y>=2019]
R['scrap_share_pre_post']={c:dict(pre=round(float(ss.loc[c,pre].mean()),2),post=round(float(ss.loc[c,post].mean()),2)) for c in maj+['Denmark']}
R['scrap_gt_pre_post_tr']=dict(pre=round(float(S.loc['Türkiye',pre].mean()),0),post=round(float(S.loc['Türkiye',post].mean()),0)); R['scrap_gt_pre_post_world']=dict(pre=round(float(Sw[pre].mean()),0),post=round(float(Sw[post].mean()),0))
# 2) Döngüsellik: d ln(ülke) ~ d ln(dünya, ülke hariç); oynaklık
cyc={}
for c in maj:
    x=np.log((Sw-S.loc[c]).astype(float)).diff().dropna(); yv=np.log(S.loc[c].astype(float)).diff().dropna()
    m=sm.OLS(yv,sm.add_constant(x)).fit(); cyc[c]=dict(beta=round(float(m.params.iloc[1]),2),se=round(float(m.bse.iloc[1]),2),p=round(float(m.pvalues.iloc[1]),3),r2=round(float(m.rsquared),2),cv=round(float(S.loc[c].std()/S.loc[c].mean()),2),minmax=round(float(S.loc[c].max()/S.loc[c].min()),1))
R['cyclicality']=cyc; R['world_scrap_cv']=round(float(Sw.std()/Sw.mean()),2); R['world_scrap_minmax']=round(float(Sw.max()/Sw.min()),1)
# 3) Yapısal kırılma (2019): Türkiye'nin Güney Asya üçlüsüne göre log oranı; Chow testi (sabit + eğilim) ve ortalama kayması (HAC)
lr=np.log(S.loc['Türkiye']/S.loc[['Bangladesh','India','Pakistan']].sum()); t=np.arange(len(lr)); post_d=(np.array(YR)>=2019).astype(float)
m0=sm.OLS(lr.values,sm.add_constant(t)).fit(); m1=sm.OLS(lr.values,sm.add_constant(np.c_[t,post_d,post_d*t])).fit()
Fst=((m0.ssr-m1.ssr)/2)/(m1.ssr/(len(lr)-4)); from scipy import stats
R['break']=dict(F=round(float(Fst),2),p=round(float(1-stats.f.cdf(Fst,2,len(lr)-4)),4))
m2=sm.OLS(lr.values,sm.add_constant(post_d)).fit(cov_type='HAC',cov_kwds={'maxlags':1}); R['break']['level_shift']=round(float(m2.params[1]),3); R['break']['level_se']=round(float(m2.bse[1]),3); R['break']['level_p']=round(float(m2.pvalues[1]),4); R['break']['ratio_pre']=round(float(np.exp(lr[pre].mean())*100),2); R['break']['ratio_post']=round(float(np.exp(lr[post].mean())*100),2)
# plasebo kırılma yılları
pl={}
for yb in range(2016,2024):
    dmy=(np.array(YR)>=yb).astype(float); mm=sm.OLS(lr.values,sm.add_constant(np.c_[t,dmy,dmy*t])).fit(); Fx=((m0.ssr-mm.ssr)/2)/(mm.ssr/(len(lr)-4)); pl[yb]=round(float(Fx),2)
R['break_placebo_F']=pl
# 4) Yaşam döngüsü konumu: inşa, sahiplik, bayrak, geri dönüşüm payları (2025; sahiplik ve bayrak 2026 başı ~ 2025 sonu)
bo=L('US_FleetBeneficialOwners'); own=bo[(bo['FlagOfRegistration Label']=='Total all flags')&(bo.BeneficialOwnership.str.len()==3)].pivot_table(index='BeneficialOwnership Label',columns='Year',values='Dead weight tons in thousands').fillna(0)
ownw=bo[(bo['FlagOfRegistration Label']=='Total all flags')&(bo['BeneficialOwnership Label']=='World')].set_index('Year')['Dead weight tons in thousands']
mf=L('US_MerchantFleet'); fl=mf[mf['ShipType Label'].str.contains('Total')&(mf.Economy.astype(str).str.len()==3)].pivot_table(index='Economy Label',columns='Year',values='Dead weight tons in thousands').fillna(0); flw=mf[mf['ShipType Label'].str.contains('Total')&(mf['Economy Label']=='World')].set_index('Year')['Dead weight tons in thousands']
sf=L('US_Seafarers'); cr=sf[(sf.Year==2021)&(sf['SeafarerType Label']=='Total')&(sf.Economy.astype(str).str.len()==3)].set_index('Economy Label')['Percentage of total world']
def pos(yb,yo):
    d=pd.DataFrame({'insa':bs[yb],'sahiplik':own[yo]/ownw[yo]*100,'bayrak':fl[yo]/flw[yo]*100,'geri_donusum':ss[yb]}).fillna(0); return d
P3=pd.DataFrame({'insa':B.loc[:,2023:2025].sum(axis=1)/Bw.loc[2023:2025].sum()*100,'sahiplik':own[2026]/ownw[2026]*100,'bayrak':fl[2026]/flw[2026]*100,'geri_donusum':S.loc[:,2023:2025].sum(axis=1)/Sw.loc[2023:2025].sum()*100}).fillna(0)
P3['mürettebat_2021']=cr; P3['toplam']=P3[['insa','sahiplik','bayrak','geri_donusum']].sum(axis=1)
w=P3[['insa','sahiplik','bayrak','geri_donusum']].div(P3.toplam,axis=0)
P3['LCP']=(w*np.array([1,2,3,4])).sum(axis=1)                         # 1 = inşa ... 4 = geri dönüşüm
P3['H']=-(w.where(w>0)*np.log(w.where(w>0))).sum(axis=1)/np.log(4)     # aşamalar arası denge (0-1)
P3['maks_asama']=w.idxmax(axis=1)
sel=P3[P3.toplam>=1.0].sort_values('toplam',ascending=False); sel.round(3).to_csv(O+'lifecycle_position.csv'); R['lcp_n']=int(len(sel))
R['lcp_tr']={k:(round(float(v),3) if not isinstance(v,str) else v) for k,v in P3.loc['Türkiye'].items()}; R['lcp_rank_tr']=int(sel.LCP.rank(ascending=False).loc['Türkiye'])
R['lcp_table']={c:{k:(round(float(v),2) if not isinstance(v,str) else v) for k,v in r.items()} for c,r in sel.head(40).iterrows()}
R['lcp_downstream']=list(sel.sort_values('LCP',ascending=False).head(6).index); R['lcp_upstream']=list(sel.sort_values('LCP').head(6).index)
# 2014-2016 konumu (zaman içinde değişim)
P0=pd.DataFrame({'insa':B.loc[:,2014:2016].sum(axis=1)/Bw.loc[2014:2016].sum()*100,'sahiplik':own[2016]/ownw[2016]*100,'bayrak':fl[2016]/flw[2016]*100,'geri_donusum':S.loc[:,2014:2016].sum(axis=1)/Sw.loc[2014:2016].sum()*100}).fillna(0)
w0=P0.div(P0.sum(axis=1),axis=0); R['lcp_tr_2014_16']={**{k:round(float(v),3) for k,v in P0.loc['Türkiye'].items()},'LCP':round(float((w0.loc['Türkiye']*np.array([1,2,3,4])).sum()),3)}
# 5) Yoğunlaşma
hh=lambda s:float(((s/s.sum())**2).sum())
R['hhi']={int(y):dict(build=round(hh(B[y]),3),scrap=round(hh(S[y]),3),top3_build=round(float(B[y].nlargest(3).sum()/Bw[y]*100),1),top3_scrap=round(float(S[y].nlargest(3).sum()/Sw[y]*100),1)) for y in (2014,2018,2022,2025)}
# 6) Geri dönüşüm / inşa oranı ve Avrupa karşılaştırması
R['tr_scrap_to_build']={int(y):round(float(S.loc['Türkiye',y]/B.loc['Türkiye',y]),1) for y in YR}; R['tr_scrap_to_build_cum']=round(float(S.loc['Türkiye'].sum()/B.loc['Türkiye'].sum()),1)
EU=['Italy','Germany','France','Finland','Netherlands (Kingdom of the)','Norway','Spain','Poland','Romania','Croatia','Russian Federation','Türkiye','Denmark','Portugal','Greece','United Kingdom']
EU=[c for c in EU if c in B.index]; eb=B.loc[EU]; R['europe_build_2025']={c:round(float(v),0) for c,v in eb[2025].sort_values(ascending=False).items()}; R['europe_build_cum']={c:round(float(v),0) for c,v in eb.sum(axis=1).sort_values(ascending=False).items()}
R['europe_build_cv']={c:round(float(eb.loc[c].std()/eb.loc[c].mean()),2) for c in EU if eb.loc[c].mean()>0}
R['europe_rank_tr']={int(y):int(eb[y].rank(ascending=False).loc['Türkiye']) for y in (2014,2018,2022,2025)}
es=S.loc[[c for c in EU if c in S.index]]; R['europe_scrap_share_2023_25']={c:round(float(v),1) for c,v in (es.loc[:,2023:2025].sum(axis=1)/es.loc[:,2023:2025].sum().sum()*100).sort_values(ascending=False).head(6).items()}
def _nan2null(o):   # JSON'da NaN gecersizdir; eksik deger null yazilir
    if isinstance(o,dict): return {k:_nan2null(v) for k,v in o.items()}
    if isinstance(o,list): return [_nan2null(v) for v in o]
    if isinstance(o,float) and o!=o: return None
    return o
json.dump(_nan2null(R),open(O+'results.json','w'),ensure_ascii=False,indent=1)
# şekiller
plt.rcParams.update({'font.size':9}); TRN={'Bangladesh':'Bangladeş','India':'Hindistan','Pakistan':'Pakistan','China':'Çin','Türkiye':'Türkiye'}
fig,ax=plt.subplots(1,2,figsize=(10,3.8)); ax[0].stackplot(YR,*[ss.loc[c] for c in maj],100-ss.loc[maj].sum(),labels=[TRN[c] for c in maj]+['Diğer'],colors=['#16a085','#e67e22','#8e44ad','#7f8c8d','#c0392b','#ecf0f1']); ax[0].set_ylabel('dünya geri dönüşümündeki pay (%)'); ax[0].legend(fontsize=7,ncol=3,frameon=False,loc='lower center'); ax[0].set_title('(a) Geri dönüşüm payları'); ax[0].axvline(2019,color='k',ls=':',lw=.8)
a2=ax[1].twinx(); ax[1].bar(YR,Sw/1e6,color='#bdc3c7',label='Dünya (sol)'); a2.plot(YR,S.loc['Türkiye']/1e6,'o-',color='#c0392b',label='Türkiye (sağ)'); ax[1].set_ylabel('dünya, milyon GT'); a2.set_ylabel('Türkiye, milyon GT'); a2.set_ylim(0,2); ax[1].set_title('(b) Geri dönüşüm hacmi'); ax[1].legend(loc='upper left',frameon=False,fontsize=7); a2.legend(loc='upper right',frameon=False,fontsize=7)
plt.tight_layout(); plt.savefig(F+'fig1.png',dpi=200); plt.close()
fig,ax=plt.subplots(figsize=(7,5.2)); q=sel.copy(); ax.scatter(q.LCP,q.H,s=q.toplam*6+10,alpha=.6,color='#2980b9')
nm={'Türkiye':'Türkiye','China':'Çin','Republic of Korea':'Kore','Japan':'Japonya','Greece':'Yunanistan','Bangladesh':'Bangladeş','India':'Hindistan','Pakistan':'Pakistan','Panama':'Panama','Liberia':'Liberya','Marshall Islands':'Marshall Ad.','Singapore':'Singapur','Germany':'Almanya','Norway':'Norveç','Denmark':'Danimarka','Italy':'İtalya','Malta':'Malta','China, Hong Kong SAR':'Hong Kong','United States':'ABD','Philippines':'Filipinler','Viet Nam':'Vietnam','Bahamas':'Bahamalar'}
for c,r in q.iterrows():
    if c in nm: ax.annotate(nm[c],(r.LCP,r.H),fontsize=7,color='#c0392b' if c=='Türkiye' else 'k',xytext=(3,3),textcoords='offset points')
ax.set_xlabel('yaşam döngüsü konum endeksi (1 = inşa, 2 = sahiplik, 3 = bayrak, 4 = geri dönüşüm)'); ax.set_ylabel('aşamalar arası denge (0–1)'); plt.tight_layout(); plt.savefig(F+'fig2.png',dpi=200); plt.close()
fig,ax=plt.subplots(1,2,figsize=(10,3.6)); ax[0].plot(YR,lr.values,'o-',color='#c0392b'); ax[0].axvline(2018.5,color='k',ls=':'); ax[0].hlines([lr[pre].mean(),lr[post].mean()],[2014,2019],[2018,2025],colors='#2980b9',linestyles='--'); ax[0].set_ylabel('ln(Türkiye / Güney Asya üçlüsü)'); ax[0].set_title('(a) Göreli geri dönüşüm hacmi')
ax[1].bar(list(pl),list(pl.values()),color=['#c0392b' if k==2019 else '#bdc3c7' for k in pl]); ax[1].set_ylabel('Chow F istatistiği'); ax[1].set_xlabel('varsayılan kırılma yılı'); ax[1].set_title('(b) Plasebo kırılma yılları'); plt.tight_layout(); plt.savefig(F+'fig3.png',dpi=200); plt.close()
fig,ax=plt.subplots(figsize=(7.5,3.6)); 
for c,lab in [('Italy','İtalya'),('Germany','Almanya'),('France','Fransa'),('Finland','Finlandiya'),('Russian Federation','Rusya'),('Norway','Norveç'),('Romania','Romanya'),('Türkiye','Türkiye')]:
    if c in B.index: ax.plot(YR,B.loc[c]/1e3,'o-' if c=='Türkiye' else '-',lw=2.2 if c=='Türkiye' else 1,color='#c0392b' if c=='Türkiye' else None,label=lab)
ax.set_ylabel('teslim edilen gemi (bin GT)'); ax.legend(ncol=4,fontsize=7,frameon=False); plt.tight_layout(); plt.savefig(F+'fig4.png',dpi=200); plt.close()
print(json.dumps({k:R[k] for k in R if k not in ('lcp_table','world','tr')},ensure_ascii=False)[:5000]); print(sel.head(28).round(2).to_string())

# ------------------------------------------------------------------------------
# ## Şekiller / Figures
# ------------------------------------------------------------------------------
print('Sekiller / figures:', sorted(glob.glob('fig/*.png')))
