I cna’t believe : 어? 어떻게 이렇게 됐지? I can’t beleive I’m a senior citizen now. I can’t believe I’m already a senior citizen. It’s already 10 year anniversery.
It’s already 5:30 p.m. 벌써 5시 반이야?
I’m a little ealry for my doctor’s appointment : 약간 일찍 왔네 You’re a little early 10분? You’re really early 1시간 이상? No no no, You’re fine. I arrived early. / I’m a little early.
I arrived just in time for the meeting. just in time: 거의 늦을 뻔 했는데, 늦기 바로 직전에 온 것. in time: 제 시간에. 그 시간까지. 좀 전에 와도 in time. on time: 딱 그 시간.
I got on my flight just in time. Is it already 4 o’clock? Time is flying today! It’s a little bit early for me to go to bed. He showed up just in time. I’m so sleepy. It’s already 11 p.m. It is a little early for me to make dinner.
It is just the right weather for ~하기 딱 좋은 날씨군! It is just the right weather for hiking. It is just the right temperature for는 약간 어색.
On sultry days like this, I wish I could stay home and do nothing sultry는 덥고 습한. 그러나 섹시하다 야하다 같은 뜻도 있음. 따라서 sultry eyes, sultry women 같은 건 다른 뜻. sultry night 같은 말은 약간 섹시한 뉘앙스가 있음. 비슷한 단어로 muggy는 후덥지근한.
It’s a little chilly today, but not as bad as yesterday 오늘도 좀 쌀쌀한데, 어제보단 낫네. chilly는 완전히 추운건 아니고 쌀쌀하다. chilly < nippy < cold. nippy는 좀더 춥고 건조한, 약간 꼬집는? 뉘앙스.
It’s boling today, but not as bsd as yesterday. Yay, it’s the perfect weather for going outside. The only thing that cheers me up on sultry days like this is beer. It’s humid today, but not as bad as yesterday. It’s not the right weather for me to sleep. On sultry days like this, my back gets sweaty.
웹페이지 내에 오디오를 넣고 싶을 때는 audio element로 넣을 수 있다. src attribute 혹은 source element로 하나의 오디오 소스를 가지거나 audio element의 children으로 source element 리스트를 넣어서 여러개의 오디오 소스를 가질 수 있다.
<audio controls src="media/dasomoli.mp3">여러분의 브라우저가 audio 태그를 지원하지 않는 것 같네요..</audio>
위처럼 <audio>와 </audio> 사이에 브라우저가 지원하지 않을 때 나타낼 메시지를 넣을 수 있다. controls attribute는 여러분이 오디오를 재생할 수 있도록 할 수 있다. 다음과 같은 contol이 나타난다.
다음과 같은 속성들이 있다.
autoplay (boolean)
preload (none / metadata / auto)
loop (boolean)
controls
autoplay는 전부 다운로드 받지 않더라도 재생이 가능할만큼만 되면 바로 재생한다. 사람들이 웹페이지에 들어왔을 때 오디오가 바로 재생되면 싫어하므로 사용에 주의하라.
preload는 미디어 소스의 로딩을 어떻게 할지를 정하고 싶을 때 사용한다. none은 preload하지 않고, metadata는 metadata만 로드한다. auto는 empty string(“”)과 동등한데, 전체 파일이 로드된다.
loop는 반복 재생하도록 한다.
controls는 브라우저의 기본 미디어 컨트롤을 추가한다. 사용자가 오디오의 재생을 제어할 수 있다. 브라우저마다 UI가 다른데, 공통적인 기능은 비슷하다. UI가 다르므로 controls attribute를 셋팅하지 않고 HTML, CSS, Javascript를 사용해서 customize한 control을 생성, 원하는 디자인을 할 수도 있다.
webm, mp3, ogg등 브라우저마다 지원하는 format이 다르다. 이에 대해서는 MDN의 다음 글을 참고하자.
여러개의 source를 넣고 싶을 때는 source element를 이용한다. src attribute를 사용하지 않고 여러개의 source를 사용했음에 주목하라. 이 중 지원하지 않는 format이 있으면 다음 것을 시도한다.
<audio controls>
<source src="media/dasomoli.webm" type="audio/webm">
<source src="media/dasomoli.mp3" type="audio/mp3">
<source src="media/dasomoli.ogg" type="audio/ogg">
여러분의 브라우저가 <code>audio</code>를 지원하지 않는 것 같아요!
</audio>
동영상 (Video)
video element와 audio element는 둘 모두 HTML media elements이다. 사실 video element로 audio를, audio element로 video를 재생하는 것도 가능하다. video element는 display 영역을 제공한다는 것이 차이이다.
video element의 attribute는 audio element 것을 모두 가진다. 추가로 다음 attribute를 제공한다:
height
width
poster
width와 height attribute는 video display area의 width와 height을 각각 조정한다. 둘 모두 pixel로 조정된다. %로 비율을 쓸 수 없다.
poster attribute는 video가 다운로드되는 동안 보여줄 이미지를 지정한다. 지정하지 않으면 video의 첫 frame의 다운로드 전에는 빈 네모가 보이고, 첫 frame을 다운로드 받으면 그 첫 frame이 보일 것이다.
Text track
track element는 media element와 연관된 시간 기준의 글을 지정한다. 이는 미디어 재생과 싱크가 맞는 시간에 어떤 글을 보여줄 수 있다는 뜻이다. 자막이나 해당 미디어에 대한 설명은 물론, 앞이 안보이거나 소리가 안들리는 사람들에게도 어떤 것인지 설명할 수 있도록 해준다.
video의 source element와 같이 하나의 media element 에 여러개의 track element를 넣어서 그 media에 대한 여러 track을, 예를 들면 다른 언어 자막 같은 식으로 제공할 수 있다.
track element의 attribute는 다음과 같다:
src: text track file의 위치
default: media element 당 하나의 track element가 default track으로 지정될 수 있다. 사용자 설정에 따라 override될 수 있다.
kind: text track이 무엇으로 사용되는지를 지정한다. subtitles, captions, descriptions, chapters, metadata같은 여러 옵션이 있다. default는 subtitles이다.
위에서 source element는 media attribute를 갖는다. 위 코드는 첫번째 것부터 media attribute가 참인지를 보고 맞다면, 위 코드에서는 viewport가 639 픽셀 이하인지를 보고 맞다면 해당 이미지를 보여준다. 아니라면 다음 것으로 넘어간다. 다 안맞으면 마지막의 img의 것을 보여주게 된다. 브라우저가 picture를 지원하지 않을 때도 picture의 가장 마지막 것을 보여주게 된다.
조건으로 media 외에도 type attribute나 mime type도 사용할 수 있다.
위의 .jpeg, .gif, .png, .webp 같은 foramt외에도 SVG (Scalable vector graphics)나 canvas element 처럼 프로그래밍한 그래픽을 생성할 수 있다. SVG는 vector graphics를 위한 XML 기반의 format이고, canvas element는 웹페이지 상에서 rasterized graphics를 생성하는데 사용되는 JavaScript drawing API로 접근 할 수 있는 element다.
svg element
svg는 vector graphics를 정의하는 XML 기반 format이다. Vector graphics는 깨지는 문제없이 비율에 따라 계산되기 때문에 반응형 웹에 매우 유용하다. 간단한 예로 play와 stop button을 만든다고 하자.
viewBox attribute로 x좌표 0, y좌표 0에서 100 dimension으로 설정했다. viewBox는 pixel로 표시하지 않는다. width와 height attribute로 비율을 정할 수 있다. 안에 들어가는 children들은 viewBox의 상대적 위치에 놓이게 된다.
circle element로 x좌표 50, y좌표 50의 위치에 반지름 50짜리 원을 그렸고, 안을 black으로 채웠다. hex value #rrggbb로도 당연히 설정 가능하다. 그 후 path로 3점을 정해서 삼각형을 하나 그리고 이를 white로 채웠다. 비슷하게 stop 버튼은 사각형을 하나 그리고 이를 white로 채웠다. 위 소스는 다음과 같이 렌더링된다.
svg는 canvas처럼 javaScript가 필요하지 않고 바로 접근 가능하지만, shape들이 많으면 성능 문제가 일어날 수 있다.
canvas Element
canvas element로는 rasterized graphics를 렌더링할 수 있다. 이를 위해서 JavaScript의 drawing API를 사용한다. 2D와 WebGL의 두가지 렌더링 모드가 있다. WebGL은 GPU acceleration과 같은 shader support를 제공한다.
browser가 canvas를 지원하는지를 확인한 후 이용하는 것이 좋다. 확인하는 코드는 다음과 같이 쓸 수 있다.
moveTo(x, y) 로 옮기고, lineTo(x, y) 로 경로를 정한 후, strokeStyle을 정한 후 stroke()로 외곽선을 그린다. lineTo로 이어서 그린 후 해당 경로를 fillStyle로 정한 후 fill()로 채울 수도 있다.
사각형(Rectangle) 그리기
속이 빈 사각형을 외곽선 만으로 그리고 싶으면, strokeStyle로 외곽선의 style을 정하고, lineWidth로 외곽선 굵기를 정한 후, strokeRect(x, y, width, height)로 그린다.
안이 채워진 사각형을 그리고 싶으면 fillStyle로 style을 정하고, fillRect(x, y, width, height)로 그린다. fillStyle은 CSS에서 사용하는 값이면 다 쓸 수 있다. color, backgroundColor같은 property나 black, red, white 같은 color값, hex value #rrggbb나, rgba(25, 35, 45, 0.7) 같은 rgba 값도 가능하다.
외곽선과 안이 채워진 것을 모두 적용하고 싶다면, strokeStyle과 fillStyle을 모두 설정하고, rect(x, y, width, height)로 사각형 경로를 설정하고, fill()로 채우고, stroke()로 외곽선을 그리면 된다.
from selenium import webdriver
driver = webdriver.Firefox()
driver.get("blog.dasomoli.org")
페이지를 열고 난 후 기다리기
어느 페이지를 열고 난 후 동작을 시작하려면 해당 페이지가 열렸을 때 나타나는 element를 기다려서 동작을 시작해야 한다. link text라면 다음과 같은 식으로 기다릴 수 있다. 아래에서 20은 20초를 의미한다. 첫번째 인자가 괄호로 둘러싸여 있음에 유의하라.
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
element = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.LINK_TEXT, "Ult-Build-1")))
다음처럼 어느 태그가 나타나길 기다릴 수도 있다.
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
element = WebDriverWait(driver, 10).until(EC.text_to_be_present_in_element((By.TAG_NAME, "h1"), "Project INTEGRATED_BUILD_SYSTEM_TOOL"))
페이지 내의 특정 element 찾기
element = driver.find_element_by_name("userName")
element가 찾기 쉽게 id나, class name 등으로 되어 있다면 find_element_by_id() 혹은 find_element_by_class_name() 등으로 쉽게 찾을 수 있다. 아니라면 tag name 등으로 찾은 후 돌리면서 찾아본다. 함수명이 element가 아닌 elements 임에 유의하라.
import re
ultp = re.compile('^Ult-Build-[12].*')
ult_req = { }
elements = driver.find_elements_by_tag_name("tbody")
for tag in elements:
if ultp.match(tag.text):
wordlist = tag.text.split()
if len(wordlist) >= 2:
ult_req[wordlist[0]] = wordlist[1]
키 입력이나 클릭하기
찾은 element가 input과 같은 입력이 가능한 element라면 바로 send_keys()로 입력이 가능하다.
from selenium.webdriver.common.keys import Keys
element = driver.find_element_by_id("j_username")
element.send_keys("dasomoli")
element = driver.find_element_by_name("j_password")
element.send_keys("password", Keys.ENTER)
직접 element를 찾기 어렵다면 근처 element를 찾은 후 click한 후 key를 입력할 수도 있다.
from selenium.webdriver.common.action_chains import ActionChains
elements = driver.find_elements_by_class_name("setting-name")
for element in elements:
if element.text == "P4_Shelve_CLs":
shelve_element = element
actions = ActionChains(driver)
actions.move_to_element_with_offset(shelve_element, shelve_element.rect['width'] + 5, shelve_element.rect['height'] / 2).click().send_keys("12345678", Keys.ENTER)
actions.perform()
send_keys() 대신 click() 을 이용하면 마우스 클릭이 가능하다. 마우스 클릭 지점을 찾기 힘들 때는 context_click()을 사용하면 우클릭되는데, 이 때 나타나는 context menu로 클릭 지점을 대충 파악할 수 있다.
from selenium.webdriver.support.ui import Select
select = Select(element)
if value != "":
select.select_by_visible_text(value)
else:
select.select_by_index(0)
fstab은 Linux 시스템의 file system table을 뜻한다. mount를 쉽게 하기 위한 configuration table이다.
fstab의 구조
6개의 항목이 순서대로 구성되어야 한다.
디바이스 (Device): 보통 mount되는 디바이스의 이름 혹은 UUID이다. 예를 들면, sda1
마운트 위치 (Mount point): mount될 디렉토리의 위치
파일 시스템 타입 (File System Type): 사용되는 file system의 type
옵션 (Options): mount 옵션. 여러개를 쓸 때는 콤마(,)로 구분한다.
백업 동작 (Backup Operation): 0은 백업하지 않음. 1은 dump로 backup을 할지를 결정. 오래된 backup 방법이라서 0으로 설정해서 사용하지 않도록 한다.
파일 시스템 체크 순서 (File System Check Order): 0은 fsck로 체크하지 않음. 1은 root file system, 다른 파티션들은 2로 설정되어야 한다. 3, 4, … 로 한다고 해서 순서가 되지 않으므로 순서를 설정하지 않도록 한다. 그냥 다른 모든 파티션은 2이다.
예제
proc /proc proc defaults 0 0
PARTUUID=5e3da3da-01 /boot vfat defaults 0 2
PARTUUID=5e3da3da-02 / ext4 defaults,noatime 0 1
UUID=678dcc13-1b44-4ee8-80cf-7f186587054d /mnt/NAS ext4 defaults,noatime,rw 0 2
# a swapfile is not a swap partition, no line here
# use dphys-swapfile swap[on|off] for that
다른 mount 옵션
auto / noauto: 부팅 시에 자동으로 mount할지 말지.
exec / noexec: 그 파티션이 바이너리를 실행할 수 있는지 아닌지. 보통 보안 목적으로 noexec로 설정된다.
ro / rw: ro는 읽기 전용 (read-only), rw는 읽기 쓰기 (read-write)
nouser / user: user가 mount권한을 갖을지 말지.
atime / noatime / relatime: access time (atime) 을 기록할지 말지. relatime은 access time이 atime data가 마지막으로 update된 (mtime) 이후에 파일이 수정되었을 때, 또는 마지막으로 access된 후 일정 시간 (기본값은 하루)이 지난 후에만 업데이트한다.
suid / nosuid: suid와 sgid 비트 동작을 허용할지 말지.
dev / nodev: character나 block special device를 interpret할지 말지.
defaults: 기본값을 사용. rw, suid, dev, exec, auto, nouser, async 와 같다.