Ipython: % matplotlib 인라인으둜 λ©”λͺ¨λ¦¬ λˆ„μˆ˜

에 λ§Œλ“  2014λ…„ 12μ›” 19일  Β·  23μ½”λ©˜νŠΈ  Β·  좜처: ipython/ipython

μ•ˆλ…• λͺ¨λ‘λ“€

문제λ₯Ό λ°œκ²¬ν–ˆμŠ΅λ‹ˆλ‹€. μ½”λ“œλ₯Ό μ‹€ν–‰ν•˜κ³  λ©”λͺ¨λ¦¬λ₯Ό μ‚΄νŽ΄λ³΄μ„Έμš”. 그런 λ‹€μŒ "% matplotlib inline"을 μ‚­μ œν•˜κ³  λ‹€μ‹œ μ‹œμž‘ν•˜μ‹­μ‹œμ˜€.

import matplotlib
import matplotlib.pyplot as plt
import matplotlib.ticker

%matplotlib inline

import os
import sys
import StringIO
import urllib, base64

from matplotlib import rcParams

rcParams['figure.figsize'] = (24, 6)
rcParams['figure.dpi'] = 150

OUTPUT_FILENAME = "Asd"

def printHTML(html):
    with open(OUTPUT_FILENAME, "a") as outputFile: outputFile.write(html if type(html) == str else html.encode('utf8') )

def friendlyPlot():

    figure = plt.Figure()
    ax = plt.subplot2grid((1,2), (0,0))

    ax.plot( range(1000), range(1000) )


    #plt.show() 
    fig = plt.gcf()

    imgdata = StringIO.StringIO()
    fig.savefig(imgdata, format='png')
    imgdata.seek(0)  # rewind the data
    image = imgdata.buf.encode('base64').replace('\n', '')
    printHTML('<img src="data:image/png;base64,{0}" /><br />'.format(image))
    plt.close('all')
    imgdata.close()

open(OUTPUT_FILENAME, 'w').close()

for i in range(500):
    friendlyPlot()
bug matplotlib

κ°€μž₯ μœ μš©ν•œ λŒ“κΈ€

두 번째둜이 λ¬Έμ œμ— λŒ€ν•œ μˆ˜μ •μ„ μ£Όμ‹œλ©΄ κ°μ‚¬ν•˜κ² μŠ΅λ‹ˆλ‹€.

λͺ¨λ“  23 λŒ“κΈ€

이 버그도 λ°œμƒν–ˆμŠ΅λ‹ˆλ‹€. λ©”λͺ¨λ¦¬ λˆ„μˆ˜μ—†μ΄ 인라인 ν”Œλ‘―μ„ 얻을 μˆ˜μžˆλŠ” 방법이 μžˆμŠ΅λ‹ˆκΉŒ? 배열이 μƒλ‹Ήνžˆ 크기 λ•Œλ¬Έμ— 각 ν”Œλ‘―μ— λŒ€ν•΄ λ³„λ„μ˜ ν”„λ‘œμ„ΈμŠ€λ₯Ό μ‹œμž‘ν•˜κ³  싢지 μ•ŠμŠ΅λ‹ˆλ‹€.

λ©”λͺ¨λ¦¬ μ‚¬μš©λŸ‰μ΄ μ¦κ°€ν•˜λ©΄μ΄λ₯Ό 확인할 수 μžˆμŠ΅λ‹ˆλ‹€.

len(IPython.kernel.zmq.pylab.backend_inline.show._to_draw)

그것은 μˆ˜μΉ˜κ°€ μ €μž₯λ˜λŠ” λͺ©λ‘μž…λ‹ˆλ‹€. μΌμ‹œμ μœΌλ‘œ 만 μžˆμ–΄μ•Όν•˜μ§€λ§Œ μ •λ¦¬λ˜μ§€ μ•Šκ³  μŒ“μ΄κ³ μžˆμ„ μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€.

len (IPython.kernel.zmq.pylab.backend_inline.show._to_draw) = 0

BTW, pandas 데이터 ν”„λ ˆμž„μ—μ„œ .plot() λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•˜μ—¬ ν”Œλ‘œνŒ…ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€.

μ’‹μ•„, κ·Έ 이둠에 λ„ˆλ¬΄ 많이.

νŒ¬λ”κ°€ λ‚΄λΆ€μ μœΌλ‘œλ„ ν”Œλ‘― 주변에 일뢀 데이터λ₯Ό 보관할 수 μžˆμŠ΅λ‹ˆλ‹€. ν•˜μ§€λ§Œ μ›λž˜ λ³΄κ³ μ„œμ—λŠ” νŒλ‹€κ°€ ν¬ν•¨λ˜μ–΄ μžˆμ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

각 μΆ”κ°€ ν”Œλ‘―μ΄ μΆ”κ°€λ˜λŠ” κ²ƒμ²˜λŸΌ λ³΄μ΄λŠ” λ©”λͺ¨λ¦¬ 양은 μ–Όλ§ˆμž…λ‹ˆκΉŒ?

μ’‹μ•„, 이것은 λ‚΄ 경우 인 것 κ°™κ³  pandas 0.16.0을 μ‚¬μš©ν–ˆμ§€λ§Œ λ¬Έμ œλŠ” λ§ˆμŠ€ν„°μ—μ„œ μˆ˜μ •λ˜μ—ˆμŠ΅λ‹ˆλ‹€.

https://github.com/pydata/pandas/pull/9814

κ°μ‚¬ν•©λ‹ˆλ‹€. μ›λž˜ λ³΄κ³ μ„œμ—λŠ” νŒλ‹€κ°€ ν¬ν•¨λ˜μ§€ μ•Šμ•˜κΈ° λ•Œλ¬Έμ— μ—΄λ € μžˆμŠ΅λ‹ˆλ‹€.

이것은 더 κ°„λ‹¨ν•˜κ²Œ μž¬ν˜„ ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

import matplotlib
import matplotlib.pyplot as plt
import matplotlib.ticker

%matplotlib inline

import os
import sys
import StringIO
import urllib, base64

from matplotlib import rcParams

rcParams['figure.figsize'] = (24, 6)
rcParams['figure.dpi'] = 150



def friendlyPlot():
    fig, ax = plt.subplots()
    ax.plot(range(1000))
    fig.savefig('tmp.png')
    plt.close('all')


for i in range(500):
    friendlyPlot()

이것은 λ©”λͺ¨λ¦¬ λˆ„μΆœμ΄ μ—†μœΌλ―€λ‘œ pyplot 츑이 μ•„λ‹Œ IPython 츑에 μžˆμŠ΅λ‹ˆλ‹€ (제 생각에).

import matplotlib
matplotlib.use('agg')
import matplotlib.pyplot as plt
import matplotlib.ticker



import os
import sys
import StringIO
import urllib, base64

from matplotlib import rcParams

rcParams['figure.figsize'] = (24, 6)
rcParams['figure.dpi'] = 150



def friendlyPlot():
    fig, ax = plt.subplots()
    ax.plot(range(1000))
    fig.savefig('tmp.png')
    plt.close('all')


for i in range(500):
    friendlyPlot()

@tacaswell ν…ŒμŠ€νŠΈ μ½”λ“œλ₯Ό μ‚¬μš©ν•˜λ©΄ Windows 7의 IPython은 μ—¬κΈ°μ„œ μ•½ 1.7GBλ₯Ό μ†ŒλΉ„ν•˜λ©° λ‚˜μ€‘μ— ν•΄μ œλ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. μ•½κ°„ 더 λ§Žμ€ 반볡 횟수둜 μ‹€ν–‰ν•˜λ©΄ λ©”λͺ¨λ¦¬ 였λ₯˜κ°€ λ°œμƒν•©λ‹ˆλ‹€. κ·Έλž˜μ„œ 이것은 μ—¬μ „νžˆ β€‹β€‹λ¬Έμ œμž…λ‹ˆλ‹€.

@asteppke 첫 번째 λ˜λŠ” 두 번째 블둝?

@tacaswell 첫 번째 ν…ŒμŠ€νŠΈ μ½”λ“œ ( %matplotlib inline )λ₯Ό μ‚¬μš©ν•˜λ©΄ λ©”λͺ¨λ¦¬ μ‚¬μš©λŸ‰μ΄ 1.7GBκΉŒμ§€ λŠ˜μ–΄λ‚©λ‹ˆλ‹€. λŒ€μ‘°μ μœΌλ‘œ 두 번째 쑰각 ( matplotlib.use('agg') )을 μ‚¬μš©ν•  λ•Œ λ©”λͺ¨λ¦¬ μ‚¬μš©λŸ‰μ€ 50MBμ—μ„œ 100MB μ‚¬μ΄μ—μ„œλ§Œ λ³€λ™ν•©λ‹ˆλ‹€.

두 ν…ŒμŠ€νŠΈ λͺ¨λ‘ Python 3.4 및 IPython λ…ΈνŠΈλΆ 버전 4.0.5둜 μ‹€ν–‰λ©λ‹ˆλ‹€.

λ‚˜λŠ” 이것을 쑰금 더 가지고 λ†€μ•˜μŠ΅λ‹ˆλ‹€. @tacaswell 의 μ˜ˆμ œμ—μ„œ for 루프λ₯Ό λͺ‡ 번 λ‹€μ‹œ μ‹€ν–‰ν•˜λ©΄ λ©”λͺ¨λ¦¬ μ‚¬μš©λŸ‰μ΄ μ¦κ°€ν•˜μ§€ μ•ŠλŠ” κ²ƒμœΌλ‘œ λ‚˜νƒ€λ‚¬μŠ΅λ‹ˆλ‹€. μ€‘μš”ν•œ 단일 μ…€μ—μ„œ λ§Œλ“œλŠ” 숫자 인 것 κ°™μŠ΅λ‹ˆλ‹€. IPython은 ν™•μ‹€νžˆ 인라인 λ°±μ—”λ“œλ₯Ό μœ„ν•΄ μ…€μ—μ„œ 생성 된 λͺ¨λ“  수치의 λͺ©λ‘μ„ μœ μ§€ν•˜μ§€λ§Œ ν•΄λ‹Ή λͺ©λ‘μ€ 셀이 μ‹€ν–‰ 된 ν›„ ν™•μ‹€νžˆ μ§€μ›Œμ Έμ„œ gc.collect() 을 μˆ˜ν–‰ ν•œ 후에도 λ©”λͺ¨λ¦¬ μ‚¬μš©λŸ‰μ΄ 떨어지지 μ•ŠμŠ΅λ‹ˆλ‹€.

우리 μ½”λ“œκ°€ matplotlib의 무언가와 λ‚˜μ˜κ²Œ μƒν˜Έ μž‘μš©ν•  수 μžˆμŠ΅λ‹ˆκΉŒ? _pylab_helpers.Gcf κ°€λŠ₯μ„±μ΄μžˆλŠ” 것 κ°™μ•˜μ§€λ§Œ 아무 것도 λΆ™ μž‘μ§€ μ•ŠλŠ” 것 κ°™μŠ΅λ‹ˆλ‹€.

λ‚˜λŠ” κ·Έλ¦Ό 쀑 ν•˜λ‚˜μ— λŒ€ν•œ μ°Έμ‘°λ₯Ό 작고 그것에 λŒ€ν•΄ gc.get_referrers() 라고 λΆ€λ₯΄λ €κ³ ν–ˆμŠ΅λ‹ˆλ‹€. user_nsμ—μžˆλŠ” μ°Έμ‘°λ₯Ό μ œμ™Έν•˜κ³  λ‹€λ₯Έ λͺ¨λ“  것듀은 mpl 객체처럼 λ³΄μ˜€μŠ΅λ‹ˆλ‹€. μ•„λ§ˆλ„ κ·Έλ“€ 쀑 λ§Žμ€ 것듀이 μ°Έμ‘° 루프에 μžˆμŠ΅λ‹ˆλ‹€. λ‹€λ₯Έ 무언가가 λΆ€μ μ ˆν•˜κ²Œ μ°Έμ‘°λ₯Ό μœ μ§€ν•˜κ³ μžˆμ„ κ°€λŠ₯성이 κ°€μž₯ 높은 κ°œμ²΄λŠ” λ¬΄μ—‡μž…λ‹ˆκΉŒ?

λ‚˜λŠ” 이것을 λ§ˆμΌμŠ€ν†€ 'μœ„μ‹œλ¦¬μŠ€νŠΈ'에 λ–¨μ–΄ λœ¨λ¦¬κ³ μžˆλ‹€. μš°λ¦¬λŠ” 그것을 고치고 μ‹Άμ§€λ§Œ ν˜„μž¬λ‘œμ„œλŠ” 버그λ₯Ό μ‹λ³„ν•˜λŠ” κ³Όμ •μ—μ„œ μ–΄λ–»κ²Œ 더 진전을 이루어야할지 확신이 μ„œμ§€ μ•ŠμœΌλ©° 릴리슀λ₯Ό 보λ₯˜ ν•  κ°€μΉ˜κ°€ μ—†λ‹€κ³  μƒκ°ν•©λ‹ˆλ‹€.

λ°œμ „ ν•  μˆ˜μžˆλŠ” μ‚¬λžŒμ€ λˆ„κ΅¬λ‚˜ λΈŒλΌμš°λ‹ˆ 포인트λ₯Όλ°›μŠ΅λ‹ˆλ‹€. λ˜ν•œ 케이크.

μ‹€μ œλ‘œ μ§„ν–‰λ˜μ§€λŠ” μ•Šμ§€λ§Œ 컀널 λ‚΄λΆ€ μ–΄λ”˜κ°€μ—μ„œ λ©”λͺ¨λ¦¬κ°€ 손싀 된 것 κ°™μŠ΅λ‹ˆλ‹€. 루프 도움말 이후 λ˜λŠ” λ‚΄λΆ€μ—μ„œ gc.collect() ν˜ΈμΆœν•˜μ§€λ„ μ•ŠμœΌλ©° summary.print_(summary.summarize(muppy.get_objects())) λŠ” λˆ„μˆ˜ 된 λ©”λͺ¨λ¦¬λ₯Ό 찾지 λͺ»ν•©λ‹ˆλ‹€. λͺ¨λ“  _N 및 _iN λ₯Ό None λ„μ›€λ§λ‘œ μ„€μ •ν•˜λŠ” 것도 μ•„λ‹™λ‹ˆλ‹€. 정말 μ‹ λΉ„ μŠ€λŸ½μŠ΅λ‹ˆλ‹€.

λ˜ν•œ μˆ˜μ§‘ ν•  μˆ˜μ—†λŠ” 개체λ₯Ό μƒμ„±ν•˜λŠ”μ§€ κΆκΈˆν–ˆμ§€λ§Œ λ‹€λ₯Έ μ°Έμ‘°κ°€μ—†λŠ” 경우 gc.garbage λλ‚˜μ•Όν•˜λ©° RAM을 많이 μ‚¬μš©ν•˜λŠ” 것을 보면 μ—¬μ „νžˆ λΉ„μ–΄ μžˆμŠ΅λ‹ˆλ‹€.

λ‚˜λŠ” μ΄λŸ¬ν•œ 것듀에 λŒ€ν•΄ μ•„λŠ” μ‚¬λžŒμ΄ C 레벨 도ꡬλ₯Ό μ‚¬μš©ν•˜μ—¬ ν•΄μ œλ˜μ§€ μ•Šμ€ λ©”λͺ¨λ¦¬λ₯Ό μΆ”μ ν•΄μ•Όν•œλ‹€κ³  μƒκ°ν•©λ‹ˆλ‹€. μš°λ¦¬κ°€ 찾을 μˆ˜μžˆλŠ” κ³³μ—μ„œλŠ” μ—¬λΆ„μ˜ 파이썬 객체가 μ‚΄μ•„ μžˆλ‹€λŠ” 증거가 μ—†μŠ΅λ‹ˆλ‹€.

두 번째둜이 λ¬Έμ œμ— λŒ€ν•œ μˆ˜μ •μ„ μ£Όμ‹œλ©΄ κ°μ‚¬ν•˜κ² μŠ΅λ‹ˆλ‹€.

μš°λ¦¬λŠ” μ•Œκ³  μžˆμ§€λ§Œ ν˜„μž¬ 아무도 λ²„κ·Έμ˜ 원인을 νŒŒμ•…ν•˜μ§€ λͺ»ν–ˆμŠ΅λ‹ˆλ‹€.

+1

+1

BTW, λ‚˜λŠ” μ΅œμ‹  matplotlib, pandas, jupyter, ipythonμ—μ„œ λ•Œλ•Œλ‘œμ΄ 문제λ₯Ό ν•΄κ²°ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€. 이 닀쀑 ν”„λ‘œμ„ΈμŠ€ 톡신 문제λ₯Ό ν•΄κ²°ν•˜λŠ” 데 도움이 될 μˆ˜μžˆλŠ” 디버거λ₯Ό μ•„λŠ” μ‚¬λžŒμ΄ 있으면 μ•Œλ €μ£Όμ‹­μ‹œμ˜€.

λΈŒλΌμš°μ € μΊμ‹œ λ©”μ»€λ‹ˆμ¦˜κ³Ό κ΄€λ ¨μ΄μžˆμ„ 수 μžˆμŠ΅λ‹ˆκΉŒ?

쒋은 μƒκ°μ΄μ§€λ§Œ κ·Έλ ‡κ²Œ μƒκ°ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. λΈŒλΌμš°μ €κ°€ μ•„λ‹Œ μΆ”κ°€ λ©”λͺ¨λ¦¬λ₯Ό μ°¨μ§€ν•˜λŠ” IPython의 ν”„λ‘œμ„ΈμŠ€μž…λ‹ˆλ‹€.
@tacaswell 의 μž¬μƒμ‚°μ€ ν”Œλ‘―μ„ λΈŒλΌμš°μ €λ‘œ λ³΄λ‚΄λŠ” 것을 ν¬ν•¨ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

μ•ˆλ…•ν•˜μ„Έμš”, μ €λŠ” λ²”μΈμ˜ 일뢀와이 문제λ₯Ό μ™„μ „νžˆλŠ” μ•„λ‹ˆμ§€λ§Œ 크게 쀄일 μˆ˜μžˆλŠ” 방법을 μ°Ύμ•˜λ‹€ κ³  μƒκ°ν•©λ‹ˆλ‹€!

ipykernel/pylab/backend_inline.py μ½”λ“œλ₯Ό 슀크둀 ν•œ ν›„ λŒ€ν™” ν˜• λͺ¨λ“œκ°€ "ν”Œλ‘―-물건"을 많이 μ €μž₯ν•œλ‹€λŠ” 직감을 μ–»μ—ˆμŠ΅λ‹ˆλ‹€. μ™„μ „νžˆ μ΄ν•΄ν•˜μ§€λŠ” λͺ»ν–ˆμ§€λ§Œ μ •ν™•ν•œ 이유λ₯Ό μ°Ύμ•„ λ‚Ό 수 μ—†μŠ΅λ‹ˆλ‹€. ν™•μ‹€ν•˜κ²Œ.

λ‹€μŒμ€μ΄λ₯Ό ν™•μΈν•˜λŠ” μ½”λ“œμž…λ‹ˆλ‹€ (μœ„μ˜ @tacaswell 슀 λ‹ˆνŽ« 기반). μˆ˜μ •μ„ κ΅¬ν˜„ν•˜λ €λŠ” λͺ¨λ“  μ‚¬λžŒμ—κ²Œ μœ μš©ν•©λ‹ˆλ‹€.

μ΄ˆκΈ°ν™” :

import matplotlib
import matplotlib.pyplot as plt
import matplotlib.ticker

%matplotlib inline

matplotlib.rcParams['figure.figsize'] = (24, 6)
matplotlib.rcParams['figure.dpi'] = 150

from resource import getrusage
from resource import RUSAGE_SELF

def friendlyPlot():
    fig, ax = plt.subplots()
    ax.plot(range(1000))
    fig.savefig('tmp.png')
    plt.close('all')

μ‹€μ œ ν…ŒμŠ€νŠΈ :

print("before any:  {:7d} kB".format(getrusage(RUSAGE_SELF).ru_maxrss))
friendlyPlot()
print("before loop: {:7d} kB".format(getrusage(RUSAGE_SELF).ru_maxrss))
for i in range(50):
    friendlyPlot()
print("after loop:  {:7d} kB".format(getrusage(RUSAGE_SELF).ru_maxrss))
import gc ; gc.collect(2)
print("after gc:    {:7d} kB".format(getrusage(RUSAGE_SELF).ru_maxrss))

루프λ₯Ό 50 회 λ°˜λ³΅ν•˜λ©΄ λ‹€μŒκ³Ό 같은 κ²°κ³Όκ°€ λ‚˜νƒ€λ‚©λ‹ˆλ‹€.

before any:    87708 kB
before loop:  106772 kB
after loop:   786668 kB
after gc:     786668 kB

루프λ₯Ό 200 번 λ°˜λ³΅ν•˜λ©΄ λ‹€μŒκ³Ό 같은 κ²°κ³Όκ°€ λ‚˜νƒ€λ‚©λ‹ˆλ‹€.

before any:    87708 kB
before loop:  100492 kB
after loop:  2824316 kB
after gc:    2824540 kB

λ°˜λ³΅μ— λ”°λ₯Έ λ©”λͺ¨λ¦¬μ˜ 거의 μ„ ν˜•μ μΈ 증가λ₯Ό λ³΄μ—¬μ€λ‹ˆλ‹€.

이제 μˆ˜μ • / ν•΄κ²° 방법 : ν…ŒμŠ€νŠΈ 슀 λ‹ˆνŽ« 전에 matplotlib.interactive(False) λ₯Ό 호좜 ν•œ λ‹€μŒ μ‹€ν–‰ν•©λ‹ˆλ‹€.

50 회 반볡 :

before any:    87048 kB
before loop:  104992 kB
after loop:   241604 kB
after gc:     241604 kB

200 회 반볡 :

before any:    87536 kB
before loop:  103104 kB
after loop:   239276 kB
after gc:     239276 kB

μ΄λŠ” 반볡과 λ¬΄κ΄€ν•˜κ²Œ μΌμ •ν•œ 증가 만 λ‚¨μ•˜μŒμ„ ν™•μΈν•©λ‹ˆλ‹€.

이 숫자λ₯Ό μ‚¬μš©ν•˜μ—¬ 반볡 λ‹Ή λˆ„μΆœ 크기λ₯Ό λŒ€λž΅μ μœΌλ‘œ μΆ”μ •ν•©λ‹ˆλ‹€.

(786668-(241604 - 104992))/50   = 13001.12
(2824316-(241604 - 104992))/200 = 13438.52

그리고 λ£¨ν”„μ˜ 단일 λ°˜λ³΅μ— λŒ€ν•΄ 13560 μ–»μŠ΅λ‹ˆλ‹€. λ”°λΌμ„œ 반볡 λ‹Ή λˆ„μˆ˜ 양은 μ›μ‹œ (> 3MB) λ˜λŠ” png μ••μΆ• (54KB) 이미지 크기보닀 훨씬 μž‘μŠ΅λ‹ˆλ‹€.

λ˜ν•œ μ΄μƒν•˜κ²Œλ„ 컀널을 λ‹€μ‹œ μ‹œμž‘ν•˜μ§€ μ•Šκ³  λ™μΌν•œ μ…€μ—μ„œ μ†Œκ·œλͺ¨ ν…ŒμŠ€νŠΈ (λͺ‡ 번만 반볡)λ₯Ό 반볡적으둜 μ‹€ν–‰ν•˜λŠ” 것은 훨씬 일관성이 μ—†μ–΄μ„œμ΄λ₯Ό μ΄ν•΄ν•˜κ±°λ‚˜ νŒ¨ν„΄μ„ κ²°μ •ν•  수 μ—†μ—ˆμŠ΅λ‹ˆλ‹€.

내뢀에 λŒ€ν•œ 더 λ§Žμ€ 지식을 가진 μ‚¬λžŒμ΄ μ—¬κΈ°μ—μ„œ κ°€μ Έκ°ˆ 수 있기λ₯Ό λ°”λžλ‹ˆλ‹€. μ§€κΈˆ λ‹Ήμž₯ 더 깊이 νŒŒκ³ λ“€ μˆ˜μžˆλŠ” μ‹œκ°„κ³Ό 지식이 λΆ€μ‘±ν•˜κΈ° λ•Œλ¬Έμž…λ‹ˆλ‹€.

νš¨κ³Όκ°€μžˆλ‹€

이 νŽ˜μ΄μ§€κ°€ 도움이 λ˜μ—ˆλ‚˜μš”?
0 / 5 - 0 λ“±κΈ‰