TypeError: 'type' object is not subscriptable

 

첨자 가능한(subscriptable)이라는 개념입니다. []는 첨자 연산자(subscript operator)라고 부릅니다.

a = [1,2,3,4]가 있다면 a[0]처럼 첫 번째 원소를 가리키는 것이 첨자 연산자의 역할입니다. 파이썬은 슬라이스를 사용해 범위까지 가르킬 수 있습니다.



IndexError: list index out of range

 

if(a)

try:

exception

 

# 올바른 값을 넣지 않으면 에러를 발생시키고 적당한 문구를 표시한다.

def rsp(mine, yours):

    allowed = ['가위','바위', '보']

    if mine not in allowed:

        raise ValueError

    if yours not in allowed:

        raise ValueError

 

try:

    rsp('가위', '바')

except ValueError:

    print('잘못된 값을 넣었습니다!')



# 190이 넘는 학생을 발견하면 반복을 종료한다.

school = {'1반' : [150, 156, 179, 191, 199], '2반' : [150, 195, 179, 191, 199]}

 

try:

    for class_number, students in school.items():

        for student in students:

            if student > 190:

                print(class_number, '190을 넘는 학생이 있습니다.')

                # break # 바로 상위 for문은 종료되지만 최고 상위 for문은 종료되지 않는다.

                raise StopIteration

                # 예외가 try 문 안에 있지 않으면 에러 발생시 프로그램이 멈춘다.

except StopIteration:

    print('정상종료') 



# 모든 에러 처리

try:

    list = []

    print(list[0])  # 에러가 발생할 가능성이 있는 코드

 

    text = 'abc'

    number = int(text)

except:

    print('에러발생')

 

# 에러 이름 확인

try:

    list = []

    print(list[0])  # 에러가 발생할 가능성이 있는 코드

 

except Exception as ex: # 에러 종류

    print('에러가 발생 했습니다', ex) # ex는 발생한 에러의 이름을 받아오는 변수

    # 에러가 발생 했습니다 list index out of range



try:

    import your_module

except ImportError:

    print('모듈이 없습니다.')




 

항상 새롭네...

'{BE} Python 3.1x' 카테고리의 다른 글

파이썬을 쉘로 써보기  (0) 2021.05.26
파이썬 수 체계  (0) 2021.05.26
python 빌드해서 에러 문구 교체해 봄.  (0) 2021.05.26
how to see the encoding  (0) 2021.05.26
AI 기본은 필수...  (0) 2021.05.20

>>> import os

 

>>> os.getcwd()

'/Users/junhoha'




 

 

>>> os.system('ls')
Applications             PycharmProjects          gotoC
Applications (Parallels) TakeIT                   ios_bridge

 

>>> os.chdir("~/Documents/GitHub")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
FileNotFoundError: [Errno 2] No such file or directory: '~/Documents/GitHub'
>>> os.chdir("/Users/junhoha/Documents/GitHub")

 

>>> os.system('git clone git@github.com:hajunho/takeTouch.git')
Cloning into 'takeTouch'...
remote: Enumerating objects: 5, done.
remote: Counting objects: 100% (5/5), done.
remote: Compressing objects: 100% (4/4), done.
Receiving objects: 100% (5/5), 5.47 KiB | 5.47 MiB/s, done.
remote: Total 5 (delta 0), reused 0 (delta 0), pack-reused 0
0

 

>>> os.chdir('./takeTouch')
>>> os.getcwd()
'/Users/junhoha/Documents/GitHub/takeTouch'
>>> os.listdir()
['LICENSE', 'README.md', '.gitignore', '.git']

 




>>> os.system('open .')
0
>>> os.system('git add *')
0
>>> os.system('git commit -a')

 

>>> os.system('git push')
Enumerating objects: 52, done.
Counting objects: 100% (52/52), done.
Delta compression using up to 16 threads
Compressing objects: 100% (50/50), done.
Writing objects: 100% (51/51), 6.48 MiB | 534.00 KiB/s, done.
Total 51 (delta 3), reused 0 (delta 0)
remote: Resolving deltas: 100% (3/3), done.
To github.com:hajunho/takeTouch.git
   214d7fa..e2c8791  main -> main
0
>>> 

 

>>> def a(f):
...     os.system(f)
... 
>>> 

 

>>> def a():
...     a = input()
...     os.system(str(a))
... 
>>> a()
ls
LICENSE                            README.md
LICENSE 복사본                TakeTouch
README 복사본.md              Touch.xcodeproj

 

( :; LIBDEPS="${LIBDEPS:--Wl,-search_paths_first -L.. -lssl -L.. -lcrypto  }"; LDCMD="${LDCMD:-cc}"; LDFLAGS="${LDFLAGS:--DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -arch x86_64 -O3 -DL_ENDIAN -Wall -DOPENSSL_IA32_SSE2 -DOPENSSL_BN_ASM_MONT -DOPENSSL_BN_ASM_MONT5 -DOPENSSL_BN_ASM_GF2m -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DMD5_ASM -DAES_ASM -DVPAES_ASM -DBSAES_ASM -DWHIRLPOOL_ASM -DGHASH_ASM -DECP_NISTZ256_ASM}"; LIBPATH=`for x in $LIBDEPS; do echo $x; done | sed -e 's/^ *-L//;t' -e d | uniq`; LIBPATH=`echo $LIBPATH | sed -e 's/ /:/g'`; LD_LIBRARY_PATH=$LIBPATH:$LD_LIBRARY_PATH ${LDCMD} ${LDFLAGS} -o ${APPNAME:=dummytest} dummytest.o  ${LIBDEPS} )
making all in tools...
make[1]: Nothing to be done for `all'.

 

sudo make install


쉽진 않네.

'{BE} Python 3.1x' 카테고리의 다른 글

기본 에러 정리  (0) 2021.05.26
파이썬 수 체계  (0) 2021.05.26
python 빌드해서 에러 문구 교체해 봄.  (0) 2021.05.26
how to see the encoding  (0) 2021.05.26
AI 기본은 필수...  (0) 2021.05.20
√ ~ % python3
Python 3.7.9 (default, Nov 20 2020, 23:58:42) 
[Clang 12.0.0 (clang-1200.0.32.27)] on darwin
Type "help", "copyright", "credits" or "license" for more information.

 

기본자료형(Built-in Types, Primitive Types, Base Types)


숫자형(Numeric Type)

숫자형에는 정수형(Integer type), 부동 소수점형(fixed point, floating point), 복소수형(complex type)이 있다. 수학의 수의 체계에서 실수는 유리수와 무리수로 이루어진다. 유리수는 정수와 정수가 아닌 유리수로 이루어 진다. 수학의 수의 체계를 그대로 옮겨 놓은 것이 파이썬의 숫자형(Numeric Type) 이다.

 

파이썬 정수형의 한계(limitation)는 다음과 같이 알아 볼 수 있다.

√ ~ % python3 -c 'import sys; print(sys.maxsize)'
9223372036854775807

 

파이썬 실수형 정보는 다음과 같이 알 수 있다.

√ ~ % python3
Python 3.7.9 (default, Nov 20 2020, 23:58:42) 
[Clang 12.0.0 (clang-1200.0.32.27)] on darwin
Type "help", "copyright", "credits" or "license" for more information.

>>> import sys
>>> sys.float_info
sys.float_info(max=1.7976931348623157e+308, max_exp=1024, max_10_exp=308, min=2.2250738585072014e-308, min_exp=-1021, min_10_exp=-307, dig=15, mant_dig=53, epsilon=2.220446049250313e-16, radix=2, rounds=1)

 

프로그래머에게는 의미있는 몇 개의 숫자들이 있다.

 



 


 

파이썬의 수 체계는 64비트를 따른다는 것을 알 수 있다.

 

'{BE} Python 3.1x' 카테고리의 다른 글

기본 에러 정리  (0) 2021.05.26
파이썬을 쉘로 써보기  (0) 2021.05.26
python 빌드해서 에러 문구 교체해 봄.  (0) 2021.05.26
how to see the encoding  (0) 2021.05.26
AI 기본은 필수...  (0) 2021.05.20
√ ~/Documents/GitHub/pythoncore/Python-3.8.8 % ./configure 
checking build system type... x86_64-apple-darwin20.3.0
checking host system type... x86_64-apple-darwin20.3.0
checking for python3.8... python3.8
checking for --enable-universalsdk... no
checking for --with-universal-archs... no
checking MACHDEP... "darwin"
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/Applications/Xcode.app/C



make

 

Could not build the ssl module

 

Error: openssl@1.1 1.1.1i is already installed.
To upgrade to 1.1.1j, run:
  brew upgrade openssl@1.1
√ ~/Documents/GitHub/pythoncore/Python-3.8.8 % brew upgrade openssl@1.1
==> Upgrading 1 outdated package:
openssl@1.1 1.1.1i -> 1.1.1j
==> Upgrading openssl@1.1 1.1.1i -> 1.1.1j 
==> Downloading https://homebrew.bintray.com/bottles/openssl%401.1-1.1.1j.big_su
==> Downloading from https://d29vzk4ow07wi7.cloudfront.net/5725361adcd088a5b4fb2
######################################################################## 100.0%
==> Pouring openssl@1.1-1.1.1j.big_sur.bottle.tar.gz
√ ~/Documents/GitHub/pythoncore/Python-3.8.8 % brew reinstall openssl

 

 

 

https://github.com/libressl-portable/portable/issues/381
https://wiki.unify.com/wiki/openssl-1.0.2k.tar.gz_V1R0

 

  $ ./config
   $ make
   $ make test
   $ make install

 

ld: symbol(s) not found for architecture i386

 

WARNING! If you wish to build 64-bit library, then you have to
         invoke './Configure darwin64-x86_64-cc' *manually*.
         You have about 5 seconds to press Ctrl-C to abort.

 

./Configure darwin64-x86_64-cc

 

make clean
make

 

sudo make install

 

./configure again in python 3.8.8

 

make clean

 

make

 

To find the necessary bits, look in setup.py in detect_modules() for the module's name.


The following modules found by detect_modules() in setup.py, have been
built by the Makefile instead, as configured by the Setup files:
_abc                  atexit                pwd                
time                                                           


Failed to build these modules:
_tkinter     

 

brew install tcl-tk

 

√ ~/Documents/GitHub/pythoncore/Python-3.8.8 % brew install tcl-tk
Updating Homebrew...
Warning: tcl-tk 8.6.11_1 is already installed and up-to-date.
To reinstall 8.6.11_1, run:
  brew reinstall tcl-tk

 

If you need to have tcl-tk first in your PATH, run:
  echo 'export PATH="/usr/local/opt/tcl-tk/bin:$PATH"' >> ~/.zshrc

For compilers to find tcl-tk you may need to set:
  export LDFLAGS="-L/usr/local/opt/tcl-tk/lib"
  export CPPFLAGS="-I/usr/local/opt/tcl-tk/include"

For pkg-config to find tcl-tk you may need to set:
  export PKG_CONFIG_PATH="/usr/local/opt/tcl-tk/lib/pkgconfig"

 

X11/Xlib.h' file not found

 

xcode-select: error: command line tools are already installed, use "Software Update" to install updates

 

?1 ~/Documents/GitHub/pythoncore/Python-3.8.8 % softwareupdate --list
Software Update Tool

Finding available software
Software Update found the following new or updated software:
* Label: macOS Big Sur 11.2.2-20D80
Title: macOS Big Sur 11.2.2, Version: 11.2.2, Size: 2123844K, Recommended: YES, Action: restart, 
√ ~/Documents/GitHub/pythoncor

 

√ ~/Documents/GitHub/pythoncore/Python-3.8.8 % softwareupdate --install -a

 

https://www.tcl.tk/software/tcltk/

 

https://www.tcl.tk/software/tcltk/download.html

 

cd macosx ; ./configure ; make ; make test ; sudo make install

 

scanning section [incr Tcl] Package C API, version 4.2.1
......
scanning section TDBC Package C API, version 1.1.2
.
Assembling index
Rescanning 271 pages to build cross links and write out
...............................................................................................................................................................................................................................................................................
Done

 

'X11/Xlib.h' file not found

xcode-select --install

 

?127 ~/Documents/GitHub/pythoncore/Python-3.8.8 % ln -s /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/Tk.framework/Versions/8.5/Headers/X11/ /usr/local/include/X11

 

/usr/bin/install -c ./install-sh /usr/local/lib/python3.8/config-3.8-darwin/install-sh
/usr/bin/install -c python-config.py /usr/local/lib/python3.8/config-3.8-darwin/python-config.py
/usr/bin/install -c python-config /usr/local/bin/python3.8-config
./python.exe -E ./setup.py install \
  --prefix=/usr/local \
--install-scripts=/usr/local/bin \
--install-platlib=/usr/local/lib/python3.8/lib-dynload \
--root=/
running install
running build
running build_ext

Python build finished successfully!

 

~/Documents/GitHub/pythoncore/Python-3.8.8 % grep -Risn "Type \"help\", \"copyright\", \"credits\" or \"license\" for more information." *
Doc/tutorial/interpreter.rst:103:   Type "help", "copyright", "credits" or "license" for more information.
Doc/install/index.rst:245:   Type "help", "copyright", "credits" or "license" for more information.
Doc/install/index.rst:647:   Type "help", "copyright", "credits" or "license" for more information.
Doc/faq/windows.rst:69:   Type "help", "copyright", "credits" or "license" for more information.
Doc/library/sys.rst:1663:      Type "help", "copyright", "credits" or "license" for more information.
Doc/whatsnew/3.8.rst:643:    Type "help", "copyright", "credits" or "license" for more information.
Lib/code.py:212:        cprt = 'Type "help", "copyright", "credits" or "license" for more information.'
Binary file Modules/main.o matches
Binary file Programs/_testembed matches
Binary file libpython3.8.a matches
Binary file python.exe matches

 

        cprt = 'Type "help", "copyright", "credits" or "license" for more information.'
         if banner is None:
             self.write("Python %s on %s\n%s\n(%s)\n" %
                        (sys.version, sys.platform, cprt,
                         self.__class__.__name__))

 

vim ./Modules/main.c

 

203     if (!config->verbose && (config_run_code(config) || !                       stdin_is_interactive(config))) {
 204         return;
 205     }
 206 
 207     fprintf(stderr, "Junho's Python %s on %s\n", Py_GetVersion(),               Py_GetPlatform());
 208     if (config->site_import) {
 209         fprintf(stderr, "%s\n", COPYRIGHT);
 210     }
 211 }

 

√ ~/Documents/GitHub/pythoncore/Python-3.8.8 % grep -Risn "is not defined" * | grep name

 

√ ~/Documents/GitHub/pythoncore/Python-3.8.8 % vim Python/ceval.c

 

#define NAME_ERROR_MSG \
     "hjh name '%.200s' is not defined"

 

√ ~/Documents/GitHub/pythoncore/Python-3.8.8 % ./python.exe -c "ls"
Traceback (most recent call last):
  File "<string>", line 1, in <module>
NameError: hjh name 'ls' is not defined


'{BE} Python 3.1x' 카테고리의 다른 글

파이썬을 쉘로 써보기  (0) 2021.05.26
파이썬 수 체계  (0) 2021.05.26
how to see the encoding  (0) 2021.05.26
AI 기본은 필수...  (0) 2021.05.20
python에서 아쉬운 점 private, protected, public...  (0) 2021.04.06
# python3 -m venv temppy
# cd temppy
# source ./bin/activate
(temppy)  junhoha  ~/Documents/Github/temppy>  deactivate
 junhoha  ~/Documents/Github/temp/temppy

 

>>> import sys
>>> print(sys.stdin.encoding)
utf-8
>>> print(sys.stdout.encoding)
utf-8


Python 으로 행렬 만들기

 

Vector & Matrix

 

벡터와 행렬도 숫자처럼 덧셈, 뺄셈, 곱셈 등의 연산을 있다. 벡터와 행렬의 연산을 이용하면 대량의 데이터에 대한 계산을 간단한 수식으로 나타낼 있다. 물론 벡터와 행렬에 대한 연산은 숫자의 사칙 연산과는 가지 다른 점이 있으므로 이러한 차이를 알아야 한다.

절에서는 넘파이를 이용하여 벡터와 행렬의 연산을 실행하는 법도 공부한다. 다음처럼 넘파이와 맷플롯립 패키지가 임포트되어 있어야 한다.

In [1]:

import numpy as np

import matplotlib.pylab as plt

벡터/행렬의 덧셈과 뺄셈

같은 크기를 가진 개의 벡터나 행렬은 덧셈과 뺄셈을 있다. 벡터와 행렬에서 같은 위치에 있는 원소끼리 덧셈과 뺄셈을 하면 된다. 이러한 연산을 요소별(element-wise) 연산이라고 한다.

예를 들어 벡터 𝑥x 𝑦y 다음과 같으면,

𝑥=⎡⎣⎢⎢101112⎤⎦⎥⎥,𝑦=⎡⎣⎢⎢012⎤⎦⎥⎥(2.2.1)(2.2.1)x=[101112],y=[012]

벡터 𝑥x 𝑦y 덧셈 𝑥+𝑦x+y 뺄셈 𝑥−𝑦x−y 다음처럼 계산한다.

𝑥+𝑦=⎡⎣⎢⎢101112⎤⎦⎥⎥+⎡⎣⎢⎢012⎤⎦⎥⎥=⎡⎣⎢⎢10+011+112+2⎤⎦⎥⎥=⎡⎣⎢⎢101214⎤⎦⎥⎥(2.2.2)(2.2.2)x+y=[101112]+[012]=[10+011+112+2]=[101214]

𝑥−𝑦=⎡⎣⎢⎢101112⎤⎦⎥⎥−⎡⎣⎢⎢012⎤⎦⎥⎥=⎡⎣⎢⎢10−011−112−2⎤⎦⎥⎥=⎡⎣⎢⎢101010⎤⎦⎥⎥(2.2.3)(2.2.3)x−y=[101112]−[012]=[10−011−112−2]=[101010]

벡터의 덧셈과 뺄셈을 넘파이로 계산하면 다음과 같다. 여기에서는 편의상 1차원 배열로 벡터를 표시하였다.

In [2]:

x = np.array([10, 11, 12, 13, 14])

y = np.array([0, 1, 2, 3, 4])

In [3]:

x + y

array([10, 12, 14, 16, 18])

In [4]:

x - y

array([10, 10, 10, 10, 10])

행렬도 같은 방법으로 덧셈과 뺄셈을 있다.

[5768]+[10302040]−[1324]=[14342444](2.2.4)(2.2.4)[5678]+[10203040]−[1234]=[14243444]

In [5]:

np.array([[5, 6], [7, 8]]) + np.array([[10, 20], [30, 40]]) - \

np.array([[1, 2], [3, 4]])

array([[14, 24],

    [34, 44]])

스칼라와 벡터/행렬의 곱셈

벡터 𝑥x 또는 행렬 𝐴A 스칼라값 𝑐c 곱하는 것은 벡터 𝑥x 또는 행렬 𝐴A 모든 원소에 스칼라값 𝑐c 곱하는 같다.

𝑐[𝑥1𝑥2]=[𝑐𝑥1𝑐𝑥2](2.2.5)(2.2.5)c[x1x2]=[cx1cx2]

𝑐[𝑎11𝑎21𝑎12𝑎22]=[𝑐𝑎11𝑐𝑎21𝑐𝑎12𝑐𝑎22](2.2.6)(2.2.6)c[a11a12a21a22]=[ca11ca12ca21ca22]

브로드캐스팅

원래 덧셈과 뺄셈은 크기(차원) 같은 벡터에 대해서만 있다. 하지만 벡터와 스칼라의 경우에는 관례적으로 다음처럼 1-벡터를 사용하여 스칼라를 벡터로 변환한 연산을 허용한다. 이를 브로드캐스팅(broadcasting)이라고 한다.

⎡⎣⎢⎢101112⎤⎦⎥⎥−10=⎡⎣⎢⎢101112⎤⎦⎥⎥−10⋅1=⎡⎣⎢⎢101112⎤⎦⎥⎥−⎡⎣⎢⎢101010⎤⎦⎥⎥(2.2.7)(2.2.7)[101112]−10=[101112]−10⋅1=[101112]−[101010]

데이터 분석에서는 원래의 데이터 벡터 𝑥x 아니라 데이터 벡터의 원소의 평균값을 평균제거(mean removed) 벡터 혹은 0-평균(zero-mean) 벡터 사용하는 경우가 많다.

𝑥=⎡⎣⎢⎢⎢⎢𝑥1𝑥2⋮𝑥𝑁⎤⎦⎥⎥⎥⎥→𝑥−𝑚=⎡⎣⎢⎢⎢⎢𝑥1−𝑚𝑥2−𝑚⋮𝑥𝑁−𝑚⎤⎦⎥⎥⎥⎥(2.2.8)(2.2.8)x=[x1x2⋮xN]→x−m=[x1−mx2−m⋮xN−m]

식에서 𝑚m 샘플 평균이다.

𝑚=1𝑁∑𝑖=1𝑁𝑥𝑖(2.2.9)(2.2.9)m=1N∑i=1Nxi

선형조합

벡터/행렬에 다음처럼 스칼라값을 곱한 더하거나 것을 벡터/행렬의 선형조합(linear combination)이라고 한다. 벡터나 행렬을 선형조합해도 크기는 변하지 않는다.

𝑐1𝑥1+𝑐2𝑥2+𝑐3𝑥3+⋯+𝑐𝐿𝑥𝐿=𝑥(2.2.10)(2.2.10)c1x1+c2x2+c3x3+⋯+cLxL=x

𝑐1𝐴1+𝑐2𝐴2+𝑐3𝐴3+⋯+𝑐𝐿𝐴𝐿=𝐴(2.2.11)(2.2.11)c1A1+c2A2+c3A3+⋯+cLAL=A

𝑐1,𝑐2,…,𝑐𝐿𝐑(2.2.12)(2.2.12)c1,c2,…,cL∈R

𝑥1,𝑥2,…,𝑥𝐿,𝑥∈𝐑𝑀(2.2.13)(2.2.13)x1,x2,…,xL,x∈RM

𝐴1,𝐴2,…,𝐴𝐿,𝐴∈𝐑𝑀×𝑁(2.2.14)(2.2.14)A1,A2,…,AL,A∈RM×N

벡터나 행렬의 크기를 직사각형으로 표시하면 다음과 같다.

𝑐1𝑥1+𝑐2𝑥2+⋯+𝑐𝐿𝑥𝐿(2.2.15)(2.2.15)c1(x1(+c2(x2(+⋯+cL(xL(

𝑐1𝐴1+𝑐2𝐴2+⋯+𝑐𝐿𝐴𝐿(2.2.16)(2.2.16)c1A1+c2A2+⋯+cLAL

벡터와 벡터의 곱셈

행렬의 곱셈을 정의하기 전에 우선 벡터의 곱셈을 알아보자. 벡터를 곱셈하는 방법은 여러 가지가 있지만 여기서는 내적(inner product) 대해서만 다룬다. 벡터 𝑥x 벡터 𝑦y 내적은 다음처럼 표기한다.

𝑥𝑇𝑦(2.2.17)(2.2.17)xTy

내적은 다음처럼 (dot)으로 표기하는 경우도 있어서 프로덕트(dot product)라고도 부르고 < 𝑥,𝑦x,y > 기호로 나타낼 수도 있다.

𝑥⋅𝑦=<𝑥,𝑦>=𝑥𝑇𝑦(2.2.18)(2.2.18)x⋅y=<x,y>=xTy

벡터를 내적하려면 다음과 같은 조건이 만족되어야 한다.

1. 우선 벡터의 차원(길이) 같아야 한다.

2. 앞의 벡터가 벡터이고 뒤의 벡터가 벡터여야 한다.

이때 내적의 결과는 스칼라값이 되며 다음처럼 계산한다. 우선 같은 위치에 있는 원소들을 요소별 곱셈처럼 곱한 다음, 값들을 다시 모두 더해서 하나의 스칼라값으로 만든다.

𝑥𝑇𝑦=[𝑥1𝑥2⋯𝑥𝑁]⎡⎣⎢⎢⎢⎢𝑦1𝑦2⋮𝑦𝑁⎤⎦⎥⎥⎥⎥=𝑥1𝑦1+⋯+𝑥𝑁𝑦𝑁=∑𝑖=1𝑁𝑥𝑖𝑦𝑖(2.2.19)(2.2.19)xTy=[x1x2⋯xN][y1y2⋮yN]=x1y1+⋯+xNyN=∑i=1Nxiyi

𝑥∈𝐑𝑁×1(2.2.20)(2.2.20)x∈RN×1

𝑦∈𝐑𝑁×1(2.2.21)(2.2.21)y∈RN×1

𝑥𝑇𝑦∈𝐑(2.2.22)(2.2.22)xTy∈R

다음은 벡터의 내적의 예다.

𝑥=⎡⎣⎢⎢123⎤⎦⎥⎥,𝑦=⎡⎣⎢⎢456⎤⎦⎥⎥(2.2.23)(2.2.23)x=[123],y=[456]

𝑥𝑇𝑦=[123]⎡⎣⎢⎢456⎤⎦⎥⎥=1⋅4+2⋅5+3⋅6=32(2.2.24)(2.2.24)xTy=[123][456]=1⋅4+2⋅5+3⋅6=32

넘파이에서 벡터와 행렬의 내적은 dot()이라는 명령 또는 @(at이라고 읽는다)이라는 연산자로 계산한다. 2차원 배열로 표시한 벡터를 내적했을 때는 결과값이 스칼라가 아닌 2차원 배열이다.

In [6]:

x = np.array([[1], [2], [3]])

y = np.array([[4], [5], [6]])

 

x.T @ y  # 또는 np.dot(x.T, y)

array([[32]])

넘파이에서는 1차원 배열끼리도 내적을 계산한다. 이때는 넘파이가 앞의 벡터는 벡터이고 뒤의 벡터는 벡터라고 가정한다.

In [7]:

x = np.array([1, 2, 3])

y = np.array([4, 5, 6])

 

x @ y  # 또는 np.dot(x, y)

32

벡터의 내적은 덧셈이나 뺄셈과 달리 이렇게 복잡하게 정의된 것일까? 이유는 데이터 분석을 이러한 연산이 필요하기 때문이다. 벡터의 내적을 사용하여 데이터를 분석하는 가지 예를 살펴보자.

가중합

벡터의 내적은 가중합을 계산할 쓰일 있다. 가중합(weighted sum)이란 복수의 데이터를 단순히 합하는 것이 아니라 각각의 수에 어떤 가중치 값을 곱한 곱셈 결과들을 다시 합한 것을 말한다.

만약 데이터 벡터가 𝑥=[𝑥1,⋯,𝑥𝑁]𝑇x=[x1,⋯,xN]T이고 가중치 벡터가 𝑤=[𝑤1,⋯,𝑤𝑁]𝑇w=[w1,⋯,wN]T이면 데이터 벡터의 가중합은 다음과 같다.

𝑤1𝑥1+⋯+𝑤𝑁𝑥𝑁=∑𝑖=1𝑁𝑤𝑖𝑥𝑖(2.2.25)(2.2.25)w1x1+⋯+wNxN=∑i=1Nwixi

값을 벡터 𝑥x 𝑤w 곱으로 나타내면 𝑤𝑇𝑥wTx 또는 𝑥𝑇𝑤xTw 라는 간단한 수식으로 표시할 있다.

𝑖=1𝑁𝑤𝑖𝑥𝑖=[𝑤1𝑤2⋯𝑤𝑁]⎡⎣⎢⎢⎢⎢𝑥1𝑥2⋮𝑥𝑁⎤⎦⎥⎥⎥⎥=[𝑥1𝑥2⋯𝑥𝑁]⎡⎣⎢⎢⎢⎢𝑤1𝑤2⋮𝑤𝑁⎤⎦⎥⎥⎥⎥=𝑤𝑇𝑥=𝑥𝑇𝑤(2.2.26)(2.2.26)∑i=1Nwixi=[w1w2⋯wN][x1x2⋮xN]=wTx=[x1x2⋯xN][w1w2⋮wN]=xTw

예를 들어 쇼핑을 물건의 가격은 데이터 벡터, 물건의 수량은 가중치로 생각하여 내적을 구하면 총금액을 계산할 있다.

만약 가중치가 모두 1이면 일반적인 (sum) 계산한다.

𝑤1=𝑤2=⋯=𝑤𝑁=1(2.2.27)(2.2.27)w1=w2=⋯=wN=1

또는

𝑤=1𝑁(2.2.28)(2.2.28)w=1N

이면

𝑖=1𝑁𝑥𝑖=1𝑇𝑁𝑥(2.2.29)(2.2.29)∑i=1Nxi=1NTx

연습 문제 2.2.1
A, B, C 회사의 주식은 각각 100만원, 80만원, 50만원이다. 주식을 각각 3, 4, 5주를 매수할 필요한 금액을 구하고자 한다.
(1) 주식의 가격과 수량을 각각 𝑝p 벡터, 𝑛n 벡터로 표시하고 넘파이로 코딩한다.
(2) 주식을 매수할 필요한 금액을 곱셈으로 표시하고 넘파이 연산으로 값을 계산한다.

가중평균

가중합의 가중치값을 전체 가중치값의 합으로 나누면 가중평균(weighted average) 된다. 가중평균은 대학교의 평균 성적 계산 등에 사용할 있다.

예를 들어 고등학교에서는 국어, 영어, 과목의 평균 점수를 구할 단순히 과목의 점수(숫자) 더한 2으로 나눈다. 그러나 대학교에서는 중요한 과목과 중요하지 않는 과목을 구분하는 학점(credit)이라는 숫자가 있다. 일주일에 시간만 수업하는 과목은 1학점짜리 과목이고 일주일에 시간씩 수업하는 중요한 과목은 3학점짜리 과목이다. 1학점과 3학점 과목의 점수가 각각 100, 60점이면 학점을 고려한 가중 평균(weighted average) 성적은 다음과 같이 계산한다.

11+3×100+31+3×60=70(2.2.30)(2.2.30)11+3×100+31+3×60=70

벡터로 표현된 𝑁N개의 데이터의 단순 평균은 다음처럼 생각할 있다.

𝑥¯=1𝑁∑𝑖=1𝑁𝑥𝑖=1𝑁1𝑇𝑁𝑥(2.2.31)(2.2.31)x¯=1N∑i=1Nxi=1N1NTx

수식에서 보인 것처럼 𝑥x 데이터의 평균은 보통 𝑥¯라는 기호로 표기하고 "엑스 (x bar)" 라고 읽는다.

다음은 넘파이로 평균을 계산하는 방법이다.

In [8]:

x = np.arange(10)

N = len(x)

 

np.ones(N) @ x / N

4.5

현실적으로는 mean()이라는 메서드를 사용하는 것이 편하다.

In [9]:

x.mean()

4.5

연습 문제 2.2.2
벡터 𝑥x 평균 제거 벡터는 다음과 같이 계산함을 증명하라.
𝑥−1𝑁1𝑇𝑁𝑥1𝑁(2.2.32)(2.2.32)x−1N1NTx1N

유사도

벡터의 곱셈(내적) 벡터 간의 유사도를 계산하는 데도 이용할 있다. 유사도(similarity) 벡터가 닮은 정도를 정량적으로 나타낸 으로 벡터가 비슷한 경우에는 유사도가 커지고 비슷하지 앟은 경우에는 유사도가 작아진다. 내적을 이용하면 코사인 유사도(cosine similarity)라는 유사도를 계산할 있다. 추후 선형대수의 기하학적 의미를 공부할 코사인 유사도에 대해 살펴볼 것이다.

예를 들어 0 1 나타내는 MNIST 이미지에 대해 내적을 계산해보자.

In [10]:

from sklearn.datasets import load_digits

import matplotlib.gridspec as gridspec

 

digits = load_digits()

d1 = digits.images[0]

d2 = digits.images[10]

d3 = digits.images[1]

d4 = digits.images[11]

v1 = d1.reshape(64, 1)

v2 = d2.reshape(64, 1)

v3 = d3.reshape(64, 1)

v4 = d4.reshape(64, 1)

 

plt.figure(figsize=(9, 9))

gs = gridspec.GridSpec(1, 8, height_ratios=[1],

                    width_ratios=[9, 1, 9, 1, 9, 1, 9, 1])

for i in range(4):

plt.subplot(gs[2 * i])

plt.imshow(eval("d" + str(i + 1)), aspect=1,

            interpolation='nearest', cmap=plt.cm.bone_r)

plt.grid(False)

plt.xticks([])

plt.yticks([])

plt.title("image {}".format(i + 1))

plt.subplot(gs[2 * i + 1])

plt.imshow(eval("v" + str(i + 1)), aspect=0.25,

            interpolation='nearest', cmap=plt.cm.bone_r)

plt.grid(False)

plt.xticks([])

plt.yticks([])

plt.title("vector {}".format(i + 1))

plt.tight_layout()

plt.show()

"0" 이미지와 "0" 이미지, 또는 "1" 이미지와 "1" 이미지의 내적값은 다음과 같다.

In [11]:

(v1.T @ v2)[0][0], (v3.T @ v4)[0][0]

(3064.0, 3661.0)

상대적으로 "0" 이미지와 "1" 이미지, 또는 "1" 이미지와 "0" 이미지의 내적값은 작다.

In [12]:

(v1.T @ v3)[0][0], (v1.T @ v4)[0][0], (v2.T @ v3)[0][0], (v2.T @ v4)[0][0]

(1866.0, 1883.0, 2421.0, 2479.0)

연습 문제 2.2.3
다음 코드를 실행하면 MNIST 숫자 이미지 전체 데이터를 모두 벡터로 변환하여 하나의 넘파이 행렬 X 만든다. 행렬을 이용하여 다음 문제를 풀어라.
from sklearn.datasets import load_digits
X = load_digits().data
(1) 내적을 이용하여 번째 이미지와 10번째 이미지의 유사도를 구하라.
(2) 내적을 이용하여 모든 이미지의 조합에 대해 유사도를 구하라. 어떻게 구현하는 것이 효율적일까? (힌트 : 문제는 뒤에서 배울 행렬과 행렬의 곱셈을 이용한다.)

선형회귀 모형

선형회귀 모형(linear regression model)이란 독립변수 𝑥x에서 종속변수 𝑦y 예측하는 방법의 하나로 독립변수 벡터 𝑥x 가중치 벡터 𝑤w와의 가중합으로 𝑦y 대한 예측값 𝑦̂ y^ 계산하는 수식을 말한다.

𝑦̂ =𝑤1𝑥1+⋯+𝑤𝑁𝑥𝑁(2.2.33)(2.2.33)y^=w1x1+⋯+wNxN

수식에서 기호 ^ "캐럿(caret)"이라는 기호이다. 𝑦̂ y^ "와이 (y hat)"이라고 읽는다.

수식은 다음처럼 벡터의 내적으로 나타낼 있다.

𝑦̂ =𝑤𝑇𝑥(2.2.34)(2.2.34)y^=wTx

선형회귀 모형은 가장 단순하면서도 가장 널리 쓰이는 예측 모형이다.

예를 들어 어떤 아파트 단지의 아파트 가격을 조사하였더니 아파트 가격은 (1)면적, (2)층수, (3)한강이 보이는지의 여부, 가지 특징에 의해 달라진다는 사실을 알게 되었다. 이때 단지 내의 아파트 가격을 예측하는 예측 모형을 다음과 같이 만들 있다.

·   면적(𝑚2m2) 입력 데이터 𝑥1x1라고 한다.

·   층수를 입력 데이터 𝑥2x2라고 한다

·   한강이 보이는지의 여부를 입력 데이터 𝑥3x3라고 하며 한강이 보이면 𝑥3=1x3=1, 보이지 않으면 𝑥3=0x3=0이라고 한다.

·   출력 데이터 𝑦̂ y^ 해당 아파트의 예측 가격이다.

위와 같이 입력 데이터와 출력 데이터를 정의하고 회귀분석을 결과, 아파트값이 다음과 같은 선형회귀 모형으로 나타난다고 가정하자. 이러한 모형을 실제로 찾는 방법은 나중에 회귀분석 파트에서 공부하게 된다.

𝑦̂ =500𝑥1+200𝑥2+1000𝑥3(2.2.35)(2.2.35)y^=500x1+200x2+1000x3

모형은 다음과 같이 해석할 있다.

·   면적이 1𝑚2m2 증가할수록 가격은 500 원이 증가한다.

·   층수가 1 높아질수록 가격은 200 원이 증가한다.

·   한강이 보이는 집은 1,000 원의 웃돈(프리미엄) 존재한다.

식은 다음과 같이 벡터의 내적으로 고쳐 있다.

𝑦̂ =[5002001000]⎡⎣⎢⎢𝑥1𝑥2𝑥3⎤⎦⎥⎥=𝑤𝑇𝑥(2.2.36)(2.2.36)y^=[5002001000][x1x2x3]=wTx

, 선형회귀 모형은 다음 가중치 벡터로 대표된다.

𝑤𝑇=[5002001000](2.2.37)(2.2.37)wT=[5002001000]

인공신경망(artificial neural network)에서는 선형회귀 모형을 다음과 같은 그림으로 표현한다. 데이터는 노드(node) 혹은 뉴런(neuron)이라는 동그라미로 표시하고 곱셈은 선분(line)위에 곱할 숫자를 써서 나타낸다. 덧셈은 여러 개의 선분이 만나는 것으로 표시한다.

그림 2.2.1 인공신경망으로 표현한 선형회귀 모형

선형회귀 모형의 단점

선형회귀 모형은 비선형적인 현실 세계의 데이터를 예측하지 못할 있다는 단점이 있다. 예를 들어 집값은 면적에 단순 비례하지 않는다. 소형 면적의 집과 대형 면적의 집은 단위 면적당 집값의 증가율이 다를 있다. 또한 저층이 보통 고층보다 집값이 싸지만 층수가 올라갈수록 정확히 층수에 비례하여 가격이 증가하지도 않는다.

이러한 현실 세계의 데이터와 선형회귀 모형의 괴리를 줄이기 위해 선형회귀 모형이 아닌 완전히 다른 모형을 쓰기보다는 선형회귀 모형을 기반으로 여러 기법을 사용해 수정한 모형을 사용하는 것이 일반적이다. 이러한 수정 선형회귀 모형에 대해서는 나중에 공부하게 된다.

제곱합

데이터의 분산(variance)이나 표준 편차(standard deviation) 등을 구하는 경우에는 각각의 데이터를 제곱한 값을 모두 더한 제곱합(sum of squares) 계산해야 한다. 경우에도 벡터의 내적을 사용하여 𝑥𝑇𝑥xTx 있다.

𝑥𝑇𝑥=[𝑥1𝑥2⋯𝑥𝑁]⎡⎣⎢⎢⎢⎢𝑥1𝑥2⋮𝑥𝑁⎤⎦⎥⎥⎥⎥=∑𝑖=1𝑁𝑥2𝑖(2.2.38)(2.2.38)xTx=[x1x2⋯xN][x1x2⋮xN]=∑i=1Nxi2

행렬과 행렬의 곱셈

벡터의 곱셈을 정의한 후에는 이를 이용하여 행렬의 곱셈을 정의할 있다. 행렬과 행렬을 곱하면 행렬이 된다. 방법은 다음과 같다.

𝐴A 행렬과 𝐵B 행렬을 곱한 결과가 𝐶C 행렬이 된다고 하자. 𝐶C 𝑖i번째 , 𝑗j번째 열의 원소 𝑐𝑖𝑗cij 값은 𝐴A 행렬의 𝑖i번째 벡터 𝑎𝑇𝑖aiT 𝐵B 행렬의 𝑗j번째 벡터 𝑏𝑗bj 곱이다.

𝐶=𝐴𝐵→𝑐𝑖𝑗=𝑎𝑇𝑖𝑏𝑗(2.2.39)(2.2.39)C=AB→cij=aiTbj

정의가 성립하려면 앞의 행렬 𝐴A 열의 수가 뒤의 행렬 𝐵B 행의 수와 일치해야만 한다.

𝐴∈𝐑𝑁×𝐿,𝐵∈𝐑𝐿×𝑀→𝐴𝐵∈𝐑𝑁×𝑀(2.2.40)(2.2.40)A∈RN×L,B∈RL×M→AB∈RN×M

다음은 4×34×3 행렬과 3×23×2 곱하여 4×24×2 계산하는 예다.

⎡⎣⎢⎢⎢⎢𝑎11𝑎21𝑎31𝑎41𝑎12𝑎22𝑎32𝑎42𝑎13𝑎23𝑎33𝑎43⎤⎦⎥⎥⎥⎥⎡⎣⎢⎢𝑏11𝑏21𝑏31𝑏12𝑏22𝑏32⎤⎦⎥⎥=⎡⎣⎢⎢⎢⎢(𝑎11𝑏11+𝑎12𝑏21+𝑎13𝑏31)(𝑎21𝑏11+𝑎22𝑏21+𝑎23𝑏31)(𝑎31𝑏11+𝑎32𝑏21+𝑎33𝑏31)(𝑎41𝑏11+𝑎42𝑏21+𝑎43𝑏31)(𝑎11𝑏12+𝑎12𝑏22+𝑎13𝑏32)(𝑎21𝑏12+𝑎22𝑏22+𝑎23𝑏32)(𝑎31𝑏12+𝑎32𝑏22+𝑎33𝑏32)(𝑎41𝑏12+𝑎42𝑏22+𝑎43𝑏32)⎤⎦⎥⎥⎥⎥(2.2.41)(2.2.41)[a11a12a13a21a22a23a31a32a33a41a42a43][b11b12b21b22b31b32]=[(a11b11+a12b21+a13b31)(a11b12+a12b22+a13b32)(a21b11+a22b21+a23b31)(a21b12+a22b22+a23b32)(a31b11+a32b21+a33b31)(a31b12+a32b22+a33b32)(a41b11+a42b21+a43b31)(a41b12+a42b22+a43b32)]

다음은 실제 행렬을 사용한 곱셈의 예다.

𝐴=[142536](2.2.42)(2.2.42)A=[123456]

𝐵=⎡⎣⎢⎢135246⎤⎦⎥⎥(2.2.43)(2.2.43)B=[123456]

𝐶=𝐴𝐵=[22492864](2.2.44)(2.2.44)C=AB=[22284964]

넘파이를 이용하여 행렬의 곱을 구할 때도 @ 연산자 또는 dot() 명령을 사용한다.

In [13]:

A = np.array([[1, 2, 3], [4, 5, 6]])

B = np.array([[1, 2], [3, 4], [5, 6]])

C = A @ B

C

array([[22, 28],

    [49, 64]])

연습 문제 2.2.4
(1) 𝐴A 𝐵B 위와 같을 𝐴𝐵AB 연습장에 손으로 계산하고 넘파이의 계산 결과와 맞는지 확인한다.
(2) 순서를 바꾸어 𝐵𝐴BA 손으로 계산하고 넘파이의 계산 결과와 맞는지 확인한다. 𝐵𝐴BA 𝐴𝐵AB 같은가?
(3) 𝐴A, 𝐵B 다음과 같을 , 𝐴𝐵AB, 𝐵𝐴BA (계산이 가능하다면) 손으로 계산하고 넘파이의 계산 결과와 맞는지 확인한다. 𝐴𝐵AB, 𝐵𝐴BA 모두 계산 가능한가?
𝐴=[123](2.2.45)(2.2.45)A=[123]
𝐵=⎡⎣⎢⎢456789⎤⎦⎥⎥(2.2.46)(2.2.46)B=[475869]
(4) 𝐴A, 𝐵B 다음과 같을 , 𝐴𝐵AB, 𝐵𝐴BA (계산이 가능하다면) 손으로 계산하고 넘파이의 계산 결과와 맞는지 확인한다. 𝐴𝐵AB, 𝐵𝐴BA 모두 계산 가능한가? 𝐵𝐴BA 결과가 𝐴𝐵AB 같은가?
𝐴=[1324](2.2.47)(2.2.47)A=[1234]
𝐵=[5768](2.2.48)(2.2.48)B=[5678]
(5) 𝐴A 다음과 같을 , 𝐴𝐴𝑇AAT 𝐴𝑇𝐴ATA 손으로 계산하고 넘파이의 계산 결과와 맞는지 확인한다. 𝐴𝐴𝑇AAT 𝐴𝑇𝐴ATA 크기는 어떠한가? 항상 정방행렬이 되는가?
𝐴=⎡⎣⎢⎢135246⎤⎦⎥⎥(2.2.49)(2.2.49)A=[123456]
(6) 𝑥x 다음과 같을 , 𝑥𝑇𝑥xTx 𝑥𝑥𝑇xxT 손으로 계산하고 넘파이의 계산 결과와 맞는지 확인한다. 𝑥𝑇𝑥xTx 𝑥𝑥𝑇xxT 크기는 어떠한가? 어떤 것이 스칼라이고 어떤 것이 정방행렬인가?
𝑥=⎡⎣⎢⎢123⎤⎦⎥⎥(2.2.50)(2.2.50)x=[123]

인공 신경망은 내부적으로 다음과 같이 여러 개의 선형회귀 모형을 사용한다. 구조는 행렬과 벡터의 곱으로 나타낼 있다.

그림 2.2.2 인공신경망의 기본 구조

그림을 행렬식으로 표현하면 다음과 같다.

[𝑦̂ 1𝑦̂ 2]=[𝑤11𝑤21𝑤12𝑤22𝑤13𝑤23]⎡⎣⎢⎢𝑥1𝑥2𝑥3⎤⎦⎥⎥(2.2.51)(2.2.51)[y^1y^2]=[w11w12w13w21w22w23][x1x2x3]

𝑦̂ =𝑊𝑥(2.2.52)(2.2.52)y^=Wx

교환 법칙과 분배 법칙

행렬의 곱셈은 곱하는 행렬의 순서를 바꾸는 교환 법칙이 성립하지 않는다. 그러나 덧셈에 대한 분배 법칙은 성립한다.

𝐴𝐵≠𝐵𝐴(2.2.53)(2.2.53)AB≠BA

𝐴(𝐵+𝐶)=𝐴𝐵+𝐴𝐶(2.2.54)(2.2.54)A(B+C)=AB+AC

(𝐴+𝐵)𝐶=𝐴𝐶+𝐵𝐶(2.2.55)(2.2.55)(A+B)C=AC+BC

𝐴A, 𝐵B, 𝐶C 다음과 같을 법칙을 넘파이로 살펴보자.

𝐴=[1324](2.2.56)(2.2.56)A=[1234]

𝐵=[5768](2.2.57)(2.2.57)B=[5678]

𝐶=[9786](2.2.58)(2.2.58)C=[9876]

In [14]:

A = np.array([[1, 2], [3, 4]])

B = np.array([[5, 6], [7, 8]])

C = np.array([[9, 8], [7, 6]])

𝐴𝐵AB 𝐵𝐴BA 값은 다음처럼 다른 값이 나오므로 교환법칙이 성립하지 않음을 있다.

In [15]:

A @ B

array([[19, 22],

    [43, 50]])

In [16]:

B @ A

array([[23, 34],

    [31, 46]])

분배법칙은 다음과 같이 성립한다.

In [17]:

A @ (B + C)

array([[42, 42],

    [98, 98]])

In [18]:

A @ B + A @ C

array([[42, 42],

    [98, 98]])

In [19]:

(A + B) @ C

array([[110,  96],

    [174, 152]])

In [20]:

A @ C + B @ C

array([[110,  96],

    [174, 152]])

전치 연산도 마찬가지로 덧셈/뺄셈에 대해 분배 법칙이 성립한다.

(𝐴+𝐵)𝑇=𝐴𝑇+𝐵𝑇(2.2.59)(2.2.59)(A+B)T=AT+BT

전치 연산과 곱셈의 경우에는 분배 법칙이 성립하기는 하지만 전치 연산이 분배되면서 곱셈의 순서가 바뀐다.

(𝐴𝐵)𝑇=𝐵𝑇𝐴𝑇(2.2.60)(2.2.60)(AB)T=BTAT

(𝐴𝐵𝐶)𝑇=𝐶𝑇𝐵𝑇𝐴𝑇(2.2.61)(2.2.61)(ABC)T=CTBTAT

마찬가지로 넘파이로 법칙이 성립하는지 살펴보자.

In [21]:

(A + B).T

array([[ 6, 10],

    [ 8, 12]])

In [22]:

A.T + B.T

array([[ 6, 10],

    [ 8, 12]])

In [23]:

(A @ B).T

array([[19, 43],

    [22, 50]])

In [24]:

B.T @ A.T

array([[19, 43],

    [22, 50]])

연습 문제 2.2.5
(1) 길이가 같은 일벡터 1𝑁𝐑𝑁1N∈RN 행벡터 𝑥∈𝐑𝑁x∈RN 곱은 행벡터 𝑥x 반복하여 가지는 행렬과 같음을 보여라.
1𝑁𝑥𝑇=⎡⎣⎢⎢⎢⎢𝑥𝑇𝑥𝑇⋮𝑥𝑇⎤⎦⎥⎥⎥⎥(2.2.62)(2.2.62)1NxT=[xTxT⋮xT]
(2) 행렬 𝑋(𝑋∈𝐑𝑁×𝑀)X(X∈RN×M) 있을 , 행렬의 열의 평균으로 이루어진 벡터 𝑥¯(𝑥¯∈𝐑𝑀)x¯(x¯∈RM) 다음과 같음을 보여라.
𝑥¯=1𝑁𝑋𝑇1𝑁(2.2.63)(2.2.63)x¯=1NXT1N
(3) 행렬 𝑋¯ (𝑋¯∈𝐑𝑁×𝑀)X¯ (X¯∈RN×M) 동일한 벡터 𝑥¯𝑇x¯T 𝑁N 누적하여 만든 행렬이다. 열의 모든 값이 열의 평균으로 이루어진 행렬이다.
𝑋¯=⎡⎣⎢⎢⎢⎢𝑥¯𝑇𝑥¯𝑇⋮𝑥¯𝑇⎤⎦⎥⎥⎥⎥(2.2.64)(2.2.64)X¯=[x¯Tx¯T⋮x¯T]
이때 𝑋¯ 다음과 같음을 보여라.
𝑋¯=1𝑁1𝑁1𝑇𝑁𝑋(2.2.65)(2.2.65)X¯=1N1N1NTX
(4) 다음 코드를 실행하면 붓꽃 전체 데이터를 모두 벡터로 변환하여 하나의 넘파이 행렬 X 만든다.
from sklearn.datasets import load_iris
X = load_iris().data
데이터로 행렬 𝑋¯ 값을 계산하라. 행렬은 번째 열의 값이 모두 같은 값으로 붓꽃의 꽃받침의 길이(sepal length) 평균이고 번째 열의 값이 모두 같은 값으로 붓꽃의 꽃받침의 (sepal width) 평균, 이런 식으로 계산된 행렬이다.

곱셈의 연결

연속된 행렬의 곱셈은 계산 순서를 임의의 순서로 해도 상관없다.

𝐴𝐵𝐶=(𝐴𝐵)𝐶=𝐴(𝐵𝐶)(2.2.66)(2.2.66)ABC=(AB)C=A(BC)

𝐴𝐵𝐶𝐷=((𝐴𝐵)𝐶)𝐷=(𝐴𝐵)(𝐶𝐷)=𝐴(𝐵𝐶𝐷)=𝐴(𝐵𝐶)𝐷(2.2.67)(2.2.67)ABCD=((AB)C)D=(AB)(CD)=A(BCD)=A(BC)D

연습 문제 2.2.6
다음 행렬의 곱셈을 순서를 바꾸어 가지 방법으로 해본다.
[12][1324][56](2.2.68)(2.2.68)[12][1234][56]

항등행렬의 곱셈

어떤 행렬이든 항등행렬을 곱하면 행렬의 값이 변하지 않는다.

𝐴𝐼=𝐼𝐴=𝐴(2.2.69)(2.2.69)AI=IA=A

넘파이로 다음과 같이 확인한다.

In [25]:

A = np.array([[1, 2], [3, 4]])

I = np.eye(2)

In [26]:

A @ I

array([[1., 2.],

    [3., 4.]])

In [27]:

I @ A

array([[1., 2.],

    [3., 4.]])

행렬과 벡터의

그럼 이러한 행렬의 곱셈은 데이터 분석에서 어떤 경우에 사용될까? 행렬의 곱셈 가장 널리 쓰이는 것은 다음과 같은 형태의 행렬 𝑀M 벡터 𝑣v 곱이다.

𝑀𝑣(2.2.70)(2.2.70)Mv

벡터와 행렬의 크기를 직사각형으로 표시하면 다음과 같다.

𝑀𝑣=𝑀𝑣(2.2.71)(2.2.71)M(v(=Mv

행렬과 벡터의 곱을 사용하는 몇가지 예를 살펴보자.

벡터의 선형조합

행렬 𝑋X 벡터 𝑤w 곱은 행렬 𝑋X 이루는 열벡터 𝑐1,𝑐2,…,𝑐𝑀c1,c2,…,cM 뒤에 곱해지는 벡터 𝑤w 성분 𝑤1,𝑤2,…,𝑤𝑀w1,w2,…,wM으로 선형조합(linear combination) 결과 벡터와 같다.

𝑋𝑤=[𝑐1𝑐2⋯𝑐𝑀]⎡⎣⎢⎢⎢⎢𝑤1𝑤2⋮𝑤𝑀⎤⎦⎥⎥⎥⎥=𝑤1𝑐1+𝑤2𝑐2+⋯+𝑤𝑀𝑐𝑀(2.2.72)(2.2.72)Xw=[c1c2⋯cM][w1w2⋮wM]=w1c1+w2c2+⋯+wMcM

벡터의 크기를 직사각형으로 표시하면 다음과 같다.

⎡⎣⎢⎢⎢⎢⎢𝑐1𝑐2⋯𝑐𝑀⎤⎦⎥⎥⎥⎥⎥⎡⎣⎢⎢⎢⎢𝑤1𝑤2⋮𝑤𝑀⎤⎦⎥⎥⎥⎥=𝑤1𝑐1+𝑤2𝑐2+⋯+𝑤𝑀𝑐𝑀(2.2.73)(2.2.73)[(c11((c21(⋯(cM(][w1w2⋮wM]=w1(c11(+w2(c21(+⋯+wM(cM(

연습 문제 2.2.7
다음 행렬 𝑋X 벡터 𝑤w 대해 𝑋𝑤Xw 열벡터 𝑐1,𝑐2,𝑐3c1,c2,c3 선형조합 𝑤1𝑐1+𝑤2𝑐2+𝑤3𝑐3w1c1+w2c2+w3c3 됨을 실제 계산으로 증명하라.
𝑋=[142536],𝑤=⎡⎣⎢⎢234⎤⎦⎥⎥(2.2.74)(2.2.74)X=[123456],w=[234]
연습 문제 2.2.8
벡터 𝑣1,𝑣2,𝑣3v1,v2,v3 이루어진 행렬 𝑉V 벡터 𝜆λ 대해 다음 식이 성립함을 증명하라. 식에서 𝜆1λ1 스칼라이다.
𝑉𝜆=[𝑣1𝑣2𝑣3]⎡⎣⎢⎢𝜆100⎤⎦⎥⎥=𝜆1𝑣1(2.2.75)(2.2.75)Vλ=[v1v2v3][λ100]=λ1v1

벡터의 선형조합은 다양한 분야에 응용된다. 예를 들어 이미지 벡터의 선형조합은 이미지를 섞어놓은 모핑(morphing) 효과를 얻는 사용할 있다.

In [28]:

from sklearn.datasets import fetch_olivetti_faces

 

faces = fetch_olivetti_faces()

 

f, ax = plt.subplots(1, 3)

 

ax[0].imshow(faces.images[6], cmap=plt.cm.bone)

ax[0].grid(False)

ax[0].set_xticks([])

ax[0].set_yticks([])

ax[0].set_title("image 1: $x_1$")

 

ax[1].imshow(faces.images[10], cmap=plt.cm.bone)

ax[1].grid(False)

ax[1].set_xticks([])

ax[1].set_yticks([])

ax[1].set_title("image 2: $x_2$")

 

new_face = 0.7 * faces.images[6] + 0.3 * faces.images[10]

ax[2].imshow(new_face, cmap=plt.cm.bone)

ax[2].grid(False)

ax[2].set_xticks([])

ax[2].set_yticks([])

ax[2].set_title("image 3: $0.7x_1 + 0.3x_2$")

 

plt.show()

여러 개의 벡터에 대한 가중합 동시 계산

벡터 하나의 가중합은 𝑤𝑇𝑥wTx 또는 𝑥𝑇𝑤xTw 표시할 있다는 것을 배웠다. 그런데 만약 이렇게 𝑤w 가중치를 사용한 가중합을 하나의 벡터 𝑥x 아니라 여러 벡터 𝑥1,⋯,𝑥𝑀x1,⋯,xM 개에 대해서 모두 계산해야 한다면 어떻게 해야 할까? 예를 들어 위와 같이 선형 회귀 모형을 사용하여 여러 데이터 𝑥1,𝑥2,𝑥3,⋯,𝑥𝑁x1,x2,x3,⋯,xN 개의 데이터 모두에 대해 예측값 𝑦1,𝑦2,𝑦3,⋯,𝑦𝑁y1,y2,y3,⋯,yN 한꺼번에 계산하고 싶다면 다음처럼 데이터 행렬 𝑋X 사용하여 𝑦̂ =𝑋𝑤y^=Xw라는 수식으로 간단하게 표시할 있다.

𝑦̂ =⎡⎣⎢⎢⎢⎢𝑦̂ 1𝑦̂ 2⋮𝑦̂ 𝑀⎤⎦⎥⎥⎥⎥=⎡⎣⎢⎢⎢⎢𝑤1𝑥1,1+𝑤2𝑥1,2+⋯+𝑤𝑁𝑥1,𝑁𝑤1𝑥2,1+𝑤2𝑥2,2+⋯+𝑤𝑁𝑥2,𝑁⋮𝑤1𝑥𝑀,1+𝑤2𝑥𝑀,2+⋯+𝑤𝑁𝑥𝑀,𝑁⎤⎦⎥⎥⎥⎥=⎡⎣⎢⎢⎢⎢𝑥1,1𝑥2,1⋮𝑥𝑀,1𝑥1,2𝑥2,2⋮𝑥𝑀,2⋯⋯⋮⋯𝑥1,𝑁𝑥2,𝑁⋮𝑥𝑀,𝑁⎤⎦⎥⎥⎥⎥⎡⎣⎢⎢⎢⎢𝑤1𝑤2⋮𝑤𝑁⎤⎦⎥⎥⎥⎥=⎡⎣⎢⎢⎢⎢⎢𝑥𝑇1𝑥𝑇2⋮𝑥𝑇𝑀⎤⎦⎥⎥⎥⎥⎥⎡⎣⎢⎢⎢⎢𝑤1𝑤2⋮𝑤𝑁⎤⎦⎥⎥⎥⎥=𝑋𝑤(2.2.76)(2.2.76)y^=[y^1y^2⋮y^M]=[w1x1,1+w2x1,2+⋯+wNx1,Nw1x2,1+w2x2,2+⋯+wNx2,N⋮w1xM,1+w2xM,2+⋯+wNxM,N]=[x1,1x1,2⋯x1,Nx2,1x2,2⋯x2,N⋮⋮⋮⋮xM,1xM,2⋯xM,N][w1w2⋮wN]=[x1Tx2T⋮xMT][w1w2⋮wN]=Xw

.

𝑦̂ =𝑋𝑤(2.2.77)(2.2.77)y^=Xw

연습 문제 2.2.9
𝑥1x1, 𝑥2x2 다음과 같을 ,
𝑥1=⎡⎣⎢⎢𝑥11𝑥21𝑥31⎤⎦⎥⎥𝑥2=⎡⎣⎢⎢𝑥12𝑥22𝑥32⎤⎦⎥⎥(2.2.78)(2.2.78)x1=[x11x21x31]x2=[x12x22x32]
다음 등식이 성립함을 보인다.
𝑋𝑤=[𝑥𝑇1𝑥𝑇2]⎡⎣⎢⎢𝑤1𝑤2𝑤3⎤⎦⎥⎥=[𝑥𝑇1𝑤𝑥𝑇2𝑤](2.2.79)(2.2.79)Xw=[x1Tx2T][w1w2w3]=[x1Twx2Tw]

잔차

선형 회귀분석(linear regression) 결과는 가중치 벡터 𝑤w라는 형태로 나타나고 예측치는 가중치 벡터를 사용한 독립변수 데이터 레코드 , 벡터 𝑥𝑖xi 가중합 𝑤𝑇𝑥𝑖wTxi 된다고 했다. 예측치와 실젯값(target) 𝑦𝑖yi 차이를 오차(error) 혹은 잔차(residual) 𝑒𝑖ei라고 한다. 이러한 잔찻값을 모든 독립변수 벡터에 대해 구하면 잔차 벡터 𝑒e 된다.

𝑒𝑖=𝑦𝑖−𝑦̂ 𝑖=𝑦𝑖−𝑤𝑇𝑥𝑖(2.2.80)(2.2.80)ei=yi−y^i=yi−wTxi

잔차 벡터는 다음처럼 𝑦−𝑋𝑤y−Xw 간단하게 표기할 있다.

𝑒=⎡⎣⎢⎢⎢⎢𝑒1𝑒2⋮𝑒𝑀⎤⎦⎥⎥⎥⎥=⎡⎣⎢⎢⎢⎢𝑦1𝑦2⋮𝑦𝑀⎤⎦⎥⎥⎥⎥−⎡⎣⎢⎢⎢⎢⎢𝑥𝑇1𝑤𝑥𝑇2𝑤⋮𝑥𝑇𝑀𝑤⎤⎦⎥⎥⎥⎥⎥=𝑦−𝑋𝑤(2.2.81)(2.2.81)e=[e1e2⋮eM]=[y1y2⋮yM]−[x1Twx2Tw⋮xMTw]=y−Xw

𝑒=𝑦−𝑋𝑤(2.2.82)(2.2.82)e=y−Xw

잔차 제곱합

잔차의 크기는 잔차 벡터의 원소를 제곱한 더한 잔차 제곱합(RSS: Residual Sum of Squares) 이용하여 구한다. 값은 𝑒𝑇𝑒eTe 간단하게 있으며 값은 다음처럼 계산한다.

𝑖=1𝑁𝑒2𝑖=∑𝑖=1𝑁(𝑦𝑖−𝑤𝑇𝑥𝑖)2=𝑒𝑇𝑒=(𝑦−𝑋𝑤)𝑇(𝑦−𝑋𝑤)(2.2.83)(2.2.83)∑i=1Nei2=∑i=1N(yi−wTxi)2=eTe=(y−Xw)T(y−Xw)

연습 문제 2.2.10
분배 법칙을 사용하여 (𝑦−𝑋𝑤)𝑇(𝑦−𝑋𝑤)(y−Xw)T(y−Xw) 풀어쓰면 다음과 같아짐을 보여라.
(𝑦−𝑋𝑤)𝑇(𝑦−𝑋𝑤)=𝑦𝑇𝑦−𝑤𝑇𝑋𝑇𝑦−𝑦𝑇𝑋𝑤+𝑤𝑇𝑋𝑇𝑋𝑤(2.2.84)(2.2.84)(y−Xw)T(y−Xw)=yTy−wTXTy−yTXw+wTXTXw

이차형식

위의 연습 문제에서 마지막 항은 𝑤𝑇𝑋𝑇𝑋𝑤wTXTXw라는 형태다. 식에서 𝑋𝑇𝑋XTX 정방행렬이 되므로 정방행렬을 𝐴A라고 이름 붙이면 마지막 항은 𝑤𝑇𝐴𝑤wTAw 같은 형태가 된다.

벡터의 이차형식(Quadratic Form)이란 이처럼 어떤 벡터와 정방행렬이 '행벡터 x 정방행렬 x 열벡터' 형식으로 되어 있는 것을 말한다.

수식을 풀면 𝑖=1,…,𝑁,𝑗=1,…,𝑁i=1,…,N,j=1,…,N 대해 가능한 모든 𝑖,𝑗i,j 쌍의 조합을 구한 다음 𝑖i, 𝑗j 해당하는 원소 𝑥𝑖xi, 𝑥𝑗xj 가중치 𝑎𝑖,𝑗ai,j 같이 곱한 𝑎𝑖,𝑗𝑥𝑖𝑥𝑗ai,jxixj 총합이 된다.

𝑥𝑇𝐴𝑥=[𝑥1𝑥2⋯𝑥𝑁]⎡⎣⎢⎢⎢⎢𝑎1,1𝑎2,1⋮𝑎𝑁,1𝑎1,2𝑎2,2⋮𝑎𝑁,2⋯⋯⋱⋯𝑎1,𝑁𝑎2,𝑁⋮𝑎𝑁,𝑁⎤⎦⎥⎥⎥⎥⎡⎣⎢⎢⎢⎢𝑥1𝑥2⋮𝑥𝑁⎤⎦⎥⎥⎥⎥=∑𝑖=1𝑁𝑗=1𝑁𝑎𝑖,𝑗𝑥𝑖𝑥𝑗(2.2.85)(2.2.85)xTAx=[x1x2⋯xN][a1,1a1,2⋯a1,Na2,1a2,2⋯a2,N⋮⋮⋱⋮aN,1aN,2⋯aN,N][x1x2⋮xN]=∑i=1N∑j=1Nai,jxixj

연습 문제 2.2.11
다음 3차원 벡터와 행렬에 대해 이차형식을 쓰고 값을 계산하라.
𝑥=⎡⎣⎢⎢𝑥1𝑥2𝑥3⎤⎦⎥⎥(2.2.86)(2.2.86)x=[x1x2x3]
𝐴=⎡⎣⎢⎢𝑎11𝑎21𝑎31𝑎12𝑎22𝑎32𝑎13𝑎23𝑎33⎤⎦⎥⎥(2.2.87)(2.2.87)A=[a11a12a13a21a22a23a31a32a33]

예를 들어 𝑥=[1,2,3]𝑇x=[1,2,3]T 이고 A 다음과 같다면

𝐴=⎡⎣⎢⎢147258369⎤⎦⎥⎥(2.2.88)(2.2.88)A=[123456789]

넘파이 에서 벡터의 이차형식은 다음처럼 계산한다.

In [29]:

x = np.array([1, 2, 3])

x

array([1, 2, 3])

In [30]:

A = np.arange(1, 10).reshape(3, 3)

A

array([[1, 2, 3],

    [4, 5, 6],

    [7, 8, 9]])

In [31]:

x.T @ A @ x

228

연습 문제 2.2.12
다음 식이 성립함을 증명하라.
𝑥𝑇𝐴𝑥=12𝑥𝑇(𝐴+𝐴𝑇)𝑥(2.2.89)(2.2.89)xTAx=12xT(A+AT)x

부분행렬

다음과 같은 2차원 정방행렬 𝐴A, 𝐵B 있다.

𝐴=[𝑎11𝑎21𝑎12𝑎22],𝐵=[𝑏11𝑏21𝑏12𝑏22](2.2.90)(2.2.90)A=[a11a12a21a22],B=[b11b12b21b22]

이때 행렬의 𝐴𝐵AB 𝐴A, 𝐵B 부분행렬(submatrix) 이용하여 여러 방법으로 계산할 있다.

(1) 우선 앞에 곱해지는 행렬을 행벡터로 나누어 계산해도 된다.

𝐴=⎡⎣⎢⎢𝑎𝑇1𝑎𝑇2⎤⎦⎥⎥(2.2.91)(2.2.91)A=[a1Ta2T]

,

𝑎𝑇1=[𝑎11𝑎12],𝑎𝑇2=[𝑎21𝑎22](2.2.92)(2.2.92)a1T=[a11a12],a2T=[a21a22]

이면

𝐴𝐵=⎡⎣⎢⎢𝑎𝑇1𝑎𝑇2⎤⎦⎥⎥𝐵=⎡⎣⎢⎢𝑎𝑇1𝐵𝑎𝑇2𝐵⎤⎦⎥⎥(2.2.93)(2.2.93)AB=[a1Ta2T]B=[a1TBa2TB]

(2) 아니면 뒤에 곱해지는 행렬을 열벡터로 나누어 계산해도 된다.

𝐵=⎡⎣⎢⎢⎢𝑏1𝑏2⎤⎦⎥⎥⎥(2.2.94)(2.2.94)B=[(b1((b2(]

,

𝑏1=[𝑏11𝑏21],𝑏2=[𝑏21𝑏22](2.2.95)(2.2.95)b1=[b11b21],b2=[b21b22]

이면

𝐴𝐵=𝐴⎡⎣⎢⎢⎢𝑏1𝑏2⎤⎦⎥⎥⎥=⎡⎣⎢⎢⎢𝐴𝑏1𝐴𝑏2⎤⎦⎥⎥⎥(2.2.96)(2.2.96)AB=A[(b1((b2(]=[(Ab1((Ab2(]

(3) 앞에 곱해지는 행렬을 열벡터로, 뒤에 곱해지는 행렬을 행벡터로 나누어 스칼라처럼 계산해도 된다.

𝐴𝐵=[𝑎1𝑎2][𝑏𝑇1𝑏𝑇2]=𝑎1𝑏𝑇1+𝑎2𝑏𝑇2(2.2.97)(2.2.97)AB=[a1a2][b1Tb2T]=a1b1T+a2b2T

벡터의 크기를 직사각형으로 표시하면 다음과 같다.

𝐴𝐵=⎡⎣⎢⎢⎢𝑎1𝑎2⎤⎦⎥⎥⎥⎡⎣⎢⎢𝑏𝑇1𝑏𝑇2⎤⎦⎥⎥=𝑎1𝑏𝑇1+𝑏1𝑏𝑇2(2.2.98)(2.2.98)AB=[(a1((a2(][b1Tb2T]=(a1(b1T+(b1(b2T

여기에서는 2차원 행렬의 예를 들었지만 일반적인 𝑁N차원 행렬에서도 관계는 성립한다.

연습 문제 2.2.13
행렬 𝑉V 열벡터 𝑣𝑖(𝑖=1,…,𝑁)vi(i=1,…,N) 이루어진 정방행렬이다. 𝑉V 크기가 같은 다른 정방행렬 𝐴A, ΛΛ 있을 다음 식이 성립한다.
𝐴𝑉=𝐴[𝑣1⋯𝑣𝑁]=[𝐴𝑣1⋯𝐴𝑣𝑁](2.2.99)(2.2.99)AV=A[v1⋯vN]=[Av1⋯AvN]
𝑉Λ=[𝑣1⋯𝑣𝑁]⎡⎣⎢⎢⎢⎢𝜆10⋮00𝜆2⋮0⋯⋯⋱⋯00⋮𝜆𝑁⎤⎦⎥⎥⎥⎥=[𝜆1𝑣1⋯𝜆𝑁𝑣𝑁](2.2.100)(2.2.100)VΛ=[v1⋯vN][λ10⋯00λ2⋯0⋮⋮⋱⋮00⋯λN]=[λ1v1⋯λNvN]
𝑁=3N=3 경우에 식이 성립함을 보여라.
연습 문제 2.2.14
부분행렬 공식 (3)으로부터 𝐴A 행벡터 𝑎𝑇𝑖(𝑖=1,…,𝑁)aiT(i=1,…,N) 이루어진 𝑁N 정방행렬일
𝐴=⎡⎣⎢⎢⎢⎢⎢𝑎𝑇1𝑎𝑇2⋮𝑎𝑇𝑁⎤⎦⎥⎥⎥⎥⎥(2.2.101)(2.2.101)A=[a1Ta2T⋮aNT]
다음 관계가 성립한다.
𝐴𝑇𝐴=[𝑎1𝑎2⋯𝑎𝑁]⎡⎣⎢⎢⎢⎢⎢𝑎𝑇1𝑎𝑇2⋮𝑎𝑇𝑁⎤⎦⎥⎥⎥⎥⎥=∑𝑖=1𝑁𝑎𝑖𝑎𝑇𝑖(2.2.102)(2.2.102)ATA=[a1a2⋯aN][a1Ta2T⋮aNT]=∑i=1NaiaiT
𝑁=3N=3 경우에 식이 성립함을 보여라.

질문/덧글

dot연산된 2차원 배열 벡터 hamj*** 2017 3 24 9:42 오후 답변

안녕하세요. numpy 관련 문서를 찾다가 압도적인 튜토리얼을 발견했네요 ! 요새 딥러닝관련 문서들을 보는데, 문꽈 출신으로 첩첩산중이라 애로사항이 많슴다... 위에서 2차원 벡터의 dot 연산된 "결과값이 스칼라가 아닌 2차원 배열이라는 점에 유의한다."

array([[32]]) 이게 무슨 의미인지 이해하기가 힘듭니다. 얼마 전에 수학교과서에서는 "내적(inner product = dot product)연산은 결과값이 스칼라이므로 scalar product라고도 부른다"라고 봤거든요. 외적은 결과값도 벡터이므로 벡터곱이라고 부른다고 하구요. 수학적인 결과값은 스칼라이지만, 파이썬의 자료형으로 2차원 배열이라는 의미인지요 ?

답변: dot연산된 2차원 배열 벡터 관리자 2017 3 27 8:29 오후 답변

, 말씀하신대로 수학적인 결과값은 스칼라이지만, 파이썬의 자료형으로 2차원 배열이라는 의미입니다.

본문의 평균 부분 beom*** 2017 9 3 8:22 오후 답변

본문의 평균 부분에서 N = len(x) np.dot(np.ones(N), x) / N 아래에 나오는 결과값이 잘못 같습니다. x.mean() 결과값과 동일하게 4.5 수정되어야 같습니다.

답변: 본문의 평균 부분 관리자 2017 9 4 1:38 오후 답변

수정하였습니다. 지적 감사드립니다.

본문의 문장 '벡터로 표현된 N 개의 데이터의 단순 평균은 가중치값이 모두 1/N 가중 평균과 같다'에서 가중 평균이 가중 합으로 바뀌어하는게 아닌지요? beom*** 2017 9 8 4:25 오후 답변

답변: 본문의 문장 '벡터로 표현된 N 개의 데이터의 단순 평균은 가중치값이 모두 1/N 가중 평균과 같다'에서 가중 평균이 가중 합으로 바뀌어하는게 아닌지요? 관리자 2017 9 8 5:56 오후 답변

수정하였습니다. 지적 감사드립니다.

사용자에 의해 삭제되었습니다. eddy*** 2017 9 23 8:12 오후 답변

사용자에 의해 삭제되었습니다.

교열맨 roh.*** 2018 9 18 9:37 오전 답변

행렬과 행렬의 곱셈) 다음은 실제 행렬을 사용한 '곱셍' 예이다. -> 곱셈

벡터의 선형조합) 이미지를 섞어놓은 모핑(morhping) 효과 -> morphing 감사합니다!!

답변: 교열맨 관리자 2018 9 19 9:49 오전 답변

지적 감사드립니다. 수정하겠습니다.

사용자에 의해 삭제되었습니다. shul*** 2019 5 6 8:48 오후 답변

사용자에 의해 삭제되었습니다.

사용자에 의해 삭제되었습니다. shul*** 2019 5 6 9:13 오후 답변

사용자에 의해 삭제되었습니다.

의문 혹은 질문들 shul*** 2019 5 6 11:27 오후 답변

· 내적을 표현할 각괄호<> 사용하는데, 각괄호는 위치벡터를 표현할 때도 사용하는 걸로 압니다. 혹시 사이에 어떤 연관성이 있기에 같은 기호를 사용하는 걸까요?

· 절에서 Numpy에서는 1차원 배열의 전치 연산이 계산되지 않는다고 했는데, 내적은 행벡터와 열벡터를 가정해가면서까지 자동으로 구할 있게 해놨네요. 그렇게 만들어진 걸까요?

· 문서와 연습문제들로 , 행렬간의 곱셈에서는 교환법칙이 성립하지 않지만, 벡터와 행렬의 곱셈에서는 교환법칙이 성립한다고 이해했는데 맞을까요?

답변: 의문 혹은 질문들 관리자 2019 5 10 9:32 오전 답변

(1) 참고 자료나 링크를 제시해주시면 좋겠습니다. (2) 사용자 편의를 위한 것입니다. (3) 아닙니다. 벡터도 행렬이므로 교환법칙이 일반적으로 성립하지 않습니다.

연습문제 해설을 보다가 질문 드립니다. sgus*** 2020 3 18 2:03 오후 답변

연습문제 2.2.1에서 내적 곱을 , p.T @ n으로 끝나지 않고, p.T @ n [0][0] 들어가 있는 확인하였습니다. [0][0] 넣은 것은 2차원 배열을 1차원 배열로 변형하기 위해서인가요?

답변: 연습문제 해설을 보다가 질문 드립니다. 관리자 2020 3 25 7:12 오후 답변

2차원 배열에서 스칼라를 뽑기 위해서입니다.

 


파이썬을 메인 BE로 지정하기 어려운 점이다... 파이썬은 BE language로 쓰긴 하지만 메인은 역시 자바...

In Python, member variables (attributes) are not inherently private like they might be in languages such as Java. In Python, all member variables are public by default, meaning they can be directly accessed from outside the class. However, the Python community follows naming conventions to indicate the intended access level for variables:

  • Public Members: Variables or methods declared normally are accessible from anywhere. For example, a member variable self.name is accessible from outside the class and is considered public.
  • Protected Members: Variables or methods that start with a single underscore (_) are considered protected. This convention suggests that these members are intended for use only within the class and its subclasses, and access from outside should be avoided. Example: self._name
  • Private Members: Variables or methods that start with a double underscore (__) are considered private and are intended to be used only within the class. Python performs name mangling on these members to make direct access from outside more difficult. For example, to access self.__name, you'd have to use _ClassName__name from outside the class.

Python uses these conventions to indicate the access control of member variables, but these are not enforced by the language itself. It aligns with the Python philosophy "We are all consenting adults here", implying that developers are expected to follow these conventions and not the language enforcing strict access control.

 

 

=== 사족 === 

www.a-ha.io/questions/45be375c892279c99e0f98338d25ade7

 

트론 블록체인의 단점이 있나요? | 전문 지식 검색은 아하!

블록체인 기술, 장점, 트론, 단점, 특징 - 이오스와 이더리움 설명이 많이 되어 있는데 트론 블록체인은 많이 알려져 있지 않는거 같네요.... 트론 블록체인의 장점이나 단점, 아니면 특징에 대해

www.a-ha.io

트론은 POW나 POS외에 위임된 지분증명을 통해 모든 노드 자격을 가진 주주들이

블록생성에 참여 하면서 상위노드에게 권한을 위임하는 DPOS를 사용하고 있습니다.

트랜잭션 처리가 빠르고 비용이 낮은 장점을 보유하고 있습니다.

하지만 단점도 있습니다.

  1. 엄청난 발행량
  2. 낮은가격대와 가격의 변동성이 큼
  3. 소수의 독점현상
  4. 트론은 매일 50만건정도의 트랜잭션 처리밖에 하지못합니다.
  5. 이더리움은 이의 1000배를 처리합니다. 범위가 다릅니다.
  6. 실질적인 댑의 이용수가 적다
  7. 프로젝트 개발보다는 마케팅에만 치우친다
  8. 트론은 스마트컨트랙트보다는 엔터에만 치중된 코인입니다.

-=-0=0=-0=-0=-0=-0=-0=-0=0=-0-

아하 지식 플랫폼이 너무 잘 되어 있어서 이 정도 회사라면 투자해도 좋다고 생각해서 이쪽으로 다 옮겨왔는데 트론은 계속 오르고 있다. 슬프다. 아무리 생각해도 150원, BTT 는 15원이 한계일 것 같은데...

왜냐면 BTT는 실제 비트토렌토에서 이용이 가능한데. 이 가격이 2배로 뛰면 비트토렌토에서 빠르게 이용하려는 이용자의 부담도 2배가 되므로 외면 받을 것이기 때문이다. 엄청나게 뛰어난 기술이 아닌 다음에야 실 가치 부여가 되지 않는 코인/토큰은 사라질 것이라고 생각된다.

'{BE} Python 3.1x' 카테고리의 다른 글

how to see the encoding  (0) 2021.05.26
AI 기본은 필수...  (0) 2021.05.20
VoyagerX 창업자_개발 능력 요구사항  (0) 2020.12.29
PEP8 code layout  (0) 2020.12.05
0 matrix  (0) 2020.12.01

Sedong Nam

12월 23일 오후 11:02 

딥러닝 3년차 이상 기술 면접할 때 묻는 질문들 중 (보이저엑스 딥러닝 모델러 기준) 당락을 가르는데 가장 유용했다 싶은 열가지를 공개한다.

1. Python에서 Generator가 무엇이고 어떻게 만드나요?

2. Activation Function 없이 뉴럴넷을 학습하면 왜 안될까요?

3. Max Pool Layer의 Back-Propagation은 어떻게 되나요?

4. 멀티 GPU에서의 SGD는 어떻게 되는 걸까요?

5. Word2Vec 학습결과 King-Queen 같은 것이 되는 이유가 뭘까요?

6. Transformer에서 K, Q, V 각각은 어떻게 만들어지나요?

7. GPT-3에서 Few-Shot Learning의 의미는 무엇인가요?

8. Mnist에 대한 VAE와 AE의 Latent Space는 어떻게 다른가요?

9. 현재 사용중인 GPU가 무엇이고 그 메모리는 어느 정도인가요?

10. 만들었던 그 모델의 파라메터수가 대략 어떻게 되나요?

3년차 이상이라면 최소한 절반 이상은 잘 대답하길 기대한다.

 

페북을 그대로 긁어 온 이유는 다른 글도 정말 읽을 만한 글이 많다. 보통 대표면 솔직한 이야기를 잘 안하는데 이 회사는 다른 스타트업과 다르게 대표가 솔직한 이야기를 정말 많이 한다.

 

-=-=00-=0=-0-=0=-0

 

국내 기업에서 관심두고 있는 AI 기업은 2개인데 VUNO와  VoyagerX 이다. 뷰노의 경우 링크드인을 통해 소식을 보고 보이저 엑스의 경우 facebook 으로 소식을 본다. 둘 다 상용화 솔루션을 만들었기에 관심을 두고 딥러닝에 vision 에 포커싱 되어 있는 것을 보고 잘 안 될리는 없다고 생각해서 관심을 두고 있다. 그리고 내가 있는 IT필드에서도 python의 generator가 가장 중요한데 첫 질문만 보고 공유를 했다. 나머지는 필요한 질문인지 잘 모르겠다. 공부하기 좋은 키워드임에는 분명하지만, 난 제품으로만 평가한다. 지금 낸 제품은 결국 기존에 만들었었던 카메라 프로그램의 연장이며, scanner pro 앱에 비해 빠르긴 하지만, 영수증 제출하는데도 계속 수동으로 끝을 잘라내는 작업을 해 줘야 하니 말이다. 물론, 업데이트는 계속 될 것이고 뷰노던 보이저엑스던 글로벌 원탑이 될만한 루트는 보인다. 글로벌 원탑이 되려면 구글, IBM, facebook, 마이크소프트 등을 다 이겨야 하는데 그럴 가능성이 보이는 아이템 선정이라는 것이다. 사실 가장 중요한 것은 나중에 우리 자국 기업을 해외에 갖다 바치느냐 아니냐 차이다. 안철수가 그렇게 싫지만 그래도 다른 사람과 차별점은 확실한 것은 그러지 않았다는 것. 물론, 안철수던 저커버그던 자기 요트에서 평생 놀고 먹을 수 있지만 그것은 본인들이 원하는 길이 아니었기 때문에 동시대의 사람들과 끊임없이 고민하고 사는 것이다.

 난 살아 있는 사람은 평가하기도 막 따르기도 힘들다. 끝에 이르렀을 때 마지막 선택들에 그 의미를 부여한다. 역사에 남을 것인지 아닌지는 본인들의 선택이겠다.

'{BE} Python 3.1x' 카테고리의 다른 글

AI 기본은 필수...  (0) 2021.05.20
python에서 아쉬운 점 private, protected, public...  (0) 2021.04.06
PEP8 code layout  (0) 2020.12.05
0 matrix  (0) 2020.12.01
for, zip, range  (0) 2020.11.30

 

www.python.org/dev/peps/pep-0008/

 

PEP 8 -- Style Guide for Python Code

The official home of the Python Programming Language

www.python.org


pip3 install flake8 --user
flake8 a.py
a.py:1:2: E225 missing whitespace around operator
a.py:3:1: W191 indentation contains tabs
a.py:4:1: W391 blank line at end of file

.vimrc
set smartindent
set tabstop=4
set expandtab
set shiftwidth=4
set textwidth=79

'{BE} Python 3.1x' 카테고리의 다른 글

python에서 아쉬운 점 private, protected, public...  (0) 2021.04.06
VoyagerX 창업자_개발 능력 요구사항  (0) 2020.12.29
0 matrix  (0) 2020.12.01
for, zip, range  (0) 2020.11.30
Finally... Android also.  (0) 2020.11.04

>>> n = 4

>>> print([[0 for i in range(n)] for j in range(n)])

[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]

'{BE} Python 3.1x' 카테고리의 다른 글

VoyagerX 창업자_개발 능력 요구사항  (0) 2020.12.29
PEP8 code layout  (0) 2020.12.05
for, zip, range  (0) 2020.11.30
Finally... Android also.  (0) 2020.11.04
일단, python 의 승리  (2) 2020.10.03

>>> for (i, j) in zip(range(1, 10, 1), range(10, 1, -1)):

...     print(i, ' ', j)

... 

1   10

2   9

3   8

4   7

5   6

6   5

7   4

8   3

9   2

'{BE} Python 3.1x' 카테고리의 다른 글

PEP8 code layout  (0) 2020.12.05
0 matrix  (0) 2020.12.01
Finally... Android also.  (0) 2020.11.04
일단, python 의 승리  (2) 2020.10.03
xlsx control. python 1 : swift 0  (0) 2020.09.12


Setup Type: Standard
SDK Folder: C:\Users\hajun\AppData\Local\Android\Sdk
JDK Location: C:\Android\Android Studio\jre (Note: Gradle may be using JAVA_HOME when invoked from command line. More info...)
Total Download Size: 1.68 GB
SDK Components to Download: 

Android Emulator
  
240 MB

Android Emulator Hypervisor Driver for AMD Processors (installer)
  
161 KB

Android SDK Build-Tools 30.0.2
  
51.3 MB

Android SDK Platform 30
  
49.9 MB

Android SDK Platform-Tools
  
8.03 MB

Android SDK Tools
  
149 MB

Google APIs Intel x86 Atom System Image
  
1.15 GB

SDK Patch Applier v4
  
1.74 MB

Sources for Android 30
  
41.3 MB

'{BE} Python 3.1x' 카테고리의 다른 글

0 matrix  (0) 2020.12.01
for, zip, range  (0) 2020.11.30
일단, python 의 승리  (2) 2020.10.03
xlsx control. python 1 : swift 0  (0) 2020.09.12
Swift VS Python 으로 카테고리 변경  (0) 2020.09.02

시대의 흐름이 국가의 전략을 좌우하고 국가의 기획이 IT 의 흐름을 좌우 한다. 코로나로 비대면, 원격 근무가 유행한다.

www.dt.co.kr/contents.html?article_no=2020052002109919607013

 

구글 CEO "지독한 코로나… 직원 60% 일주일에 한번꼴 출근"

˝연말까지 직원의 60%가 일주일에 한 번꼴로 사무실에 나오게 될 것입니다.˝신종..

www.dt.co.kr

biz.chosun.com/site/data/html_dir/2020/05/20/2020052000415.html

 

구글 CEO "연말까지도 대다수 직원 재택근무 할 것"

순다르 피차이 구글 최고경영자(CEO)가 "올해 연말까지 직원의 약 60%가 일주일에 한 번꼴로 사무실에 나오게 될 것"이라고 말했다고 미국 경..

biz.chosun.com

www.hankyung.com/economy/article/2020052056287

 

구글CEO "연말 직원 대다수 재택, 60%만 일주일 한번 사무실로"

구글CEO "연말 직원 대다수 재택, 60%만 일주일 한번 사무실로", 채선희 기자, 경제

www.hankyung.com

라고 하지만 원격 근무를 해 보면 알게 된다.

www.bbc.com/korean/international-54067470

 

넷플릭스 회장 '재택근무, 부정적 영향 준다' - BBC News 코리아

'그 어떤 긍정적인 것도 보이지 않는다.'

www.bbc.com

www.welfareissue.com/news/articleView.html?idxno=6164

 

재택근무, 신뢰가 기본...시공간 주체돼야 - 웰페어이슈(welfareissue)

최근 사회적 거리두기 2단계, 특히 수도권에 2.5단계가 시행되면서 재택근무에 대한 관심이 높아졌다. 이는 네이버의 검색어 트랜드에서 ‘재택근무’를 검색해보면 확인할 수 있다.필자는 지난

www.welfareissue.com

news.g-enews.com/view.php?ud=2020092813263827509a1f309431_1&ssk=pcmain_0_1&md=20200928134548_R

 

[글로벌-Biz 24] 피차이 구글 CEO "미래의 직장은 하이브리드 방식"

미래의 직장은 하이브리드 방식이 될 것이며 구글은 이에 대비해 근무 환경에 대한 전면적인 조정작업을 진행하고 있다고 순다 피차이 구글 최고경영자(CEO)가 밝혔다. 27일(이하 현지시간) 비즈�

news.g-enews.com

www.forbes.com/sites/jackkelly/2020/09/28/google-ceo-sundar-pichai-calls-for-a-hybrid-work-from-home-model/#5e695fc0e9cf

 

Google CEO Sundar Pichai Calls For A 'Hybrid' Work-From-Home Model

Google will be more “flexible” with its workers and offer a “hybrid” model that will include a blend of both remote and in-office methods of working. Pichai acknowledged that his employees have distinct needs, as it relates to their work style and

www.forbes.com

재택, 원격 근무 경험으로 내 생각을 말하면 원격 근무는 필요하지만 충분한 유대감이 형성된 이후에 하는 것이 좋다. 충분한 유대감이 형성될 수 없는 사람들이라면 일에 대한 명확한 달성 목표를 주고 파트 타임 일을 주는게 맞다.

잠깐 이야기가 빠진 것 같지만 시대의 흐름에 따라 무엇이 중요한 기술이 된 것인지 공감대는 맞는 것 같다.

Swift의 서버 모델인 perfect는 확실히 망했다. Swift는 사실상 아이폰을 위한 프로그래밍 언어라고 보는 것이 맞다.

python 으로 안드로이드나 아이폰 프로그래밍을 할 수는 있으나 google play나 앱스토어에 올릴 앱을 만들 수는 없다. 코르도바와 그 아류작들과 같이 뭘 덧 씌울 수는 있겠으나 너무 구차해서 안된다고 하는 편이 맞다. 

iOS 개발자고 그게 주 수입원이고 swift가 이겼으면 하지만, 한국에서 프로그래밍 언어 경쟁에서는 python 이 이겼다고 보는 것이 맞겠다. 왜냐면 swift는 자격증도 없다 ㅡㅡ; 자격증이 중요한 것은 아니지만 자격증이 없다...

파이썬마스터_2급_샘플문제_및_문제풀이_방법.pdf
0.17MB

python 시험은 cos pro랑 python master 가 있다. 물론, 알고리즘 시험에 swift가 들어 간 경우는 있다. 그 외 여러 채널을 통한 정보를 종합해 보면 젊은 세대는 python을 하고 데이터를 다루는 모든 분야의 사람들과 서버 프로그래머는 python을 하는 것 같다. 프로그래밍 도구에 대한 기류가 완전히 시장에 녹아 들려면 대략 5년 정도의 시간이 걸렸던 것 같은데 이제 python은 java 때와 마찬가지로 그 분야에 종사 하지 않더라도 꼭 한 번은 해야만 하는 프로그램밍 언어로 자리를 잡은 것 같다.

아니라고 부정하며 자기 자리 지켜도 되지만 주변을 둘러보면, 그런 경우 10년은 버티기가 힘든 것 같다. 10년이면 정말 긴 시간이라 괜찮긴 하지만... IT 흐름에 맞춰서 살다보면 자연스레, 아... 이건 꼭 해야 하는구나... 라는 것이 생기기 나름이다.

www.youtube.com/watch?v=RhuYDAEdGHE

Swift 5.3 영상을 보고 정리하며... 아... 하는 생각이 들었다.

Android 경력이 화려한데 iOS를 넘어가며 경력을 버려도 결국 둘 다 할 줄 안다는 것 때문에 550하는 프리랜싱 단가가 800대가 되었다. 뽑는 쪽에서도 기다림이 가능하다면, 300 절약하며 일관된 아키텍쳐를 만날 수 있으니 요즘 추세다. 그런데 대용량 서비스의 경우 웹으로 돌아가다 보니 결국 웹이 완전히 배제되기는 힘들어서 웹도 해야 하는 상황... pyCharm, WebStorm, PphStorm 을 써 가며 개발해 보지만 점점 재미가 없어진다.

어린 시절에는 영어, 한국어, 일어, 중국어 든 여러 언어를 하는게 대단해 보이지만, 나이가 들어 보면 한국어 하나만 한 사람이 시를 쓸 때 그것이 그렇게 부러워 보일 수가 없다.

자전거를 타던 사람이 오토바이를 배우면 쉽게 배울 수 있듯... 그 철학만 제대로 이해하면 파이썬을 제대로 해 볼 수 있지 않을까? 하는 생각이 든다. 나 같은 경우 C 온라인 강의 요청도 있으니 python의 core쪽도 함께 공부할 수 있으니 더 좋은 조건이겠다.

방향은 어느 정도 잡혔으니 얼마나 열정적으로 길을 닦아 보느냐가 관건이겠다.

이 글을 쓴 이유는 이제 비교 글 보다 python 관련 자료를 더 많이 올리겠다는 말을 애둘러서 한 것이겠다.

'{BE} Python 3.1x' 카테고리의 다른 글

for, zip, range  (0) 2020.11.30
Finally... Android also.  (0) 2020.11.04
xlsx control. python 1 : swift 0  (0) 2020.09.12
Swift VS Python 으로 카테고리 변경  (0) 2020.09.02
python basic problems  (0) 2020.08.11

github.com/CoreOffice/CoreXLSX

 

CoreOffice/CoreXLSX

Excel spreadsheet (XLSX) format parser written in pure Swift - CoreOffice/CoreXLSX

github.com

swift는 4.2 부터... 일단 import 되면 

let sharedStrings = try file.parseSharedStrings() let columnCStrings = worksheet.cells(atColumns: [ColumnReference("C")!]) .compactMap { $0.stringValue(sharedStrings) }

문제는 내부 자료형으로 딱히 excel 을 다룰 일이 없다. 아무리 지식 공유 목적이라지만 자료 처리를 위한 언어와 비교를 하는 것 자체가 사실 공평하지 못하니, 데탑에서는 swift를 쓰지 않으니... swift 1점 주기 위해 파이써니스타와 스위프트 중 스위프트가 우세한 한 가지를 향 후 적어야 겠다. python 의 경우 pandas는 기본 라이브러리고 excel을 다루는 것은 코어 기능이라 매우 강력하다.

------------------------------

import pandas as pd

data_path = './data/corona_data.xlsx'

corona_data = pd.read_excel(data_path)

confirmed = corona_data['확진자']

print(confirmed)

19 1 23 2 24 3 24 4 27 5 27 6 28 7 28 8 28 9 28 10 28 11 29 12 30 13 31 14 51 15 104 16 204 17 433 18 602 19 833 20 977 21 1261 22 1766 23 2337 24 3150 25 3736 26 4212 27 4812 28 5328 29 5766 ... 152 12904 153 12967 154 13030 155 13091 156 13137 157 13181 158 13244 159 13293 160 13338 161 13373 162 13417 163 13479 164 13512 165 13551 166 13612 167 13672 168 13711 169 13745 170 13771 171 13816 172 13879 173 13938 174 13979 175 14092 176 14150 177 14175 178 14203 179 14251 180 14269 181 14305 Name: 확진자, Length: 182, dtype: int64

------------------------------------------------------

data_path = './data/corona_data.xlsx' 

corona_data = pd.read_excel(data_path)

confirmed = corona_data['확진자'].values

[ 19 23 24 24 27 27 28 28 28 28 28 29 30 31 51 104 204 433 602 833 977 1261 1766 2337 3150 3736 4212 4812 5328 5766 6284 6767 7134 7382 7513 7755 7869 7979 8086 8162 8236 8320 8413 8565 8652 8799 8897 8961 9037 9037 9137 9241 9332 9478 9583 9661 9786 9887 9976 9976 10062 10156 10237 10284 10331 10384 10423 10450 10480 10512 10537 10564 10591 10613 10635 10653 10661 10674 10683 10694 10702 10708 12801 10718 10718 10728 10738 10752 10761 10765 10774 10780 10793 10801 10804 10806 10810 10822 10840 10874 10909 10936 10962 10991 11018 11037 11050 11065 11078 11110 11122 11142 11165 11190 11206 11225 11265 11344 11402 11441 11468 11503 11541 11590 11629 11668 11719 11776 11814 11852 11902 11947 12003 12051 12085 12121 12155 12198 12257 12306 12373 12421 12438 12484 12535 12563 12602 12653 12715 12757 12800 12850 12904 12967 13030 13091 13137 13181 13244 13293 13338 13373 13417 13479 13512 13551 13612 13672 13711 13745 13771 13816 13879 13938 13979 14092 14150 14175 14203 14251 14269 14305]

코드 실행이 완료되었습니다.
------------------------------------------------------

data_path = './data/corona_data.xlsx' 

corona_data = pd.read_excel(data_path)

confirmed = corona_data['확진자'].values.tolist()

[19, 23, 24, 24, 27, 27, 28, 28, 28, 28, 28, 29, 30, 31, 51, 104, 204, 433, 602, 833, 977, 1261, 1766, 2337, 3150, 3736, 4212, 4812, 5328, 5766, 6284, 6767, 7134, 7382, 7513, 7755, 7869, 7979, 8086, 8162, 8236, 8320, 8413, 8565, 8652, 8799, 8897, 8961, 9037, 9037, 9137, 9241, 9332, 9478, 9583, 9661, 9786, 9887, 9976, 9976, 10062, 10156, 10237, 10284, 10331, 10384, 10423, 10450, 10480, 10512, 10537, 10564, 10591, 10613, 10635, 10653, 10661, 10674, 10683, 10694, 10702, 10708, 12801, 10718, 10718, 10728, 10738, 10752, 10761, 10765, 10774, 10780, 10793, 10801, 10804, 10806, 10810, 10822, 10840, 10874, 10909, 10936, 10962, 10991, 11018, 11037, 11050, 11065, 11078, 11110, 11122, 11142, 11165, 11190, 11206, 11225, 11265, 11344, 11402, 11441, 11468, 11503, 11541, 11590, 11629, 11668, 11719, 11776, 11814, 11852, 11902, 11947, 12003, 12051, 12085, 12121, 12155, 12198, 12257, 12306, 12373, 12421, 12438, 12484, 12535, 12563, 12602, 12653, 12715, 12757, 12800, 12850, 12904, 12967, 13030, 13091, 13137, 13181, 13244, 13293, 13338, 13373, 13417, 13479, 13512, 13551, 13612, 13672, 13711, 13745, 13771, 13816, 13879, 13938, 13979, 14092, 14150, 14175, 14203, 14251, 14269, 14305]

코드 실행이 완료되었습니다.

------------------------------------------------------

corona_data = pd.read_excel(data_path, usecols="D")

confirmed = corona_data.values.tolist()

[[19], [23], [24], [24], [27], [27], [28], [28], [28], [28], [28], [29], [30], [31], [51], [104], [204], [433], [602], [833], [977], [1261], [1766], [2337], [3150], [3736], [4212], [4812], [5328], [5766], [6284], [6767], [7134], [7382], [7513], [7755], [7869], [7979], [8086], [8162], [8236], [8320], [8413], [8565], [8652], [8799], [8897], [8961], [9037], [9037], [9137], [9241], [9332], [9478], [9583], [9661], [9786], [9887], [9976], [9976], [10062], [10156], [10237], [10284], [10331], [10384], [10423], [10450], [10480], [10512], [10537], [10564], [10591], [10613], [10635], [10653], [10661], [10674], [10683], [10694], [10702], [10708], [12801], [10718], [10718], [10728], [10738], [10752], [10761], [10765], [10774], [10780], [10793], [10801], [10804], [10806], [10810], [10822], [10840], [10874], [10909], [10936], [10962], [10991], [11018], [11037], [11050], [11065], [11078], [11110], [11122], [11142], [11165], [11190], [11206], [11225], [11265], [11344], [11402], [11441], [11468], [11503], [11541], [11590], [11629], [11668], [11719], [11776], [11814], [11852], [11902], [11947], [12003], [12051], [12085], [12121], [12155], [12198], [12257], [12306], [12373], [12421], [12438], [12484], [12535], [12563], [12602], [12653], [12715], [12757], [12800], [12850], [12904], [12967], [13030], [13091], [13137], [13181], [13244], [13293], [13338], [13373], [13417], [13479], [13512], [13551], [13612], [13672], [13711], [13745], [13771], [13816], [13879], [13938], [13979], [14092], [14150], [14175], [14203], [14251], [14269], [14305]]

-------------------------------------------------

import pandas as pd

import datetime as dt

data_path = './data/corona_data.xlsx'

corona_data = pd.read_excel(data_path)

death_0730 = corona_data.loc[corona_data['날짜'] == dt.datetime(2020,7,30), '사망자']

print(death_0730)

-=-=-=-=-=-=-=-=-=--=-=-=-=0=-0=-0=-0-=0=-0-=0-=0-=0-=0-=0

confirmed_10000 = corona_data.loc[corona_data['확진자'] >= 10000]

print(confirmed_10000)

'{BE} Python 3.1x' 카테고리의 다른 글

Finally... Android also.  (0) 2020.11.04
일단, python 의 승리  (2) 2020.10.03
Swift VS Python 으로 카테고리 변경  (0) 2020.09.02
python basic problems  (0) 2020.08.11
텍스트를 이미지로 그려서 붙이기  (0) 2020.07.01

1.

카테고리를 변경했다. 앞으로의 내용도 비교 위주로 적을 예정이다. 단일 내용이야 다른 블로그에도 많으니 특색이 없어 바꿨다.

Xcode & PyCharm 카테고리 삭제하며 해당 카테고리의 게시글도 모두 옮겼다.

2.

코드는 github 외 공유 하는 것이 아닌 것 같다는 생각이 어제 들어서 오늘 바꾸게 되었다. 블로그에는 고찰 같은 것을 적는게 맞아 보인다.

유닉스 창시자가 creat 로 만들고 후회했다고 했다. 줄여서... create 가 맞기 때문에 수 십년 뒤에 가장 바꾸고 싶다는 인터뷰를 봤었다. func, def 도 같은 문제점이 있는 것 같다.  function 이던 method 던 명시하는 것은 좋은데 func던, def 던 둘 다 틀렸다고 보인다. 이미 C처럼 없애던지, JAVA 처럼 접근 제한자 자리를 두던지. 아니면 말을 줄이지 말던지. -1 : -1

{}냐 :와 indent 냐 하는 것은 python 의 :로 승리로 보는 사람이 있다. 어차피 코드 정리를 해야 하기 때문이다. 그러나 auto format 기능을 쓸 때 자동 정렬되고 회사마다 다른 formatting rule 이 있는데 그 룰을 리팩토링 툴에 적용하는 것을 볼 때 {}가 차라리 유용하다는 생각도 들 하다. Xcode에서 {의 경우 더블클릭 하면 어디까지가 block 인지 알 수 있다. 그리고 go to matches로 블럭 끝으로 이동 가능하다. PyCharm에서는 더블 클릭도 없고 matches도 없으나 expend/collapse 기능이다. Folding 메뉴가 있으므로 폴딩하며 볼 수 있는데 이 방법 밖에 없어서 오히려 기능을 매우 자주 쓰게 된다. 단일 책임의 원칙을 적용하던 뭐던, 프로그램 내용이 깊어지면 점점 복잡해지니... pythonic 하게 짠다면 그렇게 긴 코드가 필요 없다고 볼 때 python 이 나아 보일 수도 있다. assembly 도 자주 접할 수 밖에 없었던 나는 python style이 낫다. -1 : 0 

for 문에서는 아무래도 swift가 더 직관적이다.  for x in 0..<y 일 때 for x in range(0, y) 인데 <= 인지, < 인지 swift는 명확하게 명시하고 있기 때문이다. range(4) 경우 0, 1, 2, 3으로 해당 숫자가 포함되지 않는데 ..< 가 더 직관적이다. 0:0

뭐, 이런 것들을 적으려고 한다. 생각날 때마다. 

 

 

'{BE} Python 3.1x' 카테고리의 다른 글

일단, python 의 승리  (2) 2020.10.03
xlsx control. python 1 : swift 0  (0) 2020.09.12
python basic problems  (0) 2020.08.11
텍스트를 이미지로 그려서 붙이기  (0) 2020.07.01
plist 읽기  (0) 2020.07.01

출처 : YBM

 

#문제1
A 학교에서는 단체 티셔츠를 주문하기 위해 학생별로 원하는 티셔츠 사이즈를 조사했습니다. 선택할 수 있는 티셔츠 사이즈는 작은 순서대로 "XS", "S", "M", "L", "XL", "XXL" 총 6종류가 있습니다.

학생별로 원하는 티셔츠 사이즈를 조사한 결과가 들어있는 리스트 shirt_size가 매개변수로 주어질 때, 사이즈별로 티셔츠가 몇 벌씩 필요한지 가장 작은 사이즈부터 순서대로 리스트에 담아 return 하도록 solution 함수를 완성해주세요.

---
##### 매개변수 설명
학생별로 원하는 사이즈를 조사한 결과가 들어있는 리스트 shirt_size가 solution 함수의 매개변수로 주어집니다.
* shirt_size 의 길이는 1 이상 100 이하입니다.
* shirt_size 에는 치수를 나타내는 문자열 "XS", "S", "M",  `"L", "XL", "XXL" 이 들어있습니다.

---
##### return 값 설명
티셔츠가 사이즈별로 몇 벌씩 필요한지 가장 작은 사이즈부터 순서대로 리스트에 담아 return 해주세요.
* return 하는 리스트에는 [ "XS" 개수, "S" 개수, "M" 개수, "L" 개수, "XL" 개수, "XXL" 개수] 순서로 들어있어야 합니다.

---
##### 예시

| shirt_size                       | return        |
|----------------------------------|---------------|
| ["XS", "S", "L", "L", "XL", "S"] | [1, 2, 0, 2, 1, 0] |

##### 예시 설명
* "XS"와 "XL"은 각각 한 명씩 신청했습니다.
* "S"와 "L"은 각각 두 명씩 신청했습니다.
* "M"과 "XXL"을 신청한 학생은 없습니다.

따라서 순서대로 [1, 2, 0, 2, 1, 0]을 리스트에 담아 return 하면 됩니다.


#문제2
A 쇼핑몰에서는 회원 등급에 따라 할인 서비스를 제공합니다.
회원 등급에 따른 할인율은 다음과 같습니다.
(S = 실버, G = 골드, V = VIP)

| 등급     | 할인율 |
|----------|--------|
| "S" | 5%     |
| "G"   | 10%    |
| "V"    | 15%    |

상품의 가격 price와 구매자의 회원 등급을 나타내는 문자열 grade가 매개변수로 주어질 때, 할인 서비스를 적용한 가격을 return 하도록 solution 함수를 완성해주세요.

---

#####매개변수 설명
상품의 가격 price와 회원 등급 grade가 매개변수로 주어집니다.
* price는 100 이상 100,000 이하의 100단위 자연수입니다.
* grade는 "S", "G", "V" 세 가지 중 하나입니다.

---

#####return 값 설명
할인한 가격을 return 하도록 solution 함수를 작성해주세요.

---

#####예시

| price | grade    | return |
|-------|----------|--------|
| 2500  | "V"    | 2125   |
| 96900 | "S" | 92055  |

##### 예시 설명
예시 #1
2500원의 15%는 375원 입니다. 2500 - 375 = 2125 입니다.

예시 #2
96900원의 5%는 4845원 입니다. 96900 - 4845 = 92055 입니다.


#문제3
시작 날짜와 끝 날짜가 주어질 때, 두 날짜가 며칠만큼 떨어져 있는지(D-day)를 구하려 합니다. 이를 위해 다음과 같이 3단계로 간단히 프로그램 구조를 작성했습니다. (단, 윤년은 고려하지 않습니다.)

~~~
1단계. 시작 날짜가 1월 1일로부터 며칠만큼 떨어져 있는지 구합니다.
2단계. 끝 날짜가 1월 1일로부터 며칠만큼 떨어져 있는지 구합니다.
3단계. (2단계에서 구한 날짜) - (1단계에서 구한 날짜)를 구합니다.
~~~

시작 날짜의 월, 일을 나타내는 start_month, start_day, 끝 날짜의 월, 일을 나타내는 end_month, end_day가 매개변수로 주어질 때, 시작 날짜와 끝 날짜가 며칠만큼 떨어져 있는지 return 하도록 solution 함수를 작성했습니다. 이때, 위 구조를 참고하여 중복되는 부분은 func_a라는 함수로 작성했습니다. 코드가 올바르게 동작할 수 있도록 빈칸을 알맞게 채워주세요.

---
##### 매개변수 설명
시작 날짜의 월, 일을 나타내는 start_month, start_day, 끝 날짜의 월, 일을 나타내는 end_month, end_day가 solution 함수의 매개변수로 주어집니다.

* 잘못된 날짜가 주어지는 경우는 없습니다.
* 끝 날짜는 항상 시작 날짜보다 뒤에 있는 날이 주어집니다.
* 끝 날짜가 다음 해로 넘어가는 경우는 주어지지 않습니다.
  * 즉, start_month <= end_month를 항상 만족합니다.
  * start_month = end_month라면 start_day <= end_day를 항상 만족합니다.
* 각 달의 날짜 수는 1월부터 순서대로 [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] 이며, 윤년은 고려하지 않습니다.

---
##### return 값 설명
시작 날짜와 끝 날짜가 며칠만큼 떨어져 있는지 return 해주세요.

---
##### 예시

| start_month | start_day | end_month | end_day | return |
|-------------|-----------|-----------|---------|--------|
| 1           | 2         | 2         | 2       | 31     |

##### 예시 설명
시작 날짜는 1월 2일이고, 끝 날짜는 2월 2일입니다.

* 1월 2일은 1월 1일로부터 1일만큼 지난 날입니다.
* 2월 2일은 1월 1일로부터 32일만큼 지난 날입니다.
* 32 - 1 = 31입니다.
* 따라서 1월 2일과 2월 2일은 31일만큼 떨어져 있습니다.



#문제4
자연수가 들어있는 리스트가 있습니다. 이 리스트에서 가장 많이 등장하는 숫자의 개수는 가장 적게 등장하는 숫자 개수의 몇 배인지 구하려 합니다. 이를 위해 다음과 같이 간단히 프로그램 구조를 작성했습니다.

~~~
1단계. 리스트에 들어있는 각 자연수의 개수를 셉니다.
2단계. 가장 많이 등장하는 수의 개수를 구합니다.
3단계. 가장 적게 등장하는 수의 개수를 구합니다.
4단계. 가장 많이 등장하는 수가 가장 적게 등장하는 수보다 몇 배 더 많은지 구합니다.
~~~

단, 몇 배 더 많은지 구할 때는 소수 부분은 버리고 정수 부분만 구하면 됩니다.

자연수가 들어있는 리스트 arr가 매개변수로 주어질 때, 가장 많이 등장하는 숫자가 가장 적게 등장하는 숫자보다 몇 배 더 많은지 return 하도록 solution 함수를 작성하려 합니다. 위 구조를 참고하여 코드가 올바르게 동작할 수 있도록 빈칸에 주어진 func_a, func_b, func_c 함수와 매개변수를 알맞게 채워주세요.

---
##### 매개변수 설명
자연수가 들어있는 리스트 arr가 solution 함수의 매개변수로 주어집니다.
* arr의 길이는 3 이상 1,000 이하입니다.
* arr에는 1 이상 1,000이하의 자연수가 들어있습니다.

---
##### return 값 설명
리스트에서 가장 많이 등장하는 숫자가 가장 적게 등장하는 숫자보다 몇 배 이상 많은지 return 해주세요.

* 가장 많이 들어있는 수의 개수와 가장 적게 들어있는 수의 개수가 같은 경우에는 1을 return 합니다.

---
##### 예시

| arr                   | return |
|-----------------------|--------|
| [1,2,3,3,1,3,3,2,3,2] | 2      |

##### 예시 설명
리스트에 1이 2개, 2가 3개, 3이 5개 들어있습니다.

* 가장 적게 들어있는 숫자 : 1 (2개)
* 가장 많이 들어있는 숫자 : 3 (5개)

3이 1보다 2.5배 많이 들어있으며, 소수 부분을 버리고 2를 return 하면 됩니다.


#문제5
주어진 리스트의 순서를 뒤집으려고 합니다.

예를 들어 주어진 리스트가 [1, 4, 2, 3]이면, 순서를 뒤집은 리스트는 [3, 2, 4, 1]입니다.

정수가 들어있는 리스트 arr가 매개변수로 주어졌을 때, arr를 뒤집어서 return 하도록 solution 함수를 작성하려 합니다. 빈칸을 채워 전체 코드를 완성해주세요.

---
##### 매개변수 설명
정수가 들어있는 리스트 arr가 solution 함수의 매개변수로 주어집니다.
* arr의 길이는 1 이상 100 이하입니다.
* arr의 원소는 -100 이상 100 이하의 정수입니다.

---
##### return 값 설명
리스트 arr의 순서를 뒤집어서 return 해주세요.

---
##### 예시

| arr          | return       |
|--------------|--------------|
| [1, 4, 2, 3] | [3, 2, 4, 1] |

##### 예시 설명
[1, 4, 2, 3]을 뒤에서부터 읽으면 3, 2, 4, 1입니다. 따라서 [1, 4, 2, 3]의 순서를 뒤집은 결과는 [3, 2, 4, 1]이 됩니다.



#문제6
369 게임은 여러 명이 같이하는 게임입니다. 게임의 규칙은 아래와 같습니다.
* 1부터 시작합니다.
* 한 사람씩 차례대로 숫자를 1씩 더해가며 말합니다.
* 말해야 하는 숫자에 3, 6, 9중 하나라도 포함되어있다면 숫자를 말하는 대신 숫자에 포함된 3, 6, 9의 개수만큼 손뼉을 칩니다.

어떤 수 number가 매개변수로 주어질 때, 1부터 number까지 369게임을 올바르게 진행했을 경우 박수를 총 몇 번 쳤는지를 return 하도록 solution 함수를 작성하려 합니다. 빈칸을 채워 전체 코드를 완성해주세요.

---

#####매개변수 설명
number가 solution 함수의 매개변수로 주어집니다.
* number는 10 이상 1,000 이하의 자연수입니다.

---

#####return 값 설명
1부터 number까지 369게임을 올바르게 진행했을 경우 박수를 총 몇 번을 쳤는지 return 해주세요.

---

#####예시

| number | return |
|--------|--------|
| 40     | 22     |

#####예시 설명
3, 6, 9 : 각각 한 번 (+3)
13, 16, 19 : 각각 한 번 (+3)
23, 26, 29 : 각각 한 번 (+3)
30, 31, 32, 33, ..., 38, 39 : 십의 자리 열 번 + 일의 자리 세 번 (+13)
따라서, 3 + 3 + 3 + 13 = 22번의 박수를 칩니다.


#문제7
A 대학에서는 수준별 영어 강의를 제공하고 있습니다. 초급 영어 강의는 토익시험에서 650점 이상 800점 미만의 성적을 취득한 학생만을 수강대상으로 하고 있습니다. 초급 영어 강의에 수강신청한 사람이 10명일 때, 이 중에서 몇명이 수강 대상에 해당하는지 확인하려합니다.

수강신청자들의 토익 성적이 들어있는 리스트 scores가 매개변수로 주어질 때, 수강 대상자들의 인원수를 return 하도록 solution 함수를 작성했습니다. 그러나, 코드 일부분이 잘못되어있기 때문에, 몇몇 입력에 대해서는 올바르게 동작하지 않습니다. 주어진 코드에서 _**한 줄**_만 변경해서 모든 입력에 대해 올바르게 동작하도록 수정해주세요.

---

#####매개변수 설명
수강신청자들의 토익 성적이 들어있는 리스트 scores가 solution 함수의 매개변수로 주어집니다.
* scores의 원소는 500 이상 990 이하의 정수입니다.
* scores의 길이는 10입니다.

---

#####return 값 설명
수강 대상자들의 인원수를 return 해주세요.

---

#####예시

| scores                                             | return |
|----------------------------------------------------|--------|
| [650, 722, 914, 558, 714, 803, 650, 679, 669, 800] | 6      |

#####예시 설명
|점수| 650 | 722 | 914 | 558 | 714 | 803 | 650 | 679 | 669 | 800 |
|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|
|수강 대상| O   | O   | X   | X   | O   | X   | O   | O   | O   | X   |

650점 이상 800점 미만의 성적을 취득한 학생이 수강대상이므로, 800점을 취득한 학생은 수강대상이 아닙니다.
따라서, 6명이 수강 대상입니다.


#문제8
앞에서부터 읽을 때와 뒤에서부터 읽을 때 똑같은 단어 또는 문장을 팰린드롬(palindrome)이라고 합니다. 예를 들어서 racecar, noon은 팰린드롬 단어입니다. 

소문자 알파벳, 공백(" "), 그리고 마침표(".")로 이루어진 문장이 팰린드롬 문장인지 점검하려 합니다. 문장 내에서 알파벳만 추출하였을 때에 팰린드롬 단어이면 팰린드롬 문장입니다. 예를 들어, "Never odd or even."과 같은 문장은 팰린드롬입니다.

소문자 알파벳, 공백(" "), 그리고 마침표(".")로 이루어진 문장 sentence가 주어질 때 팰린드롬인지 아닌지를 return 하도록 solution 함수를 작성했습니다. 그러나, 코드 일부분이 잘못되어있기 때문에, 몇몇 입력에 대해서는 올바르게 동작하지 않습니다. 주어진 코드에서 _**한 줄**_만 변경해서 모든 입력에 대해 올바르게 동작하도록 수정해주세요.

---
##### 매개변수 설명
소문자 알파벳, 공백(" "), 그리고 마침표(".")로 이루어진 문장 sentence가 solution 함수의 매개변수로 주어집니다.

* sentence의 길이는 1이상 100이하입니다.
* sentence에는 적어도 하나의 알파벳이 포함되어 있습니다.
* setntence의 각 문자는 소문자 알파벳, 공백(" "), 또는 마침표(".")입니다.

---
##### return 값 설명
주어진 문장이 팰린드롬인지 아닌지를 return 해주세요.

---
##### 예시

| sentence              | return  |
|---------------------- |-------- |
| "never odd or even."  | true    |
| "palindrome"          | false   |


##### 예시 설명
예시 #1
알파벳과 숫자만 추출하여 소문자로 변환해보면 "neveroddoreven"이 되며 이 단어는 팰린드롬입니다.

예시 #2
문장의 맨 앞 문자인 "p"와 맨 뒤 문자인 "e"가 다르므로 팰린드롬이 아닙니다.


#문제9
알파벳 문자열이 주어질 때, 연속하는 중복 문자를 삭제하려고 합니다. 예를 들어, "senteeeencccccceeee"라는 문자열이 주어진다면, "sentence"라는 결과물이 나옵니다.

영어 소문자 알파벳으로 이루어진 임의의 문자열 characters가 매개변수로 주어질 때, 연속하는 중복 문자들을 삭제한 결과를 return 하도록 solution 함수를 작성하였습니다. 그러나, 코드 일부분이 잘못되어있기 때문에, 코드가 올바르게 동작하지 않습니다. 주어진 코드에서 _**한 줄**_만 변경해서 모든 입력에 대해 올바르게 동작하도록 수정하세요.

---

#####매개변수 설명
영어 소문자 알파벳으로 이루어진 임의의 문자열 characters가 solution 함수의 매개변수로 주어집니다. 
* characters는 알파벳 소문자로만 이루어져있습니다.
* characters의 길이는 10 이상 100 이하입니다.

---

#####return 값 설명
characters에서 연속하는 중복 문자를 제거한 문자열을 return 해주세요.

---

#####예시

| characters                  | return    |
|-------------------------|-----------|
| "senteeeencccccceeee" | "sentence" |


#문제10
평균은 자료의 합을 자료의 개수로 나눈 값을 의미합니다. 자연수가 들어있는 리스트의 평균을 구하고, 평균 이하인 숫자는 몇 개 있는지 구하려합니다.

예를 들어 주어진 리스트가 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]이라면, 평균은 5.5이므로 리스트에서 평균 이하인 값은 5개입니다.

자연수가 들어있는 리스트 data가 매개변수로 주어질 때, 리스트에 평균 이하인 값은 몇 개인지 return 하도록 solution 함수를 작성했습니다. 그러나, 코드 일부분이 잘못되어있기 때문에, 몇몇 입력에 대해서는 올바르게 동작하지 않습니다. 주어진 코드에서 _**한 줄**_만 변경해서 모든 입력에 대해 올바르게 동작하도록 수정하세요.

---

#####매개변수 설명
자연수가 들어있는 리스트 data가 solution 함수의 매개변수로 주어집니다.
* data의 길이는 10 이상 100 이하 정수입니다.
* data의 원소는 1 이상 1,000 이하의 자연수입니다.

---

#####return 값 설명
평균보다 값이 작은 자연수는 몇개인지 return 해주세요.

---
#####예시

| data                            | return |
|---------------------------------|--------|
| [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] | 5      |
| [1, 1, 1, 1, 1, 1, 1, 1, 1, 10] | 9      |

---
#####예시 설명
예시 #1
자료의 합은 55이며, 자료의 개수는 10개입니다. 따라서 평균은 55 / 10 = 5.5입니다.
주어진 리스트에서 5.5보다 작은 숫자는 총 5개입니다.

예시 #2
자료의 합은 19이며, 자료의 개수는 10개입니다. 따라서 평균은 19 / 10 = 1.9입니다.
주어진 리스트에서 1.9보다 작은 숫자는 총 9개입니다.


 

#문제1
왼손 장갑의 제품 번호가 들어있는 리스트와 오른손 장갑의 제품 번호가 들어있는 리스트가 있습니다. 제품 번호는 1부터 10 사이의 자연수입니다. 제품 번호가 같은 왼손장갑과 오른손 장갑을 합쳐 장갑 한 쌍을 만들 수 있습니다. 이때, 최대한 많은 쌍의 장갑을 만들면 최대 몇 쌍을 만들 수 있는지 구하려 합니다. 이를 위해 다음과 같이 프로그램 구조를 작성했습니다. 

~~~
1. 왼손 장갑이 제품 번호별로 몇 개씩 있는지 개수를 셉니다.
2. 오른손 장갑이 제품 번호별로 몇 개씩 있는지 개수를 셉니다.
3. 각 제품 번호별로 최대한 많은 장갑 쌍을 만들면서 개수를 셉니다.
~~~

왼손 장갑의 제품 번호가 들어있는 리스트 left_gloves와 오른손 장갑의 제품 번호가 들어있는 리스트 right_gloves가 매개변수로 주어질 때, 최대 몇 개의 장갑 쌍을 만들 수 있는지 return 하도록 solution 함수를 작성하려 합니다. 이때, 위 구조를 참고하여 중복되는 부분은 func_a라는 함수로 작성했습니다. 코드가 올바르게 동작할 수 있도록 빈칸을 알맞게 채워주세요.

---
##### 매개변수 설명
왼손 장갑의 제품 번호가 들어있는 리스트 left_gloves와 오른손 장갑의 제품 번호가 들어있는 리스트 right_gloves가 solution 함수의 매개변수로 주어집니다.

* left_gloves의 길이는 1 이상 100 이하입니다.
* left_gloves의 원소는 1 이상 10 이하의 자연수입니다.
* right_gloves의 길이는 1 이상 100 이하입니다.
* right_gloves의 원소는 1 이상 10 이하의 자연수입니다.

---
##### return 값 설명 
왼손과 오른손의 제품 번호가 같은 장갑 끼리 한 쌍을 만들 때, 최대 몇 개의 쌍을 만들 수 있는지 개수를 return 해주세요.

---
##### 예시

| left_gloves              | right_gloves                  | return |
|---------------------------|--------------------------------|--------|
| [2, 1, 2, 2, 4] | [1, 2, 2, 4, 4, 7] | 4      |

---
##### 예시 설명
예시 #1
왼손 장갑 : 1번 장갑 1개, 2번 장갑 3개, 4번 장갑 1개가 있습니다.
오른손 장갑 : 1번 장갑 1개, 2번 장갑 2개, 4번 장갑 2개, 7번 장갑 1개가 있습니다.

따라서 1번 장갑 한 쌍, 2번 장갑 두 쌍, 4번 장갑 한 쌍을 만들면 최대 4개의 장갑 쌍을 만들 수 있습니다.


#문제2
자연수가 들어있는 리스트에 3의 배수와 5의 배수 중 어떤 수가 더 많은지 알아보려 합니다. 이를 위해 다음과 같이 프로그램 구조를 작성했습니다.

~~~
1. 3의 배수의 개수를 셉니다.
2. 5의 배수의 개수를 셉니다.
3. 3의 배수와 5의 배수의 개수를 비교 후 다음을 수행합니다.
  3-1. 만약 3의 배수가 더 많다면 "three"를 return 합니다.
  3-2. 만약 5의 배수가 더 많다면 "five"를 return 합니다.
  3-3. 만약 3의 배수와 5의 배수의 개수가 같다면 "same"을 return 합니다.
~~~

자연수가 들어있는 리스트 arr가 매개변수로 주어질 때, 리스트에 3의 배수의 개수가 더 많다면 "three"를, 5의 배수의 개수가 더 많다면 "five"를, 3의 배수와 5의 배수의 개수가 같다면 "same"을 return 하도록 solution 함수를 작성하려 합니다. 위 구조를 참고하여 코드가 올바르게 동작할 수 있도록 빈칸에 주어진 func_a, func_b, func_c 함수와 매개변수를 알맞게 채워주세요.

---
#####매개변수 설명
자연수가 들어있는 리스트 arr가 solution 함수의 매개변수로 주어집니다.
* arr의 길이는 1 이상 100 이하입니다.
* arr에 들어있는 숫자는 1 이상 1,000 이하의 자연수입니다.

---
#####return 값 설명
리스트에 3의 배수의 개수가 더 많다면 "three"를, 5의 배수의 개수가 더 많다면 "five"를, 3의 배수와 5의 배수의 개수가 같다면 "same"을 return 해주세요.

---
#####예시

| arr                    | return |
|------------------------|--------|
| [2, 3, 6, 9, 12, 15, 10, 20, 22, 25] | "three" |

#####예시 설명

* 3의 배수 : 3, 6, 9, 12, 15
* 5의 배수 : 10, 15, 20, 25

3의 배수는 5개, 5의 배수는 4개이므로 3의 배수가 더 많습니다. 따라서 "three"를 return 합니다.


#문제3
서로 다른 두 자연수 N과 M이 매개변수로 주어질 때, N부터 M까지의 자연수 중에서 짝수들의 제곱의 합을 return 하도록 solution 함수를 완성해주세요.

---
#####매개변수 설명
두 자연수 N과 M이 solution 함수의 매개변수로 주어집니다.
* N과 M은 1 이상 1,000 이하의 자연수이며, N < M을 항상 만족합니다.

---
#####return 값 설명
N부터 M까지의 수 중에서 짝수인 수의 제곱의 합을 return 해주세요.

---
#####예시

| N | M | return |
|---|---|--------|
| 4 | 7 | 52     |

#####예시 설명
4부터 7까지의 자연수 중에서 짝수는 4와 6입니다.

* 4^2 + 6^2 = 16 + 36 = 52

따라서 52를 return 하면 됩니다.


#문제4
단어들이 들어있는 리스트에서 길이가 5 이상인 단어를 리스트에 들어있는 순서대로 이어 붙이려 합니다.

예를 들어 리스트가 다음과 같은 경우

["my", "favorite", "color", "is", "violet"]

"favoritecolorviolet"을 만들면 됩니다.

단어들이 들어있는 리스트 words가 solution 함수의 매개변수로 주어질 때, 길이가 5 이상인 단어를 순서대로 이어 붙인 문자열을 return 하도록 solution 함수를 완성해주세요.

---
#####매개변수 설명
단어들이 들어있는 리스트 words가 solution 함수의 매개변수로 주어집니다.

* words의 길이는 1 이상 100 이하입니다.
* words에 들어있는 각 단어의 길이는 1 이상 10 이하이며, 알파벳 소문자로만 이루어져 있습니다.

---
#####return 값 설명
길이가 5 이상인 단어를 순서대로 이어 붙여 return 해주세요.
* 만약 return 할 문자열이 빈 문자열이면 "empty"를 return 해주세요.

---
#####예시

| words                                       | return                |
|---------------------------------------------|-----------------------|
| ["my", "favorite", "color", "is", "violet"] | "favoritecolorviolet" |
| ["yes", "i", "am"]                          | "empty"               |

#####예시 설명
예시 #1
길이가 5 이상인 단어는 "favorite", "color", "violet" 입니다. 이를 리스트에 들어있는 순서대로 이어 붙이면 "favoritecolorviolet"이 됩니다.

예시 #2
길이가 5 이상인 단어가 없으므로 "empty"를 return 하면 됩니다.


#문제5
게임 캐릭터가 몬스터와 1:1 전투를 하려 합니다. 몬스터는 처음에 일정 수치의 체력(HP)을 가지고 있습니다. 캐릭터가 전투에서 이기려면 몬스터를 공격해 몬스터의 체력을 0이하로 만들어야합니다. 캐릭터는 공격 마법만 사용하며, 공격 마법은 항상 같은 데미지를 입힙니다. 몬스터는 힐링 마법만을 사용하며, 힐링 마법은 항상 같은 수치로 체력을 회복합니다. 둘은 항상 번갈아 가며 마법을 사용하고, 처음에는 항상 캐릭터가 먼저 공격을 시작합니다.

캐릭터의 공격력 attack과 몬스터가 자신의 차례에 회복하는 체력 recovery, 몬스터의 초기 체력 hp가 매개변수로 주어질 때, 몬스터를 잡기 위해서 최소 몇 번 공격해야 하는지 return 하도록 solution 함수를 작성하려 합니다. 빈칸을 채워 전체 코드를 완성해주세요.

---
#####매개변수 설명
캐릭터의 공격력 attack과 몬스터가 자신의 차례에 회복하는 체력 recovery, 몬스터의 초기 체력 hp가 solution 함수의 매개변수로 주어집니다.

* attack은 1 이상 100 이하의 자연수입니다.
* recovery는 1 이상 100 이하의 자연수입니다.
* 캐릭터의 공격력은 항상 몬스터의 회복력보다 큽니다(recovery < attack).
* hp는 200 이상 1,000 이하의 자연수입니다.

---
#####return 값 설명
몬스터를 잡기 위해서 최소 몇 번 공격해야 하는지 return 해주세요.

---
#####예시

| attack | recovery | hp  | return |
|--------|----------|-----|--------|
| 30     | 10       | 60 | 3      |

#####예시 설명

몬스터의 체력 변화는 아래와 같습니다.

| 차례 | hp 변화  | 남은 hp |
|-------|----------|---------|
| 캐릭터     | 없음        | 60      |
| 몬스터     | 공격 -30 | 30      |
| 캐릭터     | 회복 +10 | 40      |
| 몬스터     | 공격 -30 | 10      |
| 캐릭터     | 회복 +10 | 20      |
| 몬스터     | 공격 -30 | -10       |

따라서 최소 3번 공격해야 몬스터를 잡을 수 있습니다.



#문제6
하루 동안 엘리베이터가 멈춘 층이 순서대로 들어있는 리스트가 있습니다. 이때, 엘리베이터의 총 이동거리를 구하려 합니다. 단, 층과 층 사이의 거리는 1입니다. 

예를 들어 리스트에 [1, 2, 5, 4, 2]가 들어있다면, 엘리베이터가 이동한 거리는 7입니다.
 
하루 동안 엘리베이터가 멈춰 선 층이 순서대로 들어있는 리스트 floors가 매개변수로 주어질 때, 엘리베이터의 총 이동 거리를 return 하도록 solution 함수를 작성하려 합니다. 빈칸을 채워 전체 코드를 완성해주세요.

---
#####매개변수 설명
하루 동안 엘리베이터가 멈춘 층이 순서대로 들어있는 리스트 floors가 solution 함수의 매개변수로 주어집니다.
* floors의 길이는 2 이상 100 이하입니다.
* floors의 원소는 1 이상 100 이하의 자연수이며, 인접한 두 원소의 값이 같은 경우는 주어지지 않습니다.
* floors의 첫 번째 원소는 엘리베이터의 처음 위치를 나타냅니다.

---
#####return 값 설명
엘리베이터의 총 이동 거리를 return 해주세요.

---
#####예시
| floors          | return |
|-----------------|--------|
| [1, 2, 5, 4, 2] | 7      |

#####예시 설명
엘리베이터는 처음에 1층에 있으며, 다음 순서대로 움직였습니다.

* 1층 - 2층 - 5층 - 4층 - 2층

층과 층사이의 거리는 1이므로, 엘리베이터가 이동한 거리는 다음과 같습니다.

* 1층 - 2층 (이동 거리 : 1)
* 2층 - 5층 (이동 거리 : 3)
* 5층 - 4층 (이동 거리 : 1)
* 4층 - 2층 (이동 거리 : 2)

따라서 총 이동 거리는 7입니다.


#문제7
화씨온도(℉)를 섭씨온도(℃)로, 섭씨온도(℃)를 화씨온도(℉)로 바꾸려고 합니다. 두 온도 사이의 환산 공식은 다음과 같습니다.

~~~
환산공식
* 화씨온도(℉)에서 섭씨온도(℃)로 환산 : (화씨온도 - 32) ÷ 1.8 = 섭씨온도
* 섭씨온도(℃)에서 화씨온도(℉)로 환산 : (섭씨온도 x 1.8) + 32 = 화씨온도
~~~

현재 온도 value와 현재 단위 unit이 매개변수로 주어질 때, 환산한 온도의 정수 부분을 return 하도록 solution 함수를 작성했습니다. 그러나, 코드 일부분이 잘못되어있기 때문에, 몇몇 입력에 대해서는 올바르게 동작하지 않습니다. 주어진 코드에서 _**한 줄**_만 변경해서 모든 입력에 대해 올바르게 동작하도록 수정하세요.

---

#####매개변수 설명
현재 온도 value와 현재 단위 unit이 solution 함수의 매개변수로 주어집니다.
* unit은 화씨온도 "F"와 섭씨온도 "C" 둘 중 하나로 주어집니다.
  * unit이 "F"인 경우 value는 화씨온도(℉)를 나타냅니다.
  * unit이 "C"인 경우 value는 섭씨온도(℃)를 나타냅니다.
* value는 -460 이상 1,000 이하의 정수입니다.

---

##### return 값 설명
환산한 온도의 정수 부분을 return 해주세요.
* unit이 "F"인 경우에는 화씨온도(℉)에서 섭씨온도(℃)로 환산해주세요.
* unit이 "C"인 경우에는 섭씨온도(℃)에서 화씨온도(℉)로 환산해주세요.

---

#####예시 

| value | unit | return |
|-------|------|--------|
| 527   | "C"  | 980    |

#####예시 설명
unit이 "C" 이므로 주어진 value는 527℃를 나타냅니다. 이를 화씨온도(℉)로 환산하면 다음과 같습니다.
(섭씨온도 x 1.8) + 32 = (527 x 1.8) + 32 = 980.6

따라서 환산 결과는 980.6℉이며, 정수 부분만 return 하면 되므로 980을 return 하면 됩니다.



#문제8
자연수의 각 자릿수 중에서 소수는 몇 개인지 구하려 합니다. 즉, 자연수를 각 자릿수별로 나누었을 때, 2, 3, 5, 7이 몇 개 있는지 구하려 합니다.

예를 들어, 자연수가 29022531일 때, 각 자릿수 중 소수의 위치는 다음과 같습니다.

* `2`90`2``2``5``3`1

따라서 소수의 개수는 총 5개입니다.

자연수 number가 매개변수로 주어질 때, number의 각 자릿수 중 소수는 몇 개인지 return 하도록 solution 함수를 작성했습니다. 그러나, 코드 일부분이 잘못되어있기 때문에, 몇몇 입력에 대해서는 올바르게 동작하지 않습니다. 주어진 코드에서 _**한 줄**_만 변경해서 모든 입력에 대해 올바르게 동작하도록 수정하세요.

---
#####매개변수 설명
자연수 number가 solution 함수의 매개변수로 주어집니다.
* number는 1 이상 1,000,000,000 이하의 자연수입니다.

---
#####return 값 설명
number의 각 자릿수 중 소수는 몇 개인지 return 해주세요.

---
#####예시

| number   | return |
|----------|--------|
| 29022531 | 5      |


#문제9
N명의 후보에 대해 투표한 결과가 들어있는 리스트가 있습니다. 예를 들어 5명의 후보에 대해 투표를 진행한 결과가 [2, 5, 3, 4, 1, 5, 1, 5, 5, 3]이라면 순서대로 [2번, 5번, 3번, 4번, 1번, 5번, 1번, 5번, 5번, 3번] 후보에 투표했음을 나타냅니다. 이때, 정확히 K 표를 받은 후보는 총 몇 명인지 구하려 합니다. 

예를 들어 K = 2일 때, 위 투표 결과에서 정확히 2표를 받은 후보는 1번, 3번 후보로, 총 2명입니다. 

투표 결과가 들어있는 리스트 votes, 후보의 수 N, 표의 개수 K가 매개변수로 주어질 때, K 표를 받은 후보는 몇 명인지 return 하도록 solution 함수를 작성했습니다. 그러나, 코드 일부분이 잘못되어있기 때문에, 몇몇 입력에 대해서는 올바르게 동작하지 않습니다. 주어진 코드에서 _**한 줄**_만 변경해서 모든 입력에 대해 올바르게 동작하도록 수정하세요.

---
#####매개변수 설명
투표 결과가 들어있는 리스트 votes, 후보의 수 N, 표의 개수 K가 solution 함수의 매개변수로 주어집니다.
* votes의 길이는 10 이상, 100 이하입니다.
* votes의 원소는 1 이상, 전체 후보의 수 N 이하의 자연수입니다.
* N은 3 이상 10 이하의 자연수입니다.
* K는 0 이상 100 이하의 정수입니다.

---
#####return 값 설명
K 표를 받은 후보는 몇 명인지 return 해주세요.

---
#####예시
| votes                          | N | K | return |
|--------------------------------|---|---|--------|
| [2, 5, 3, 4, 1, 5, 1, 5, 5, 3] | 5 | 2 | 2      |

#####예시 설명
각 후보가 받은 표는 다음과 같습니다.

* 1번 후보 : 2표
* 2번 후보 : 1표
* 3번 후보 : 2표
* 4번 후보 : 1표
* 5번 후보 : 4표

따라서 2표를 받은 후보는 1번, 3번 후보로 총 2명입니다.


#문제10
A 백화점에서는 고객의 구매금액에 따라 다음과 같이 상품권을 지급합니다.

| 구매 금액         | 상품권       |
|-------------------|--------------|
| 100만 원 이상 구매 | 5만 원 상품권 |
| 60만 원 이상 구매  | 3만 원 상품권 |
| 40만 원 이상 구매  | 2만 원 상품권 |
| 20만 원 이상 구매  | 1만 원 상품권 |

이때, 상품권은 지급 가능한 가장 큰 금액으로 한 장만 지급합니다. 예를 들어 고객이 65만 원을 구매했다면, 3만 원 상품권 한 장만 지급합니다.

고객들의 구매 금액이 들어있는 리스트 purchase가 주어질 때, 고객들에게 지급해야 하는 상품권 총액을 return 하도록 solution 함수를 작성했습니다. 그러나, 코드 일부분이 잘못되어있기 때문에, 코드가 올바르게 동작하지 않습니다. 주어진 코드에서 _**한 줄**_만 변경해서 모든 입력에 대해 올바르게 동작하도록 수정해주세요.

---
#####매개변수 설명
고객들의 구매 금액이 들어있는 리스트 purchase가 solution 함수의 매개변수로 주어집니다.
* purchase의 길이는 1 이상 100 이하입니다.
* purchase의 원소는 10 이상 1,500,000 이하의 자연수이며, 10원 단위로 주어집니다.

---
#####return 값 설명
고객들에게 지급해야 하는 상품권 총액을 return 해주세요.

---
#####예시

| purchase                                  | return |
|-------------------------------------------|--------|
| [150000, 210000, 399990, 990000, 1000000] | 100000 |

#####예시 설명

* 210,000원, 399,990원을 구매한 고객에게 1만 원 상품권을 지급해야 합니다.
* 990,000원을 구매한 고객에게 3만 원 상품권을 지급해야 합니다.
* 1,000,000원을 구매한 고객에게 5만 원 상품권을 지급해야 합니다.

따라서 지급해야 하는 상품권은 1만 원 상품권 2장, 3만 원 상품권 1장, 5만 원 상품권 1장으로, 총액은 10만 원 입니다.


 

'{BE} Python 3.1x' 카테고리의 다른 글

xlsx control. python 1 : swift 0  (0) 2020.09.12
Swift VS Python 으로 카테고리 변경  (0) 2020.09.02
텍스트를 이미지로 그려서 붙이기  (0) 2020.07.01
plist 읽기  (0) 2020.07.01
nodepointer  (1) 2020.07.01

러프한 코드 뭉치지만 도움이 될 부분도 있을 것 같다.


    private func drawText(str : String, x : CGFloat, y : CGFloat, width : CGFloat, height : CGFloat, txtSize : CGFloat) -> CALayer {

        let commonWidth = width + (txtSize / 4)

        let renderer = UIGraphicsImageRenderer(size: CGSize(width: commonWidth, height: height))

        let img = renderer.image { soraforever in

            let paragraphStyle = NSMutableParagraphStyle()

            paragraphStyle.alignment = .center

            let attrs = [NSAttributedStringKey.font: UIFont(name: "".font1(), size: txtSize)!, NSAttributedStringKey.paragraphStyle: paragraphStyle]

            let string = str

            string.draw(with: CGRect(x: 0, y: 0, width: commonWidth, height: height), options: .usesLineFragmentOrigin, attributes: attrs, context: nil)

        }


self.addSublayer(drawText(str: String(l), x: xlocation-(GS.s.jhATextPanelSize*3), y: jhDraw.ARQ-mMargin, width: GS.s.jhATextPanelSize, height: GS.s.jhATextPanelSize, txtSize: GS.s.jhATextSize))

            }


 self.addSublayer(drawText(str: mUnit, x: 50, y: 50, width: GS.s.jhATextPanelSize+10, height: GS.s.jhATextPanelSize, txtSize: 7)) 


   self.addSublayer(drawText(str: label, x: 100, y: fx2 - 600, width: GS.s.jhATextPanelSize, height: GS.s.jhATextPanelSize, txtSize: GS.s.jhATextSize))


'{BE} Python 3.1x' 카테고리의 다른 글

Swift VS Python 으로 카테고리 변경  (0) 2020.09.02
python basic problems  (0) 2020.08.11
plist 읽기  (0) 2020.07.01
nodepointer  (1) 2020.07.01
dropDown Menu  (2) 2020.07.01



다음과 같은 test.plist 가 있을 때,


<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">


<plist version="1.0">


<array>


<integer>73</integer>


<integer>72</integer>


<integer>142</integer>


<integer>143</integer>


<integer>132</integer>


<integer>133</integer>


<integer>133</integer>


<integer>122</integer>


<integer>102</integer>


<integer>102</integer>


<integer>102</integer>


<integer>73</integer>


</array>


</plist>





var dataSource : Array<Int> = Array()





let lvPath = Bundle.main.url(forResource: "test", withExtension: "plist")!


let lvArray = try! Data(contentsOf: lvPath)


let decoder = PropertyListDecoder()


dataSource = try! decoder.decode(Array<Int>.self, from: lvArray)





print("jhFile_dataSource => ", dataSource)






plist 자료형은


https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/PropertyLists/AboutPropertyLists/AboutPropertyLists.html

About Property Lists



developer.apple.com


'{BE} Python 3.1x' 카테고리의 다른 글

python basic problems  (0) 2020.08.11
텍스트를 이미지로 그려서 붙이기  (0) 2020.07.01
nodepointer  (1) 2020.07.01
dropDown Menu  (2) 2020.07.01
UITabBar 크기 조정  (0) 2020.06.30
https://github.com/apple/swift/blob/master/stdlib/public/runtime/Demangle.cpp

//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
#include "swift/Basic/Range.h"
#include "swift/ABI/TypeIdentity.h"
#include "swift/Runtime/Metadata.h"
#include "swift/Runtime/Portability.h"
#include "swift/Strings.h"
#include "Private.h"
#include <vector>
#if SWIFT_OBJC_INTEROP
#include <objc/runtime.h>
#endif
using namespace swift;
Demangle::NodePointer
swift::_buildDemanglingForContext(const ContextDescriptor *context,
llvm::ArrayRef<NodePointer> demangledGenerics,
Demangle::Demangler &Dem) {
unsigned usedDemangledGenerics = 0;
NodePointer node = nullptr;
// Walk up the context tree.
std::vector<const ContextDescriptor *> descriptorPath;
{
const ContextDescriptor *parent = context;
while (parent) {
descriptorPath.push_back(parent);
parent = parent->Parent;
}
}
auto getGenericArgsTypeListForContext =
[&](const ContextDescriptor *context) -> NodePointer {
if (demangledGenerics.empty())
return nullptr;
if (context->getKind() == ContextDescriptorKind::Anonymous)
return nullptr;
auto generics = context->getGenericContext();
if (!generics)
return nullptr;
auto numParams = generics->getGenericContextHeader().NumParams;
if (numParams <= usedDemangledGenerics)
return nullptr;
auto genericArgsList = Dem.createNode(Node::Kind::TypeList);
for (unsigned e = generics->getGenericContextHeader().NumParams;
usedDemangledGenerics < e;
++usedDemangledGenerics) {
genericArgsList->addChild(demangledGenerics[usedDemangledGenerics],
Dem);
}
return genericArgsList;
};
for (auto component : reversed(descriptorPath)) {
switch (auto kind = component->getKind()) {
case ContextDescriptorKind::Module: {
assert(node == nullptr && "module should be top level");
auto name = llvm::cast<ModuleContextDescriptor>(component)->Name.get();
node = Dem.createNode(Node::Kind::Module, name);
break;
}
case ContextDescriptorKind::Extension: {
auto extension = llvm::cast<ExtensionContextDescriptor>(component);
// Demangle the extension self type.
auto selfType = Dem.demangleType(extension->getMangledExtendedContext());
if (selfType->getKind() == Node::Kind::Type)
selfType = selfType->getChild(0);
// Substitute in the generic arguments.
auto genericArgsList = getGenericArgsTypeListForContext(component);
if (selfType->getKind() == Node::Kind::BoundGenericEnum
|| selfType->getKind() == Node::Kind::BoundGenericStructure
|| selfType->getKind() == Node::Kind::BoundGenericClass
|| selfType->getKind() == Node::Kind::BoundGenericOtherNominalType) {
if (genericArgsList) {
auto substSelfType = Dem.createNode(selfType->getKind());
substSelfType->addChild(selfType->getChild(0), Dem);
substSelfType->addChild(genericArgsList, Dem);
selfType = substSelfType;
} else {
// TODO: Use the unsubstituted type if we can't handle the
// substitutions yet.
selfType = selfType->getChild(0)->getChild(0);
}
}
auto extNode = Dem.createNode(Node::Kind::Extension);
extNode->addChild(node, Dem);
extNode->addChild(selfType, Dem);
// TODO: Turn the generic signature into a demangling as the third
// generic argument.
node = extNode;
break;
}
case ContextDescriptorKind::Protocol: {
auto protocol = llvm::cast<ProtocolDescriptor>(component);
auto name = protocol->Name.get();
auto protocolNode = Dem.createNode(Node::Kind::Protocol);
protocolNode->addChild(node, Dem);
auto nameNode = Dem.createNode(Node::Kind::Identifier, name);
protocolNode->addChild(nameNode, Dem);
node = protocolNode;
break;
}
default:
// Form a type context demangling for type contexts.
if (auto type = llvm::dyn_cast<TypeContextDescriptor>(component)) {
auto identity = ParsedTypeIdentity::parse(type);
Node::Kind nodeKind;
Node::Kind genericNodeKind;
switch (kind) {
case ContextDescriptorKind::Class:
nodeKind = Node::Kind::Class;
genericNodeKind = Node::Kind::BoundGenericClass;
break;
case ContextDescriptorKind::Struct:
nodeKind = Node::Kind::Structure;
genericNodeKind = Node::Kind::BoundGenericStructure;
break;
case ContextDescriptorKind::Enum:
nodeKind = Node::Kind::Enum;
genericNodeKind = Node::Kind::BoundGenericEnum;
break;
default:
// We don't know about this kind of type. Use an "other type" mangling
// for it.
nodeKind = Node::Kind::OtherNominalType;
genericNodeKind = Node::Kind::BoundGenericOtherNominalType;
break;
}
// Override the node kind if this is a Clang-imported type so we give it
// a stable mangling.
if (identity.isCTypedef()) {
nodeKind = Node::Kind::TypeAlias;
} else if (nodeKind != Node::Kind::Structure &&
_isCImportedTagType(type, identity)) {
nodeKind = Node::Kind::Structure;
}
auto typeNode = Dem.createNode(nodeKind);
typeNode->addChild(node, Dem);
auto nameNode = Dem.createNode(Node::Kind::Identifier,
identity.getABIName());
if (identity.isAnyRelatedEntity()) {
auto relatedName = Dem.createNode(Node::Kind::RelatedEntityDeclName,
identity.getRelatedEntityName());
relatedName->addChild(nameNode, Dem);
nameNode = relatedName;
}
typeNode->addChild(nameNode, Dem);
node = typeNode;
// Apply generic arguments if the context is generic.
if (auto genericArgsList = getGenericArgsTypeListForContext(component)){
auto unspecializedType = Dem.createNode(Node::Kind::Type);
unspecializedType->addChild(node, Dem);
auto genericNode = Dem.createNode(genericNodeKind);
genericNode->addChild(unspecializedType, Dem);
genericNode->addChild(genericArgsList, Dem);
node = genericNode;
}
break;
}
// This runtime doesn't understand this context, or it's a context with
// no richer runtime information available about it (such as an anonymous
// context). Use an unstable mangling to represent the context by its
// pointer identity.
char addressBuf[sizeof(void*) * 2 + 1 + 1];
snprintf(addressBuf, sizeof(addressBuf), "$%" PRIxPTR, (uintptr_t)component);
auto anonNode = Dem.createNode(Node::Kind::AnonymousContext);
CharVector addressStr;
addressStr.append(addressBuf, Dem);
auto name = Dem.createNode(Node::Kind::Identifier, addressStr);
anonNode->addChild(name, Dem);
anonNode->addChild(node, Dem);
// Collect generic arguments if the context is generic.
auto genericArgsList = getGenericArgsTypeListForContext(component);
if (!genericArgsList)
genericArgsList = Dem.createNode(Node::Kind::TypeList);
anonNode->addChild(genericArgsList, Dem);
node = anonNode;
break;
}
}
// Wrap the final result in a top-level Type node.
auto top = Dem.createNode(Node::Kind::Type);
top->addChild(node, Dem);
return top;
}
// FIXME: This stuff should be merged with the existing logic in
// include/swift/Reflection/TypeRefBuilder.h as part of the rewrite
// to change stdlib reflection over to using remote mirrors.
Demangle::NodePointer
swift::_swift_buildDemanglingForMetadata(const Metadata *type,
Demangle::Demangler &Dem);
static Demangle::NodePointer
_buildDemanglerForBuiltinType(const Metadata *type, Demangle::Demangler &Dem) {
#define BUILTIN_TYPE(Symbol, Name) \
if (type == &METADATA_SYM(Symbol).base) \
return Dem.createNode(Node::Kind::BuiltinTypeName, Name);
#include "swift/Runtime/BuiltinTypes.def"
return nullptr;
}
/// Build a demangled type tree for a nominal type.
static Demangle::NodePointer
_buildDemanglingForNominalType(const Metadata *type, Demangle::Demangler &Dem) {
using namespace Demangle;
// Get the context descriptor from the type metadata.
const TypeContextDescriptor *description;
switch (type->getKind()) {
case MetadataKind::Class: {
auto classType = static_cast<const ClassMetadata *>(type);
#if SWIFT_OBJC_INTEROP
// Peek through artificial subclasses.
while (classType->isTypeMetadata() && classType->isArtificialSubclass())
classType = classType->Superclass;
#endif
description = classType->getDescription();
break;
}
case MetadataKind::Enum:
case MetadataKind::Optional: {
auto enumType = static_cast<const EnumMetadata *>(type);
description = enumType->Description;
break;
}
case MetadataKind::Struct: {
auto structType = static_cast<const StructMetadata *>(type);
description = structType->Description;
break;
}
case MetadataKind::ForeignClass: {
auto foreignType = static_cast<const ForeignClassMetadata *>(type);
description = foreignType->Description;
break;
}
default:
return nullptr;
}
// Gather the complete set of generic arguments that must be written to
// form this type.
std::vector<const Metadata *> allGenericArgs;
gatherWrittenGenericArgs(type, description, allGenericArgs);
// Demangle the generic arguments.
std::vector<NodePointer> demangledGenerics;
for (auto genericArg : allGenericArgs) {
// When there is no generic argument, put in a placeholder.
if (!genericArg) {
auto placeholder = Dem.createNode(Node::Kind::Tuple);
auto emptyList = Dem.createNode(Node::Kind::TypeList);
placeholder->addChild(emptyList, Dem);
auto type = Dem.createNode(Node::Kind::Type);
type->addChild(placeholder, Dem);
demangledGenerics.push_back(type);
continue;
}
// Demangle this argument.
auto genericArgDemangling =
_swift_buildDemanglingForMetadata(genericArg, Dem);
if (!genericArgDemangling)
return nullptr;
demangledGenerics.push_back(genericArgDemangling);
}
return _buildDemanglingForContext(description, demangledGenerics, Dem);
}
// Build a demangled type tree for a type.
//
// FIXME: This should use MetadataReader.h.
Demangle::NodePointer
swift::_swift_buildDemanglingForMetadata(const Metadata *type,
Demangle::Demangler &Dem) {
using namespace Demangle;
switch (type->getKind()) {
case MetadataKind::Class:
case MetadataKind::Enum:
case MetadataKind::Optional:
case MetadataKind::Struct:
case MetadataKind::ForeignClass:
return _buildDemanglingForNominalType(type, Dem);
case MetadataKind::ObjCClassWrapper: {
#if SWIFT_OBJC_INTEROP
auto objcWrapper = static_cast<const ObjCClassWrapperMetadata *>(type);
const char *className = class_getName(objcWrapper->getObjCClassObject());
auto module = Dem.createNode(Node::Kind::Module, MANGLING_MODULE_OBJC);
auto node = Dem.createNode(Node::Kind::Class);
node->addChild(module, Dem);
node->addChild(Dem.createNode(Node::Kind::Identifier,
llvm::StringRef(className)), Dem);
return node;
#else
assert(false && "no ObjC interop");
return nullptr;
#endif
}
case MetadataKind::Existential: {
auto exis = static_cast<const ExistentialTypeMetadata *>(type);
auto protocols = exis->getProtocols();
auto type_list = Dem.createNode(Node::Kind::TypeList);
auto proto_list = Dem.createNode(Node::Kind::ProtocolList);
proto_list->addChild(type_list, Dem);
// The protocol descriptors should be pre-sorted since the compiler will
// only ever make a swift_getExistentialTypeMetadata invocation using
// its canonical ordering of protocols.
for (auto protocol : protocols) {
#if SWIFT_OBJC_INTEROP
if (protocol.isObjC()) {
// The protocol name is mangled as a type symbol, with the _Tt prefix.
StringRef ProtoName(protocol.getName());
NodePointer protocolNode = Dem.demangleSymbol(ProtoName);
// ObjC protocol names aren't mangled.
if (!protocolNode) {
auto module = Dem.createNode(Node::Kind::Module,
MANGLING_MODULE_OBJC);
auto node = Dem.createNode(Node::Kind::Protocol);
node->addChild(module, Dem);
node->addChild(Dem.createNode(Node::Kind::Identifier, ProtoName),
Dem);
auto typeNode = Dem.createNode(Node::Kind::Type);
typeNode->addChild(node, Dem);
type_list->addChild(typeNode, Dem);
continue;
}
// Dig out the protocol node.
// Global -> (Protocol|TypeMangling)
protocolNode = protocolNode->getChild(0);
if (protocolNode->getKind() == Node::Kind::TypeMangling) {
protocolNode = protocolNode->getChild(0); // TypeMangling -> Type
protocolNode = protocolNode->getChild(0); // Type -> ProtocolList
protocolNode = protocolNode->getChild(0); // ProtocolList -> TypeList
protocolNode = protocolNode->getChild(0); // TypeList -> Type
assert(protocolNode->getKind() == Node::Kind::Type);
assert(protocolNode->getChild(0)->getKind() == Node::Kind::Protocol);
} else {
assert(protocolNode->getKind() == Node::Kind::Protocol);
}
type_list->addChild(protocolNode, Dem);
continue;
}
#endif
auto protocolNode =
_buildDemanglingForContext(protocol.getSwiftProtocol(), { }, Dem);
if (!protocolNode)
return nullptr;
type_list->addChild(protocolNode, Dem);
}
if (auto superclass = exis->getSuperclassConstraint()) {
// If there is a superclass constraint, we mangle it specially.
auto result = Dem.createNode(Node::Kind::ProtocolListWithClass);
auto superclassNode = _swift_buildDemanglingForMetadata(superclass, Dem);
result->addChild(proto_list, Dem);
result->addChild(superclassNode, Dem);
return result;
}
if (exis->isClassBounded()) {
// Check if the class constraint is implied by any of our
// protocols.
bool requiresClassImplicit = false;
for (auto protocol : protocols) {
if (protocol.getClassConstraint() == ProtocolClassConstraint::Class)
requiresClassImplicit = true;
}
// If it was implied, we don't do anything special.
if (requiresClassImplicit)
return proto_list;
// If the existential type has an explicit AnyObject constraint,
// we must mangle it as such.
auto result = Dem.createNode(Node::Kind::ProtocolListWithAnyObject);
result->addChild(proto_list, Dem);
return result;
}
// Just a simple composition of protocols.
return proto_list;
}
case MetadataKind::ExistentialMetatype: {
auto metatype = static_cast<const ExistentialMetatypeMetadata *>(type);
auto instance = _swift_buildDemanglingForMetadata(metatype->InstanceType,
Dem);
auto node = Dem.createNode(Node::Kind::ExistentialMetatype);
node->addChild(instance, Dem);
return node;
}
case MetadataKind::Function: {
auto func = static_cast<const FunctionTypeMetadata *>(type);
Node::Kind kind;
switch (func->getConvention()) {
case FunctionMetadataConvention::Swift:
if (!func->isEscaping())
kind = Node::Kind::NoEscapeFunctionType;
else
kind = Node::Kind::FunctionType;
break;
case FunctionMetadataConvention::Block:
kind = Node::Kind::ObjCBlock;
break;
case FunctionMetadataConvention::CFunctionPointer:
kind = Node::Kind::CFunctionPointer;
break;
case FunctionMetadataConvention::Thin:
kind = Node::Kind::ThinFunctionType;
break;
}
std::vector<std::pair<NodePointer, bool>> inputs;
for (unsigned i = 0, e = func->getNumParameters(); i < e; ++i) {
auto param = func->getParameter(i);
auto flags = func->getParameterFlags(i);
auto input = _swift_buildDemanglingForMetadata(param, Dem);
auto wrapInput = [&](Node::Kind kind) {
auto parent = Dem.createNode(kind);
parent->addChild(input, Dem);
input = parent;
};
switch (flags.getValueOwnership()) {
case ValueOwnership::Default:
/* nothing */
break;
case ValueOwnership::InOut:
wrapInput(Node::Kind::InOut);
break;
case ValueOwnership::Shared:
wrapInput(Node::Kind::Shared);
break;
case ValueOwnership::Owned:
wrapInput(Node::Kind::Owned);
break;
}
inputs.push_back({input, flags.isVariadic()});
}
NodePointer totalInput = nullptr;
switch (inputs.size()) {
case 1: {
auto singleParam = inputs.front();
// If the sole unlabeled parameter has a non-tuple type, encode
// the parameter list as a single type.
if (!singleParam.second) {
auto singleType = singleParam.first;
if (singleType->getKind() == Node::Kind::Type)
singleType = singleType->getFirstChild();
if (singleType->getKind() != Node::Kind::Tuple) {
totalInput = singleParam.first;
break;
}
}
// Otherwise it requires a tuple wrapper.
LLVM_FALLTHROUGH;
}
// This covers both none and multiple parameters.
default:
auto tuple = Dem.createNode(Node::Kind::Tuple);
for (auto &input : inputs) {
NodePointer eltType;
bool isVariadic;
std::tie(eltType, isVariadic) = input;
// Tuple element := variadic-marker label? type
auto tupleElt = Dem.createNode(Node::Kind::TupleElement);
if (isVariadic)
tupleElt->addChild(Dem.createNode(Node::Kind::VariadicMarker), Dem);
if (eltType->getKind() == Node::Kind::Type) {
tupleElt->addChild(eltType, Dem);
} else {
auto type = Dem.createNode(Node::Kind::Type);
type->addChild(eltType, Dem);
tupleElt->addChild(type, Dem);
}
tuple->addChild(tupleElt, Dem);
}
totalInput = tuple;
break;
}
NodePointer parameters = Dem.createNode(Node::Kind::ArgumentTuple);
NodePointer paramType = Dem.createNode(Node::Kind::Type);
paramType->addChild(totalInput, Dem);
parameters->addChild(paramType, Dem);
NodePointer resultTy = _swift_buildDemanglingForMetadata(func->ResultType,
Dem);
NodePointer result = Dem.createNode(Node::Kind::ReturnType);
result->addChild(resultTy, Dem);
auto funcNode = Dem.createNode(kind);
if (func->throws())
funcNode->addChild(Dem.createNode(Node::Kind::ThrowsAnnotation), Dem);
funcNode->addChild(parameters, Dem);
funcNode->addChild(result, Dem);
return funcNode;
}
case MetadataKind::Metatype: {
auto metatype = static_cast<const MetatypeMetadata *>(type);
auto instance = _swift_buildDemanglingForMetadata(metatype->InstanceType,
Dem);
auto typeNode = Dem.createNode(Node::Kind::Type);
typeNode->addChild(instance, Dem);
auto node = Dem.createNode(Node::Kind::Metatype);
node->addChild(typeNode, Dem);
return node;
}
case MetadataKind::Tuple: {
auto tuple = static_cast<const TupleTypeMetadata *>(type);
const char *labels = tuple->Labels;
auto tupleNode = Dem.createNode(Node::Kind::Tuple);
for (unsigned i = 0, e = tuple->NumElements; i < e; ++i) {
auto elt = Dem.createNode(Node::Kind::TupleElement);
// Add a label child if applicable:
if (labels) {
// Look for the next space in the labels string.
if (const char *space = strchr(labels, ' ')) {
// If there is one, and the label isn't empty, add a label child.
if (labels != space) {
auto eltName =
Dem.createNode(Node::Kind::TupleElementName,
llvm::StringRef(labels, space - labels));
elt->addChild(eltName, Dem);
}
// Skip past the space.
labels = space + 1;
}
}
// Add the element type child.
auto eltType =
_swift_buildDemanglingForMetadata(tuple->getElement(i).Type, Dem);
if (eltType->getKind() == Node::Kind::Type) {
elt->addChild(eltType, Dem);
} else {
auto type = Dem.createNode(Node::Kind::Type);
type->addChild(eltType, Dem);
elt->addChild(type, Dem);
}
// Add the completed element to the tuple.
tupleNode->addChild(elt, Dem);
}
return tupleNode;
}
case MetadataKind::HeapLocalVariable:
case MetadataKind::HeapGenericLocalVariable:
case MetadataKind::ErrorObject:
break;
case MetadataKind::Opaque:
default: {
if (auto builtinType = _buildDemanglerForBuiltinType(type, Dem))
return builtinType;
// FIXME: Some opaque types do have manglings, but we don't have enough info
// to figure them out.
break;
}
}
// Not a type.
return nullptr;
}
// NB: This function is not used directly in the Swift codebase, but is
// exported for Xcode support and is used by the sanitizers. Please coordinate
// before changing.
char *swift_demangle(const char *mangledName,
size_t mangledNameLength,
char *outputBuffer,
size_t *outputBufferSize,
uint32_t flags) {
if (flags != 0) {
swift::fatalError(0, "Only 'flags' value of '0' is currently supported.");
}
if (outputBuffer != nullptr && outputBufferSize == nullptr) {
swift::fatalError(0, "'outputBuffer' is passed but the size is 'nullptr'.");
}
// Check if we are dealing with Swift mangled name, otherwise, don't try
// to demangle and send indication to the user.
if (!Demangle::isSwiftSymbol(mangledName))
return nullptr; // Not a mangled name
// Demangle the name.
auto options = Demangle::DemangleOptions();
options.DisplayDebuggerGeneratedModule = false;
auto result =
Demangle::demangleSymbolAsString(mangledName,
mangledNameLength,
options);
// If the output buffer is not provided, malloc memory ourselves.
if (outputBuffer == nullptr || *outputBufferSize == 0) {
return strdup(result.c_str());
}
// Indicate a failure if the result does not fit and will be truncated
// and set the required outputBufferSize.
if (*outputBufferSize < result.length() + 1) {
*outputBufferSize = result.length() + 1;
}
// Copy into the provided buffer.
_swift_strlcpy(outputBuffer, result.c_str(), *outputBufferSize);
return outputBuffer;
}



'{BE} Python 3.1x' 카테고리의 다른 글

텍스트를 이미지로 그려서 붙이기  (0) 2020.07.01
plist 읽기  (0) 2020.07.01
dropDown Menu  (2) 2020.07.01
UITabBar 크기 조정  (0) 2020.06.30
Making mater-detail app to hadle imageView  (0) 2020.06.23

https://github.com/AssistoLab/DropDown




        let lblDropDown : UILabel = {

            let ret = UILabel()

            ret.text = "drop down"

            ret.textColor = UIColor(hexColor: "9F9F9F")

            ret.lineBreakMode = .byClipping

            ret.sizeToFit()

            ret.isUserInteractionEnabled = true

            let tap = UITapGestureRecognizer(target: self, action: #selector(objDropDown))

            ret.addGestureRecognizer(tap)

            return ret

        }()

        

        self.bottomGroup.addSubview(lblDropDown)

        lblDropDown.snp.makeConstraints {

            $0.width.equalTo(40)

            $0.height.equalTo(40)

            $0.left.equalTo(lblSortBy.snp.right).offset(20)

        }



    @objc func objDropDown() {

        

        let dropDown = DropDown()

        // The view to which the drop down will appear on

        dropDown.anchorView = view // UIView or UIBarButtonItem

        

        // The list of items to display. Can be changed dynamically

        dropDown.dataSource = ["Car", "Motorcycle", "Truck"]

        

        // Action triggered on selection

        dropDown.selectionAction = { [unowned self] (index: Int, item: String) in

            print("Selected item: \(item) at index: \(index)")

        }

        

        dropDown.show()

    }

'{BE} Python 3.1x' 카테고리의 다른 글

plist 읽기  (0) 2020.07.01
nodepointer  (1) 2020.07.01
UITabBar 크기 조정  (0) 2020.06.30
Making mater-detail app to hadle imageView  (0) 2020.06.23
swift4 날짜 date 형식 formatting  (2) 2020.06.23

Snapkit 쓰면 편하지만, 그냥 해 보았다.




3가지 방법이 있다. 1번은 interface builder에서 수정하는 방법.

2번은 서브 뷰를 펼치기 전에 호출되는 viewWillLayoutSubviews 를 override 해서 그 안에 tabview 의 height를 변경하는 방법.

extension UITabBar {

        override open func sizeThatFits(_ size: CGSize) -> CGSize {

            print("HJH_sizeThatFits")

            return super.sizeThatFits(size)

        }

}

3번은 UITabBar의 sizeThatFits를 오버라이드 하는 방법이다.

1번은 스킵하고 2번과 3번의 호출은 다음과 같았다.


HJH_sizeThatFits

HJH_sizeThatFits

HJH_sizeThatFits

HJH_sizeThatFits

HJH_sizeThatFits

HJH_sizeThatFits

HJH_sizeThatFits

HJH_sizeThatFits

HJH_sizeThatFits

HJH_sizeThatFits

HJH_sizeThatFits

HJH_viewWillLayoutSubviews()

HJH_sizeThatFits

HJH_viewWillLayoutSubviews()

HJH_sizeThatFits


처음 그릴 때 많이 호출되고 이 후 탭 이동 시 마다 HJH_sizeThatFits이 2번씩 호출된다.


결국 viewWillLayoutSubviews를 override 하는 방법이 현명하겠다.


다음 3개 사이트의 코드가 필요하다.




var myDefaultFontSize:CGFloat = 26.0

switch UIDevice().type {

    case .iPhoneSE,.iPhone5,.iPhone5S: print("default value")

    case .iPhone6,.iPhone7,.iPhone8,.iPhone6S, .iPhoneX  : myDefaultFontSize += 4

    default:break

}


import UIKit


class DetailViewController: UIViewController {

    

    @IBOutlet weak var detailDescriptionLabel: UILabel!

    

    func configureView() {

        // Update the user interface for the detail item.

        if let detail = detailItem {

            detail.sizeToFit()

            self.view.addSubview(detail)

        }

    }

    

    override func viewDidLoad() {

        super.viewDidLoad()

        // Do any additional setup after loading the view, typically from a nib.

        configureView()

    }

    

    var detailItem: UIImageView? {

        didSet {

            // Update the view.

            configureView()

        }

    }

}


class MasterViewController: UITableViewController {

.

.

.

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

        if segue.identifier == "showDetail" {

            if let indexPath = tableView.indexPathForSelectedRow {

//                let object = objects[indexPath.row] as! NSDate

                let controller = (segue.destination asUINavigationController).topViewController asDetailViewController

                switch indexPath.row {

                case 0: controller.detailItem = UIImageView(image:  imageLiteral(resourceName: "tohip"))

                case 1: controller.detailItem = UIImageView(image:  imageLiteral(resourceName: "tomigum"))

                defaultbreak

                }

                controller.navigationItem.leftBarButtonItem = splitViewController?.displayModeButtonItem

                controller.navigationItem.leftItemsSupplementBackButton = true

            }

        }

    }


2018-12-13

let today = Date()

        let dateFormatter = DateFormatter()

        dateFormatter.dateFormat = "yyyy-MM-dd EE"

        dateFormatter.locale = Locale(identifier: "ko_KR")

        print(dateFormatter.string(from: today))


2018. 12. 13(목)

dateFormatter.dateFormat = "yyyy. MM. dd(EE)"


기타

  let df = DateFormatter()

//        df.dateFormat = "yyyy-MMMM"

        df.dateFormat = "yyyy. MM. dd(EE)"

        df.locale = Locale(identifier: "ko_KR")




7일전 날짜 저장


        let aWeekAgo : Double = Date().timeIntervalSince1970 - (7 * 60 * 60 * 24)

        GS.s.periodStartDate = Date(timeIntervalSince1970: aWeekAgo)


//----------------------


        let dt : Date = GS.s.periodStartDate ?? Date()

        let dateFormatter = DateFormatter()

        dateFormatter.timeZone = TimeZone(abbreviation: "KST")

        dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"

        dateLabel.text = dateFormatter.string(from: dt)


swift date to string

       let yourAttributes : [NSAttributedStringKey: Any] = [

            NSAttributedStringKey.font : UIFont(name: "".font1(), size: 14)!,

            NSAttributedStringKey.foregroundColor : UIColor.black,

            NSAttributedStringKey.underlineStyle : NSUnderlineStyle.styleNone.rawValue]

        

        let attributeString = NSMutableAttributedString(string: "TxtWhatYouWantToWrite",

                                                        attributes: yourAttributes)

        btn.setAttributedTitle(attributeString, for: .normal)

        btn.endEditing(false)


폰트 지정은 


import UIKit


//Where am I, exactly  ex) "".pwd(self)

extension String {

    func pwd(_ x: Any)  {

        if(!GS.s.logLevel.contains(.none)) {

            if x is String {

                print("🍭pwd_\(x)")

            } else {

                print("🍭pwd_", String(describing: x.self))

            }

        }

    }

    

    func pwdJustString(_ x: Any) -> String {

        return String(describing: x.self)

    }

    

    func font1() -> String {

        return "NanumSquareOTFR"

    }

    

    func font1L() -> String {

        return "NanumSquareOTFL"

    }

    

    func font1B() -> String {

        return "NanumSquareOTFB"

    }

    

    func font2() -> String {

        return "Pecita"

    }

}

'{BE} Python 3.1x' 카테고리의 다른 글

Making mater-detail app to hadle imageView  (0) 2020.06.23
swift4 날짜 date 형식 formatting  (2) 2020.06.23
Alamofire SwiftyJSON  (0) 2020.06.23
log 출력  (0) 2020.06.23
SwiftMessages 사용법  (0) 2020.06.23

import UIKit

import Alamofire

import SwiftyJSON


class ViewController: UIViewController {

    

    let urlString: String = "https://yoursite.com"

    let token: String = "/yourTokenAPI"

    let login: String = "/yourLoginAPI"

    let testUserName: String = "hajunho"

    let testPassword: String = "sorasorapululunsora"

    let json1level = "data"

    let json2level = "token"

    

    var count: Int = 0

    

    override func viewDidLoad() {

        super.viewDidLoad()

        // Do any additional setup after loading the view, typically from a nib.

        getLoginToken()

    }

    

    func connectionTest(_ site: String, auth: Bool) {

        Alamofire.request(site)

            .validate(statusCode: 200..<300)

            .validate(contentType: ["application/json"])

            .responseData { response in

                switch response.result {

                case .success:

                    print("Validation Successful \(self.count)")

                case .failure(let error):

                    if(auth) {

                        print("Authentication is needed for Validation "self.count)

                    }

                    else {

                        assertionFailure()

                        print("Valication is Failed."self.count, error)

                    }

                }

        }

    }

    

    func getLoginToken() {

        let parameters: Parameters = ["username"testUserName,

                                      "password"testPassword]

        

        connectionTest(urlString+login, auth: true)

        

        Alamofire.request(urlString+token, parameters: parameters).responseJSON { response in

            if(false) {

                print("Request: \(String(describing: response.request))"  // original url request

                print("Response: \(String(describing: response.response))"// http url response

                print("Result: \(response.result)"                        // response serialization result

                if let data = response.datalet utf8Text = String(data: data, encoding: .utf8) {

                    print("Data: \(utf8Text)"// original server data as UTF8 string

                }

            }

            

            if let json = response.result.value {

                if(false) {

                    print("JSON: \(json)"// serialized json response

                }

                

                let swiftyJsonVar = JSON(json)

                let resToken = swiftyJsonVar[self.json1level][self.json2level].stringValue //KEYPOINT!!

                print(resToken)

                

            }

        }

    }

}



- singleton, 프로젝트 전역에서 사용 가능

GlobalSettings.shared.logLevel.contains(.all) 

- log level 나누기 가능

logLevel = .graphPanel

if GlobalSettings.shared.logLevel.contains(.graph2) { print("blah, blah") }

- 편리한 현재 위치 찍기

"".pwd(self)



import UIKit


//Where am I, exactly 

extension String {

    func pwd(_ x: Any)  {

        print("pwd_", String(describing: x.self))

    }

}


struct _logLevel: OptionSet {

    let rawValue: Int


    static let critical    = _logLevel(rawValue: 1 << 0)

    static let major  = _logLevel(rawValue: 1 << 1)

    static let minor   = _logLevel(rawValue: 1 << 2)

    static let just   = _logLevel(rawValue: 1 << 3)

    static let graph = _logLevel(rawValue: 1 << 4)

    static let graph2 = _logLevel(rawValue: 1 << 5)

    static let graphPanel = _logLevel(rawValue: 1 << 6)

    static let all: _logLevel = [.critical, .major, .minor, .just, .graph, .graph2, .graphPanel]

}


class GlobalSettings {

    var logLevel : _logLevel


    private init() {

//        logLevel = .all

//        logLevel = .critical

           logLevel = .graphPanel

//        logLevel = .just

    }


    static let shared = GlobalSettings()

}



xib 하나 만듦. 비어있는 View 추가

File Inspector 탭에서 Use Safe Area Layout Guides 해제

Simulated Metrics에서 Size를 Freeform 으로 변경

Size Inspector 탭에서 600, 309 로 width, height 변경

내부에 view 추가(Background view)

Background view 내부에 stack view 추가(Content view)


        btnQuestionMark.addTarget(self, action: #selector(btnQuestionmark), for: .touchUpInside)



@IBAction func btnQuestionmark() {

        let view: BottomDialogView = try! SwiftMessages.viewFromNib()

        view.configureDropShadow()

        view.cancelAction = { SwiftMessages.hide() }

        var config = SwiftMessages.defaultConfig

        config.presentationContext = .window(windowLevel: UIWindowLevelStatusBar)

        config.duration = .forever

        config.presentationStyle = .bottom

        config.dimMode = .gray(interactive: true)

        SwiftMessages.show(config: config, view: view)

    }


주의할 점 : Interface Builder 에서 Ctrl+C, V로 생성된 박스는 인식 안됨.



'{BE} Python 3.1x' 카테고리의 다른 글

Alamofire SwiftyJSON  (0) 2020.06.23
log 출력  (0) 2020.06.23
swift free book pdf  (0) 2020.06.23
swift 4.2에서 잘되는 background timer  (0) 2020.06.23
swift badge  (0) 2020.06.23

'{BE} Python 3.1x' 카테고리의 다른 글

log 출력  (0) 2020.06.23
SwiftMessages 사용법  (0) 2020.06.23
swift 4.2에서 잘되는 background timer  (0) 2020.06.23
swift badge  (0) 2020.06.23
pyCharm 세팅  (0) 2020.06.23

좌표는

https://github.com/yethafiz/BackgroundTimer


스냅샷은

BackgroundTimer.zip


앱 백그라운드 상태에서 시간이 디버그 로그로  잘 찍힌다.


https://github.com/rafaelcpalmeida/Countdowner 얘도 같은 API + 화면 제어 추가



'{BE} Python 3.1x' 카테고리의 다른 글

SwiftMessages 사용법  (0) 2020.06.23
swift free book pdf  (0) 2020.06.23
swift badge  (0) 2020.06.23
pyCharm 세팅  (0) 2020.06.23
티스토리 카테고리 크롱크롱  (0) 2020.06.23

스위프트 배지 라이브러리 주소

https://github.com/evgenyneu/swift-badge


Demo-iOS 에 CreateBadgeFromCodeViewController 참조


    lazy var mBadge : UIView = {

        let real = UIView()

        let ret = BadgeSwift()

        real.addSubview(ret)

        self.configureBadge(ret)

        self.positionBadge(ret, view: real)

        return real

    }()


real이랰ㅋㅋㅋ 나도 참.

'{BE} Python 3.1x' 카테고리의 다른 글

swift free book pdf  (0) 2020.06.23
swift 4.2에서 잘되는 background timer  (0) 2020.06.23
pyCharm 세팅  (0) 2020.06.23
티스토리 카테고리 크롱크롱  (0) 2020.06.23
p001- nltk  (0) 2020.06.21

+ Recent posts