0%

介绍了网络原理、html、CSS、JavaScript 基础知识。

写 Lab 因为不会用 html 就嗯学了一点 js 的语法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
const CHECK = new Array (
new Array (1, 0, 0),
new Array (0, 0, 1),
new Array (0, 1, 0),
);

for (let index = 1; index <= 2; index++) {
for (let choice = 1; choice <= 3; choice++) {
let correct = CHECK[index - 1][choice - 1];
let button = document.querySelector(
'#choice_' + index.toString() + '_' + choice.toString()
);
let question = document.querySelector(
'#section_' + index.toString()
)
console.log(question.innerHTML);
if (correct) {
button.addEventListener('click', function() {
button.style.backgroundColor = 'green';
question.innerHTML += '<br>Correct';
});
} else {
button.addEventListener('click', function() {
button.style.backgroundColor = 'red';
question.innerHTML += '<br>Incorrect';
});
}
}
}

拿数组存答案有点抽象了,这个用 html 的 class 就行。

网页,但是格式寄了

Week 7

Iterator

例如遍历序列,for x in s 会创建 iterator,不妨记为 i = iter (s)。不断取 x = next(i)x 会依次赋值,而 i 会向后移动。

到达结尾报错 StopIteration。可以用 try 处理异常:

1
2
3
4
5
try:
while True:
x = next(i)
# ...
except StopIteration

即为 for 的等价实现

Generator

一类生成 iterator 的函数。

函数内部 yield 返回的值会依次被迭代。

generator 的运行是懒惰的,调用一次 next 会执行到下一次 yield。故 generator 可以 yield 无穷次,生成不会停止的 iterator。

可用 yield for gen()yield generator gen() 的所有迭代值。

Week 8

面向对象。

Week 5

Cat

抽空写完。

Week 6

2.3

1
seq[start:end:step]

2.4

list 的直接引用传递的是地址。

1
2
a = []
b = a

此后 a, b 会同步改变。

若想要只传递值,可以用 list(s)s[:]s 复制一份。

tuple 是不可变的序列,用括号表示。但 tuple 中的序列元素能改变。

数据分为可变(mutable)与不可变,二者有本质区别,比如可变数据无 hash 值,因此不可作为字典 key。可变数据拥有身份,isis not 是判断身份是否一致的函数。


局部状态这部分写的极为抽象。

1
2
wd = make_withdraw(12)
wd2 = wd

这绑定的是同一个函数。

只有函数调用才能引入新帧。

抽空看完 2.4。

Week 3

2.2

1
2
3
4
5
6
7
8
9
10
11
12
>>> def pair(x, y):
"""Return a function that represents a pair."""
def get(index):
if index == 0:
return x
elif index == 1:
return y
return get

>>> def select(p, i):
"""Return the element at index i of pair p."""
return p(i)

用函数定义 pair 的方式。

2.3

对解释器而言,下划线只是环境中的另一个名称,但对程序员具有约定俗成的含义,表示该名称不会出现在任何未来的表达式中。

以前乱用下划线很不规范。

1
[<map expression> for <name> in <sequence expression> if <filter expression>]

Lab 3

1
2
3
4
5
6
7
checker = lambda x: False
i = 3
while i < n:
if not checker(i):
checker = (lambda f, x: lambda y: f(y) or y % x == 0)(checker, i)
i = i + 1
return checker

忽略 i 的范围,其实是用 lambda 更简洁地实现了筛法,得到的 checkerOR(x % p_i == 0)

需要注意的是 i 必须传值进去,如果内层调用则是地址,i 随循环改变后就会让 checker 出错。

Week 4

Q6

1
(lambda g: lambda x: g(g, x))(lambda f, n: 1 if n == 1 else n * f(f, n - 1))

题目是不直接递归实现 lambda 阶乘函数。

巧妙的解法。lambda f, n 把函数自身传递到下一层避免了直接递归。而 f 本身未给定,单独后一个括号只是“循环论证”,故再通过 lambda g 调用它,让 g 作为形式函数代表 f 即可。

但凡我高中有准备点信息会考都不至于这样。

课程
教材

Week 1

1.2

1
2
3
from math import sqrt
f = max
y, x = x, y # 计算完右侧再赋值

Week 2

1.4

1
2
3
def f(a, b=1):
# f(a) -> f(a, 1)
# f(a, 2) -> f(a, 2)

1.5

1
2
3
4
5
6
7
8
9
assert a == b, 'a != b.'
'''
>>> command
result
'''

>>> from doctest import testmod
>>> testmod()
>>> run_docstring_examples(f, global(), True)

1.6

1
2
3
4
5
6
7
8
9
10
11
12
13
def f(term):

def compose(f, g):
def h(x):
return f(g(x))
return h
# curring
# f(x, y) => f(x)
def curried_pow(x):
def h(y):
return pow(x, y)
return h
lambda x: f(x)
装饰器:
1
2
3
4
5
6
7
8
9
10
@f
def g():
# ...

def g():
# ...
g = f(g)

# 二者等价
# 注意 f 的参数和返回值都是函数

当然这只是最基础的。

进阶

HW 02

You’re not allowed to rebind variables defined outside of our current frame!

(对于函数)里面不能改外面的变量。可以 nonlocal,或者建一个新的。nonlocal 在里面用,global 在外面用。

frame 搜不出东西,可能是本书自己造的概念。类似的说法比如 scope(作用域)。

1
lambda x, y: x % y or True

x % y != 0 时短路,返回的是 x % y 而非 or 运算得出的 True

Project 01 (Hog)

  • 用二次定义的函数时,外层的数据都会保留。显然必须是这样的,虽然与 C++ 不一样。

任务控制

1.

pgrep sleeppkill sleep

2.

1
2
3
4
5
6
7
8
9
10
pidwait() {
kill -0 $1
ret=$?
while [[ $ret -eq 0 ]]; do
sleep 1
kill -0 $1
ret=$?
done
echo 'Done.'
}

有点写复杂了。直接 while kill -0 $1 似乎就可以。

之前用 $? 调用返回码,但放到 while 里会出错,可能是局部变量的问题?总之 shell 语法是真反人类。

别名

Git Bash 没有自带 .bashrc。可以自己手动创建 ~/.bashrcsource 或重启 Git Bash 会自动使用这个配置。

1
alias vitblog='hexo clean; hexo g; hexo d; hexo s'

定义 hexo 一条龙还是挺方便的。分号隔开多行命令。

这节课的内容是 vim,所以没什么好写的。

给 vim 装了 MarkdownPreview 插件,之后用 vim 写 blog。


20231128:

显然寄了。理论上,🐕都不用……但笔记本没有跳转键,直接打字是真的慢,可能还是得学一学。

对于 nvim 和 vscode 等软件我都花了很多时间在配环境上。这是一项需要学习和练习的技能,早点开始学也算是一种(属于弱者的) Missing Semester 了,反正时间很多……是吗?

作业

1.

直接看手册,略。

2.

  • 注意权限。可以存在 $HOME 目录下或者 export A=$(pwd) 设置环境变量。

  • echo 是直接 IO,cat 是读取文件。

  • source *.sh 为什么没用?

    *因为 source 是执行不是编译。

3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#!/bin/bash#

# 或者 solution 中用的 /usr/bin/env bash?似乎有区别

rm out.txt err.txt
echo "out.txt and err.txt removed."

for ((cnt=0;;cnt++)); do
bash 3.sh >> out.txt 2>> err.txt
# 不是 source
if [[ $? -ne 0 ]]; then
break
fi
done

echo "Error occured after $cnt runs."
echo "stdout:"
cat out.txt
echo "stderr:"
cat err.txt

bash./ 类似,后者要权限(用 chmod)。这两个的原理是新开一个 shell 运行。

3.sh(题目给的代码)中有 exit 1,用 source 到这里会直接退出 bash,因为 source 的原理是直接在本 shell 运行。还有一种写法是把 source 替换成 .

还有一个 sh,与 bash 的区别是:

sh 遵循 POSIX 规范:“当某行代码出错时,不继续往下解释”。bash 就算出错,也会继续向下执行。

试了一下编译过不了。这其实属于历史遗留问题

4.

1
find . -name "*.css" -exec zip csss.zip {} +
  • -name 不直接操作文件,所以格式是字符串。
  • zip 后第二个参数用 {} 表示 find 的结果。
  • + 结束 -exec

老东西不会写代码了。

BIG

BIGGGG

f(x)f(x)

i=1n\sum_{i=1}^n

eiθ=cosθ+isinθi=1nΣi=1ne^{i\theta}=\cos\theta+i\sin\theta \\ \sum_{i=1}^n \\ \Sigma_{i=1}^n

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include<bits/stdc++.h>
using namespace std;

const int N=300,MOD=1e9+7;
int n,m,t,a[N+5][N+5],ans=1;

int Power(int x,int y) {
int ret=1;
while(y) {
if(y&1) ret=1ll*ret*x%MOD;
x=1ll*x*x%MOD,y>>=1;
}
return ret;
}

int main() {
scanf("%d%d%d",&n,&m,&t);
for(int i=1,u,v,w;i<=m;i++) {
scanf("%d%d%d",&u,&v,&w);
if(t) a[u][v]=(a[u][v]-w)%MOD,a[v][v]=(a[v][v]+w)%MOD;
else {
a[u][v]=(a[u][v]-w)%MOD,a[v][u]=(a[v][u]-w)%MOD;
a[u][u]=(a[u][u]+w)%MOD,a[v][v]=(a[v][v]+w)%MOD;
}
}
for(int i=2;i<=n;i++) {
int u=0;
for(int j=i;j<=n;j++) if(a[j][i]) u=j;
if(!u) { puts("0"); return 0; }
if(u!=i) ans*=-1;
for(int j=1;j<=n;j++) swap(a[i][j],a[u][j]);
for(int j=i+1;j<=n;j++) {
int u=1ll*a[j][i]*Power(a[i][i],MOD-2)%MOD;
for(int k=1;k<=n;k++) a[j][k]=(a[j][k]-1ll*u*a[i][k])%MOD;
}
ans=1ll*ans*a[i][i]%MOD;
}
printf("%d\n",(ans+MOD)%MOD);
return 0;
}

Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub.

Quick Start

Create a new post

1
$ hexo new "My New Post"

More info: Writing

Run server

1
$ hexo server

More info: Server

Generate static files

1
$ hexo generate

More info: Generating

Deploy to remote sites

1
$ hexo deploy

More info: Deployment