Published
Edited
Jun 24, 2020
Insert cell
Insert cell
Insert cell
doc01 = html`
<div>
<div class="a1">
용용<div class="c1">빵빵</div>
</div>
<div class="b1">
용용<div class="a1">통통</div>
</div>
<div class="c1">
용용<div class="b1">콩콩</div>
</div>
</div>
`
Insert cell
{ // "빵빵"에만 배경색이 칠해지도록 적절한 선택자를 작성하라. 다른 코드는 바꾸면 안됨. (2점)
doc01.querySelectorAll("*").forEach( e => e.removeAttribute("style") ) // 스타일 초기화
doc01.querySelectorAll(".a1 > .c1").forEach(e => e.style.background = "cyan")
}
Insert cell
doc02 = html`
<div>
<div class="a2">
용용<div class="c2">빵빵</div>
<div class="b2"><div class="c2">방방</div></div>
</div>
<div class="b2">
용용<div class="a2">통통</div>
<div class="c2">용용<div class="a2">동동</div></div>
</div>
<div class="c2">
용용<div class="b2">콩콩</div>
<div class="b2">용용<div class="b2">공공</div></div>
</div>
</div>
`
Insert cell
{ // "방방"에만 배경색이 칠해지도록 적절한 선택자를 작성하라. 다른 코드는 바꾸면 안됨. (3점)
doc02.querySelectorAll("*").forEach( e => e.removeAttribute("style") ) // 스타일 초기화
doc02.querySelectorAll(".a2 > .b2 > .c2").forEach(e => e.style.background = "cyan")
}
Insert cell
md`----
## TRUE와 FALSE가 바뀐 세상에서 연산 정의

람다계산법에 해당하는 화살표 함수와 함수호출식만을 이용해 NOT과 XOR을 정의하라.

참고로 XOR(b1)(b2)는 b1과 b2가 각각 TRUE와 FALSE 혹은 FLASE와 TRUE로 서로 다를 때만 계산 결과가 TRUE이고 아니면 FALSE이다.
`
Insert cell
Insert cell
TRUE = a => b => b
Insert cell
FALSE = a => b => a
Insert cell
NOT = p => a => b => p(b)(a) // 1점
Insert cell
XOR = a => b => a(b)(NOT(b)) // 3점
Insert cell
OR = p => q => p(q)(p)
Insert cell
AND = p => q => p(p)(q)
Insert cell
arity = { // 몇 개의 인자를 연속해서 받을 수 있나
const ar = c => {
if (typeof c === "function") {
try { return 1 + ar( c({}) ) } catch(_) { return 1 }
} else { return 0 }
}
// ObservableHQ 환경의 전역변수로는 직접 재귀함수를 정의가 안되니 지역변수 ar함수를 정의한 다음에 리턴
return ar
}
Insert cell
show = c => {
const n = arity(c)
// arity 26까지만 일단 생각하자 ... 넘어가는 무지복잡한 녀석은 처리하기 귀찮다
if (n > 26) throw RangeError('arity('+c+')='+n+' is over 26')
const as = ["a","b","c","d","x","y","z","w",
"u","v","p","q","r","s","t",
"e","f","g","h","i","j","k",
"l","m","n","o"].slice(0,n)
const mkF = a => {
const f = x => mkF( a+"("+x+")" )
f.toString = () => a
return f
}
const fs = as.map( mkF )
const head = as.join(" => ")
const body = fs.reduce( (g,x) => g(x), c ).toString()
return ( (n>0)? head+" => ": "") + body // arity 0인 경우는 다루지 않겠지만 혹시 모르니 ...
}
Insert cell
[ show(AND(TRUE)(TRUE)) == show(TRUE),
show(AND(TRUE)(FALSE)) == show(FALSE),
show(AND(FALSE)(TRUE)) == show(FALSE),
show(AND(FALSE)(FALSE)) == show(FALSE) ]
Insert cell
[ show(NOT(TRUE)) == show(FALSE),
show(NOT(FALSE)) == show(TRUE) ]
Insert cell
[ show(XOR(TRUE)(TRUE)) == show(FALSE),
show(XOR(TRUE)(FALSE)) == show(TRUE),
show(XOR(FALSE)(TRUE)) == show(TRUE),
show(XOR(FALSE)(FALSE)) == show(FALSE) ]
Insert cell
[ show(OR(TRUE)(TRUE)) == show(TRUE),
show(OR(TRUE)(FALSE)) == show(TRUE),
show(OR(FALSE)(TRUE)) == show(TRUE),
show(OR(FALSE)(FALSE)) == show(FALSE) ]
Insert cell
Insert cell
TRUE1 = a => b => a
Insert cell
FALSE1 = a => b => b
Insert cell
NOT1 = p => a => b => p(b)(a) // 1점
Insert cell
XOR1 = a => b => a(NOT(b))(b) // 3점
Insert cell
OR1 = p => q => p(p)(q)
Insert cell
AND1 = p => q => p(q)(p)
Insert cell
[ show(AND1(TRUE1)(TRUE1)) == show(TRUE1),
show(AND1(TRUE1)(FALSE1)) == show(FALSE1),
show(AND1(FALSE1)(TRUE1)) == show(FALSE1),
show(AND1(FALSE1)(FALSE1)) == show(FALSE1) ]
Insert cell
[ show(NOT1(TRUE1)) == show(FALSE1),
show(NOT1(FALSE1)) == show(TRUE1) ]
Insert cell
[ show(XOR1(TRUE1)(TRUE1)) == show(FALSE1),
show(XOR1(TRUE1)(FALSE1)) == show(TRUE1),
show(XOR1(FALSE1)(TRUE1)) == show(TRUE1),
show(XOR1(FALSE1)(FALSE1)) == show(FALSE1) ]
Insert cell
[ show(OR1(TRUE1)(TRUE1)) == show(TRUE1),
show(OR1(TRUE1)(FALSE1)) == show(TRUE1),
show(OR1(FALSE1)(TRUE1)) == show(TRUE1),
show(OR1(FALSE1)(FALSE1)) == show(FALSE1) ]
Insert cell
md`----
## 보였다 안보였다
`
Insert cell
btn03 = html`<button>누르면 안보이다 약 2초 후에 나타나는 버튼</button>`
Insert cell
btn03.onclick = btn03Handler
Insert cell
btn03Handler = e => { // (2점)
btn03.style.display = 'none'
setTimeout(() => btn03.style.display = 'block', 2000)
}
Insert cell
doc04 = html`
<div style="height:3em;">
<select style="height: 2em;">
<option value="2">2초마다</option>
<option value="0" selected>중지</option>
</select>
<span>깜빡깜빡</span>
</div>
`
// 처음에는 기본으로 선택된 깜빡거리지 않는 상태로 있다가,
// 2초마다를 선택하면 2초 간격으로 "깜빡깜빡" 글자가 깜빡거리도록 하라.
// 물론 다시 중지를 선택하면 깜빡거리는 것을 중지하고 글자가 계속 나타나 있어야 한다.
Insert cell
/* 힌트가 될만한 코드
{ // 2초마다 깜빡거리는 예제 코드
const span = doc02.querySelector("span")
setInterval( () => span.hidden = !span.hidden, 2000 )
}
*/
Insert cell
// 이 셀에 doc04 관련된 코드를 모두 작성하라 (여러 셀에 나눠 작성하지 말고 여기다만) (4점)
doc04.childNodes[1].children[0].getAttributeNode("value").name
// 여기에 작성
// 여기에 작성
Insert cell
Insert cell
pairs = (xs,ys) => undefined // 여기에 함수 정의 작성
Insert cell
Insert cell
sameNumArray = (xs,ys) => undefined // 여기에 함수 정의 작성
Insert cell
md`
음식을 좋아하는 순서대로 나열할 수 있도록 위/아래쪽 방향 화살표 버튼을 순위가 한단계씩
위/아래로 한칸씩 이동하도록 버튼에 적절한 핸들러가 추가되도록 작성하라.
이미 가장 높은 1순위이면 위쪽 방향 화살표를 눌러도 변화가 없으며
이미 가장 끝 순위이면 아래쪽 방향 화살표를 눌러도 변화가 없어야 한다.

이렇게 동작하도록 위쪽 방향 화살표 버튼에 대한 핸들러를 작성하는 셀 하나 (4점),
아래쪽 방향 버튼에 대한 핸들러를 작성하는 셀 하나(4점), 이렇게 두 개의 셀로 작성하라. (총합 8점)

일반적으로 5개가 아니라 다른 개수의 음식 메뉴 구성으로도 동작하도록 작성하여야 한다.
만일 5개일 때만 제대로 동작하도록 작성했다면 각각의 핸들러에 대해 부분점수 1점만 얻는다.
(둘 다 5개일 때만 제대로 동작하도록 작성했다면 부분점수 총합 2점을 얻게 된다는 뜻)

힌트: https://developer.mozilla.org/ko/docs/Web/API/Node/insertBefore
`
Insert cell
doc05 = html`
<ol>
<li>칼국수 ${srcBtnUp}${srcBtnDn}</li>
<li>비빔밥 ${srcBtnUp}${srcBtnDn}</li>
<li>불고기 ${srcBtnUp}${srcBtnDn}</li>
<li>떡볶이 ${srcBtnUp}${srcBtnDn}</li>
<li>설렁탕 ${srcBtnUp}${srcBtnDn}</li>
</ol>
`
Insert cell
srcBtnDn = `<button type="button" class="btndn">⇩</button>`
Insert cell
srcBtnUp = `<button type="button" class="btnup">⇧</button>`
Insert cell
// 여기에 위쪽 방향 버튼에 대한 핸들러 작성
Insert cell
// 여기에 아래쪽 방향 버튼에 대한 핸들러 작성
Insert cell
Insert cell
form = html`
<form action="https://postman-echo.com/post" method="post" target="_blank">
<fieldset>
<legend>관심 뉴스 분야 선택 (1-4개)</legend>
<label><input name="politics" type="checkbox">정치</label>
<label><input name="economy" type="checkbox">경제</label>
<label><input name="national" type="checkbox">사회</label>
<label><input name="world" type="checkbox">세계</label>
<label><input name="science" type="checkbox">과학/기술</label>
<label><input name="lifestyle" type="checkbox">생활/문화</label>
<label><input name="entertainment" type="checkbox">연예/엔터테인먼트</label>
<label><input name="sports" type="checkbox">스포츠</label>
</fieldset>
<button type="submit">선택</button>
<button type="reset">초기화</button>
<output style="color:red"></output>
</form>
`
Insert cell
form.onsubmit = event => {
event.preventDefault() // submit의 기본 동작이 일어나지 못하도록
const output = form.querySelector("output")
const count = Array.from( form.querySelectorAll('[type="checkbox"]') )
.filter(b => b.checked).length
if (count < 1) {
output.textContent = "관심 뉴스를 한 분야 이상 선택해 주세요."
setTimeout( () => output.textContent="", 3000 )
return false;
}
if (count > 4) {
output.textContent = "관심 뉴스는 네 분야까지만 선택 가능합니다."
setTimeout( () => output.textContent="", 3000 )
return false;
}
form.submit() // 위의 validiation 검사에서 걸리지 않고 통과되면
}
Insert cell
form.onchange = event =>
{form.querySelector("button").disabled = true
form.querySelectorAll("button")[1].disabled= true}
Insert cell
form.onchange = event => {
const count = Array.from( form.querySelectorAll('[type="checkbox"]') )
.filter(b => b.checked).length
if (count > 4 || count <1 ){
form.querySelector("button").disabled = true
}else
form.querySelector("button").disabled = false
if(count >=1)
form.querySelectorAll("button")[1].disabled=false
else
form.querySelectorAll("button")[1].disabled= true
if(count ==4){
for(let i=0; i<8; i++){
if( form.querySelectorAll("input")[i].checked==true)
form.querySelectorAll("input")[i].disabled=false
else
form.querySelectorAll("input")[i].disabled=true
}
}
if(count ==3){
for(let i=0; i<8; i++){
form.querySelectorAll("input")[i].disabled=false
}
}
}
Insert cell
form.querySelectorAll("button")[1].onclick=() => {
form.reset()
form.querySelectorAll("button")[1].disabled= true
form.querySelector("button").disabled = true
for(let i=0; i<8; i++){
form.querySelectorAll("input")[i].disabled=false
}
}
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more