반응형

 턴 테이블을 구매하기 앞서 최소한의 조건이 있습니다. 바로 LP를 손상시키지 않고, LP 본연의 음질을 살릴 수 있으며, 유지 보수를 할 수 있어야 된다는 것입니다. 아래는 이 목표를 만족할 수 있는 최소 조건을 정리해 봤습니다.

 

1. 바늘이 분리가 된다.

    사용하다 보면 바늘을 교체해 줘야 되는 시기가 온다. 이때를 위해 바늘을 분리해 교체할 수 있어야 된다.

2. 턴테이블 톤암에 무게추가 있어야 된다.

    지나친 침압은 LP판을 손상시킬 수 있다. 따라서, 톤암 뒤에 무게추가 있어 적당한 침압을 줄 수 있어야 된다.

3. 매트가 충분히 커 LP를 잘 지지할 수 있어야 된다.

    매트가 지나치게 작을 경우 LP를 잘 지지하지 못해 중간에 LP가 흔들려 바늘이 튈 수 있다.

4. 스피커가 별도로 분리가 가능해야 된다.

    스피커가 턴테이블에 내장되어 있을 경우 스피커에서 발생하는 진동이 턴테이블에 영향을 주어 LP의 음질에 영향을 끼칠 수 있다.

5. 뚜껑이 있어야 된다.

    위와 같은 맥락으로 뚜껑이 있어야 LP가 안정적으로 회전할 수 있다.

 

 위 조건을 참고해서 현명하게 입문용 턴테이블을 구매하시기 바랍니다 :)

반응형
반응형

1. 마운트 패키지 설치

sudo apt-get install cifs-utils

2. 마운트 하기 위한 폴더 생성

마운트 폴더로 지정하고 싶은 원하는 경로에 폴더를 생성한다. 예시의 경우 /mnt 폴더에 nas1이라는 폴더를 생성한 것이다. 보통 저장 장치를 마운트 할 때 /mnt 폴더에 많이 하고, 다른 유저도 볼 수 있어 보통   /mnt 폴더 안에 폴더를 만든다.

mkdir /mnt/nas1

3. 마운트 연결

이제 생성된 폴더에 nas를 마운트 해준다.

sudo mount -t cifs //{NAS IP}/{NAS directory path} {local path} -o user='NAS ID',password='NAS PW',rw,vers=2.0
    1. NAS IP : 나스 접근 IP: 111.11.11.111
    2. NAS ID: NAS 접근 아이디 : admin
    3. NAS PASSWORD: NAS 접근 비밀번호 : admin
    4. NAS directory path: 나스 디렉토리 경로 : /home
    5. local path : 마운트할 우분투 내 local 경로 : /mnt/nas1

예시)

sudo mount -t cifs //111.11.11.111/home /mnt/nas-drive -o user='admin',password='admin',rw,vers=1.0

4. 부팅시 마운트 자동 연결

sudo vi /etc/fstab

# 하단에 아래 코드 추가
//{NAS IP}/ {NAS directory path} /{local path} cifs user={NAS ID},password={NAS PASSWORD},rw,vers=2.0 0 0

 

  1. NAS IP : 나스 접근 IP: 111.11.11.111
  2. NAS ID: NAS 접근 아이디 : admin
  3. NAS PASSWORD: NAS 접근 비밀번호 : admin
  4. NAS directory path: 나스 디렉토리 경로 : /home
  5. local path : 마운트할 우분투 내 local 경로 : /mnt/nas1

예시)

//111.11.11.111/home /mnt/nas1 cifs user=admin,password=admin,rw,vers=2.0 0 0

 

참고

cifs 뒤와 0 0 사이에는 스페이스나 tab등의 공백이 있으면 안 된다. 예를들어 //111.11.11.111/home /mnt/nas1 cifs user=admin, password=admin,    rw, vers=2.0 0 0가 있다.

 

+ 자동 마운트 안 되는 오류

가끔씩 네트워크가 연결되기 전 나스가 연결을 시도해서 부팅 이후에도 자동으로 마운트가 되지 않는 경우가 있다. 아래의 코드를 실행시키고 비밀번호를 쳐도 마운트가 안 되어있다면, 자동 마운트가 안 되는 상태이다.

sudo mount -a

 이 경우엔 옵션으로 x-systemd.automount를 추가해준다.

예시)

//111.11.11.111/home /mnt/nas1 cifs user=admin,password=admin,rw,vers=2.0,x-systemd.automount 0 0
반응형
반응형

아나콘다 공식 홈페이지에서 리눅스용 .sh 형식의 anaconda 파일 설치한다.

 

*이전 버전 아나콘다 모음 링크

 

Index of /

Anaconda-1.5.0-Linux-x86.sh 238.8M 2013-05-08 09:18:43 ca7e356dc1b8c8ef27dfb74b32c77563df704c6ddb39e69cac65ec416ebfe8e5

repo.anaconda.com

 

💡우분투 Anaconda 설치 관련 내용을 검색해보면 wget을 이용하는 방법도 존재하는데요, 이 경우 최신 버전이 아닐 수 있어 공식 홈페이지에서 직접 설치하는 것을 권장합니다.

 

anaconda 파일 다운로드 후, 다운로드 경로로 이동해 아래의 코드를 실행시켜 아나콘다를 설치한다. (버전으로 들어가는 숫자는 다운 버전에 따라 달라질 수 있다.)

~/다운로드$ bash Anaconda3-2023.03-1-Linux-x86_64.sh

이후 수많은 enter키를 누르고(가급적 엔터말고 page down 또는 ctrl + c로 한 번에 넘어가자) yes를 누르면 설치가 진행된다.(terminal의 안내를 따르면 된다.)

  - 최신 아나콘다 설치 시 “~~automatically initialize conda?” 라는 질문과 여러 말들과 함께 한 번 더 [yes/no]를 묻는 질문이 나올경우 yes를 누른다.

 

가상환경 설정

source ~/.bashrc를 실행하면

(base) 사용자명@user:~$ 가 된다.

base가 떠야만 정상적으로 설치가 된 것이므로 확인해보고 뜨지 않는다면 검색해서 해결한다. 도저히 안되면 재설치한다.(확인을 위해 터미널을 껐다가 다시 켜보자)

이후 terminal에 접속하면 곧바로 (base) 사용자명@user:~$로 시작될 수 있다. 이는 기본 설정이 가상환경 activated된 상태이므로 이를 해제해준 상태로 사용해야한다.

$ conda config --set auto_activate_base false

이후 다시 터미널 껐다가 켜면 이젠 (base)가 뜨지 않는다.(deactivate 완료)

 

conda 가상환경 생성 관련 참고 링크

 

Anaconda에서 가상환경 만들기(초심자용)

※ 일본의 한 블로그 글을 번역한 포스트입니다. 오역 및 의역, 직역이 있을 수 있으며 틀린 내용은 지적해주시면 감사하겠습니다. 가상환경 1. 환경이란? 환경이란 python 버전, 설치되어 있는 라

engineer-mole.tistory.com

 

반응형
반응형

우분투 USB 설치

 

우분투(Ubuntu) 설치 USB 만들기

Ubuntu 22.04 Jammy Jellyfish 가 배포되었습니다. Ubuntu 20.04를 사용중인데 22.04로 업그레이드 하려면 어떻게 할까요? 첫번째는 사용하면서 최신 버전으로 업그레이드 하는 방법이 있을 테고, 하나는 설

dulidungsil.tistory.com

 

최초 설치 시 언어는 반드시 English로 한다.

초기 설치 완료 후 설정에서 언어를 Korean으로 변경한 후 나오는 창이 있다.

“현재 언어로 표준 폴더의 이름을 업데이트 하시겠습니까?”

여기에서 예전 이름 유지를 누르면 된다.

이 방식으로 진행해야 폴더명이 한글로 바뀌지 않는다.

우분투 버전 확인

$ lsb_release -a
$ hostnamectl(root 계정 아니어도 사용가능)
$ uname -m && cat /etc/*release (가장 자세함)

우분투 기본 설정

>한글/영어 설정

처음 계정을 만들면 한글이 안 쳐진다. 우측 상단의 한/영을 눌러 다른 ‘한글’을 선택하면 한/영 전환이 가능해진다.

 

[Linux][VMware] 우분투 20.04 LTS 한글 입력기 설치

1. 우분투 업데이트 다음 명령어를 순서대로 터미널에 입력 합니다. sudo apt-get update sudo apt-get upgrade 2. 영어 -> 한글 변경 / 한글 설치 방법 왼쪽 하단의 메뉴를 클릭한 뒤 "setting"을 검색해서 실행

lonaru-burnout.tistory.com

 

Ubuntu 22.04 기준 설명

설정-키보드-입력소스-한국어(Hangul)-기본설정-한영전환키-추가-’우측 Alt 키’ 누르고 등록-’한국어(Hangul)’을 ‘한국어’ 위로 올림-테스트 해보기

(반드시 Hangul이 적혀 있는 한국어를 사용해야 한다.)

만약 ‘한국어(Hangul)’ 이 보이지 않는다면 세팅에서 ‘지역 및 언어’를 들어가 Korean으로 다시 바꾸고 reboot하면 ‘한국어(Hangul)’이 보일 것이다.

 

 

반응형
반응형

2563번 문제는 2차원 배열 문제입니다.

 

단순히 배열을 처리하는 문제라 풀이 과정 자체는 안 어려운데요.

import sys

paper = [[0]*100]*100
input = sys.stdin.readline

for _ in range(int(input().rstrip())):
    a, b = map(int, input().split())
    for _ in range(a, a+10):
        for __ in range(90-b, 100-b):
            paper[_][__] = 1
area = 0
for _ in range(100):
    for __ in range(100):
        if paper[_][__] == 1:
            area += 1
print(area)

 

예제 입력 1을 넣어봤는데, 계속 지나치게 큰 output이 나오더라고요.

그래서 코드를 다시 쭉 복기했더니 paper = [[0]*100]*100 부분을 shallow copy로 생성했더라고요.

 

즉, [[0]*100]*100이 모두 [[0]*100]을 참조하게 되어 해당 리스트의 값이 하나라도 밖이면 전부 같이 바뀌게 됩니다.

 

예를 들어,

paper = [[0]*5]*5
paper[0][0] = 1
print(paper)

를 쓰게 되면

[[1, 0, 0, 0, 0], [1, 0, 0, 0, 0], [1, 0, 0, 0, 0], [1, 0, 0, 0, 0], [1, 0, 0, 0, 0]]로 모든 행의 첫 번째 열이 1로 변하게 됩니다.

 

따라서, 이를 방지하기 위해선 처음 리스트를 생성할 때 리스트 컴프리헨션을 사용해야 합니다.

paper = []

for _ in range(100):
    paper.append([0]*100)
    
#########################################
paper = [[0]*100 for _ in range(100)]

이러면 각 내부 리스트가 독립적인 객체로 생성되기 때문에 얕은 복사 문제를 피할 수 있습니다.

여기에 맞게 코드를 수정하면 다음과 같습니다.

import sys

paper = [[0]*100 for _ in range(100)]
input = sys.stdin.readline

for _ in range(int(input().rstrip())):
    a, b = map(int, input().split())
    for _ in range(a, a+10):
        for __ in range(90-b, 100-b):
            paper[_][__] = 1
area = 0
for _ in range(100):
    for __ in range(100):
        if paper[_][__] == 1:
            area += 1
print(area)

결과는

입니다.

 

 

 

 

 

 

 

 

 

 

오늘의 교훈

리스트를 복사하거나 생성할 땐 shallow copy와 deep copy를 잘 구분하자.

 

 

 

 

 

 

 

 

 

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

+a

 컴프리헨션(comprehension)이라고 인터넷에 검색하면 이해력이라는 뜻이 나오는데요. 리스트 컴프리헨션(list comprehension)을 단순히 리스트 이해력이라는 생각 하면 좀 이상합니다. 또 리스트 표현식이라는 표현도 쓰긴 하는데 expression이랑은 단어가 달라서 의미가 미묘하게 다른 것 같습니다. 그래서 어원사전에서 comprehension을 찾아봤는데요.

 내용을 정리해 보면 통합하다는 뜻이 가장 가까워 보이고요. 여기에 맞게 해석하면 여러 줄로 정의되는 반복문을 한 줄로 통합한다라는 뜻인 것 같습니다. 리스트 반복통합식(?)이라고 해야 되나, 정확히 한글식 표현으론 뭘 써야 될지는 모르겠네요. 혹시 괜찮은 표현 있으면 댓글 부탁드립니다.

 

 

참고 사이트

comprehension 어원 사전 사이트

 

comprehension | Search Online Etymology Dictionary

The online etymology dictionary (etymonline) is the internet's go-to source for quick and reliable accounts of the origin and history of English words, phrases, and idioms. It is professional enough to satisfy academic standards, but accessible enough to b

www.etymonline.com

python list comprehension 설명 사이트

 

1) 리스트 컴프리헨션

## 리스트 생성하기 기존에 배운 문법으로 1부터 10까지 정수를 순서대로 가지고 있는 리스트를 생성하는코드는 다음과 같습니다. ``` numbers = [] for n i…

wikidocs.net

 

반응형

'백준 > 오답노트' 카테고리의 다른 글

[백준 오답노트] 1152번 split(' ')과 split()의 차이  (0) 2024.11.05
반응형

문제 1152

 

 오늘의 오답 노트는 1152번입니다.

 간단하게 문장 내의 단어의 개수를 출력하는 문제로 굉장히 쉬워보이는 문제인데요.

 하지만 정답 비율은 무려 33.223%. 무언가 함정이 있다는 것을 알아버렸습니다.

 자세히 마저 읽다보니, 예제 입력에 처음공백이 추가적으로 들어갈 수 있다는 것을 알아버렸습니다. 예제 입력 2를 보면 다른 출력과 다르게 앞에 공백이 있습니다. 예제 입력 3은 맨 뒤에 공백이 있구요.

 

 따라서 저는 sys.stdin.readline().strip()을 통해 양 끝의 공백과 엔터를 지워주고, split(' ')을 통해 공백으로 단어를 구분해주기로 했습니다.

import sys

input = lambda:sys.stdin.readline().strip()
print(len(input().split(' ')))

 하지만 결과는 틀렸습니다....

그래서 split() 공식문서를 좀 더 찾아보니

라고 하더군요.

 

즉 split()과 split(' ')는 다르다는 겁니다.

 split()같은 경우는 공백이 연속적으로 있는 것과 상관 없이 안에 있는 값만을 리스트의 요소로 넣어서 반환하고요.

 split(' ')의 경우는 중간에 값이 없으면 ''(공백) 자체가 리스트의 요소로 넣어져서 반환됩니다.

 

따라서, 제가 만든 코드는 공백만 입력으로 들어오면 0을 반환해야되는데 1을 반환해서 틀렸다는 것을 알아버렸습니다.

 

이제 문제를 파악했으니 해결해봅시다.

split()을 쓰면 " 공백이 연속적으로 있는 것과 상관 없이 안에 있는 값만을 리스트의 요소로 넣어서 반환한다."는 특성을 활용해 기존의 strip()과 split(' ') 대신에 split()만을 사용해 간단하게 코드를 작성할 수 있습니다.

import sys

print(len(sys.stdin.readline().split()))

sys.stdin.readline()을 통해 입력을 읽어주고요.

.split()을 통해 문자열을 단어 단위로 나눠서 list로 반환해줍니다.

마지막으로 len을 통해 해당 리스트의 개수를 반환합니다.

 

 

 

결과는,

성공!

 

 

오늘의 교훈

공식 문서를 정독하자.

 

 

참고 자료

https://docs.python.org/ko/3/library/stdtypes.html#str.split

 

반응형
반응형

uvicorn을 통해 websocket을 테스트 하던 중 처음 보는 오류를 발견했다.

찾아보니 app registry가 준비되기 전에 특정 라이브러리가 import 되어 발생하는 오류였고, 처음 import 한 부분을 찾아가니 나의 경우는 처음에 asgi.py를 잘못 작성해서 생긴 문제였다.

 

오류가 생긴 asgi.py 코드는

import os

from django.core.asgi import get_asgi_application
from channels.routing import ProtocolTypeRouter, URLRouter
from channels.auth import AuthMiddlewareStack
from accounts import routing

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'backend.settings')

application = ProtocolTypeRouter({
    "http": get_asgi_application(),
    "websocket": AuthMiddlewareStack(
        URLRouter(
            routing.websocket_urlpatterns
        )
    ),
})

로 django_asgi_app = get_asgi_application() 부분이 routing이 auth 보다 뒤에 나오는 상황이었다.

 

 

오류 코드를 자세히 찾아보니 routing 부분에서 consumer를 불러오고 consumer에서 rest_framework_simplejwt.tokens을 불러오는 부분에서 문제가 발생했고, app registry가 준비되기 전 해당 부분을 불러와서 발생한 오류임을 확인했다.

 

즉, get_asgi_application으로 app registry가 준비되기 전, routing에서 사용된 라이브러리 중 rest_framework_simplejwt.tokens.AccessToken이 먼저 불러와져 발생하는 오류였다.

 

 

간단하게 아래와 같이 코드 순서를 바꿔주어 오류를 수정하였다.

import os

from django.core.asgi import get_asgi_application
from channels.routing import ProtocolTypeRouter, URLRouter

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'backend.settings')
django_asgi_app = get_asgi_application()

from channels.auth import AuthMiddlewareStack
from accounts import routing

application = ProtocolTypeRouter({
    "http": django_asgi_app,
    "websocket": AuthMiddlewareStack(
        URLRouter(
            routing.websocket_urlpatterns
        )
    ),
})

 

결과적으로 잘 작동하는 것을 확인했다.

반응형

'BackEnd > django' 카테고리의 다른 글

[django] LocMemCache 배포 시 문제점  (0) 2024.09.01
반응형

오류 확인 배경

 django를 배포하고 프런트와 합치면서 테스트하는 과정에서 신기한 현상을 발견했다. 임시로 접속할 수 있는 페이지를 만들기 위해 local memory cache를 사용해 권한을 확인하고 있었고 해당 페이지 테스트하고 있었다.  

 

 그런데 페이지를 새로고침 할 때마다 인증이 잘 될 때도 있고 안 될 때도 있는 것이다. 정확히는 서버 cache에 쿠키의 cache가 없어서 권한이 없다는 경우와 정상적으로 있어서 잘 동작하는 경우, 이 두 경우가 새로고침 할 때마다 랜덤으로 반복되었다. 보통 동작이 되면 되고 아니면 아닌데 어떻게 새로고침할 때마다 랜덤으로 오류가 발생하는일이 벌어지는 걸까?

 

왜 이런 일이 벌어진 걸까?

 LocMemCache는 django를 동작하는 프로세스의 메모리에만 접근이 가능하다. 따라서 하나의 프로세스에선 문제가 없고 당연히 테스트 환경에서도 문제가 없다.

 

 하지만 우리가 배포하는 환경은 다르다. 보통 django를 배포할 때 gunicorn으로 worker를 1이상으로 세팅하여 배포하게 된다, 이러면 worker마다 mem이 다르기 때문에 cache가 있는 worker에서만 정상 작동하게 되는 문제가 발생한다.

 

마치 슈뢰딩거의 cache 랄까?

 

따라서 LocMemCache를 쓰지 말고 db cache를 사용하도록 하자. 

 

db cache로 변경하기

 먼저 cache 세팅을 변경해준다

# settings.py
CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.db.DatabaseCache',
        'LOCATION': 'my_cache_table',
    }
}

 

 그 다음 terminal에서 캐시 db 테이블을 생성해준다.

python manage.py createcachetable

 

반응형

+ Recent posts