0%

教育是国家持续发展的根基,孩子是祖国的未来、民主的希望,因此一说到教育,就会涉及到每个孩子、每个家庭、每个学校。但是人们关于教育的理解,却显著不同。

教育是希望

对于相对贫困的农村地区,教育带来的是希望。父母希望孩子好好读书,长大改变自己的经济状况,活的比自己好。父母的想法很伟大,也很天真,他们对自己已经不报答的希望了,但却把希望寄托在孩子身上,并为他们的读书努力赚钱,给孩子提供足够的物质支撑。

教育是负担

对于城里的孩子,教育是没完没了的课业。父母给孩子安排了各种补习班,孩子回到家做各种作业,有些作业完成不了的还需要家长帮忙,写完了还有家长签字。人们越来越认识到过早、过度教育对孩子的危害,于是提出减负、双减、禁辅等措施,但是结果还是不理想,孩子还是要上各种课,只不过上的时间、方式、种类进行的变化而已。

所以你看,没有教育不可以,教育过度也不行,如何让农村的孩子和城市的孩子相互平衡平衡,是一个很有意义的问题。

教育是指向个体发展的集体性社会实践

教育并不是社会产生时就有的,教育是一种集体性社会实践,只不过这种社会实践不再仅仅指向高效的生产,而是指向帮助部分人群学会生产本身。

为了让学习者更好的观察生产的过程,于是委派一个专门的负责人对实践活动进行优化,优化包括活动内容、形式、时间、顺序等,这个专门的负责人就是教师。

教育具有社会角色再分配的功能

对于社会来讲,教育是社会职业再分配的实现方式。如果教育不能改变人们的命运,社会阶级固化,贫富差距加大,且无法改变,那么教育就失去的其社会再分配的功能。

不是教育决定你的人生轨迹,而是你决定了自己的教育轨迹

教育似乎是导致个人发展路径不同的原因。比如每个人的学历不同,其工作岗位也不同,似乎是教育过程决定了工作岗位。比如,从名牌大学毕业,进入外企或者国企或者从政就成为理所当然。这种表面的前后顺序关系,具有很强的迷惑性,先后发生并不一定是因果关系,但因果关系肯定是前因后果。实际上,你可以从事任何你想从事的职业,只有你为此付出足够多的努力。

教育是个体迭代发展的过程

教育是个体能力和观念自我迭代的过程。有的人喜欢说是能力发展,我则喜欢用迭代,因为有的时候能力会短暂的退步,让步又踏上一个新台阶。这时说发展就没有迭代合适,迭代是对原有能力的重新选择和组合。能力发展是个体在新情境压力下选择、优选出来的,而不是原有能力的简单延伸。

教育就是自我解放的过程

教育的终极是自我教育。我们通常理解的教育都是教育别人,教育是一个及物动词。有时我们会认为,学生发展是教师的教育导致的。我们当然不是要否定教师的作用,教师的职责就是帮助他人获得发展。但是对于发展或者自我超越发挥更大作为的不是别人,恰恰是你自己。没有人能替别人认知,也没有人能替你认识自己。教师只是在你认识你自己的过程中发挥了一定的引导作用而已,但是行路人还必须是学习者自己。从这个意义上来说,教育的极致必然是指向自己的。换句话说,他人教育只能通过自我教育发挥作用。所以他人教育的最大成就也是唤醒个体的自我教育。教是为了不教,就是这个道理。

教育的终极目的是自我解放。既然教育最终都会指向自我,那么其中终极目的又是什么呢?自我的超越和解放就是教育的终极目的。有人会将教育的终极目的表述为某种状态,比如自由、幸福、随心所欲不逾矩、天人合一、自然无为、立德、立功、立言。但是这些状态却差异很大,每个人的理解也不同,但是总体而言都是实现某种形式的自我超越和自我解放。所以教育的根本目的不是实现某种状态,而是超越某种状态。超越的方式有多种,超越之后获得状态也不同,所以实现超越的路径也因人而异,不可复制。其根本原因是我的束缚不同,解放路径当然也不同。

教师是以教育谋生的人,也是以教育为使命的人

教师是以从事教育活动为职业谋生的人。有人说教师是灵魂的工程师、是园丁,可见教师对人的影响作用。但是如果单纯从职业而言,教师就是以从事教育活动赚钱的人。当然也有不赚钱的教育,但是教育总要活着,中药养家糊口,所以说教师是从事教育活动谋生的人,谋取的可能不一定是钱财,也可能是自己想要的生活。说教师是以教谋生不是一种贬低,而是实事求是。认识到这一点,反而能让教师活的更踏实,教育就是教师与社会交互而付出的个人劳动,而且这种劳动或者服务对社会以及个人是产生积极作用的,它当然是有价值的,值得付费的。

生物学教师首先是教师,然后才是生物学教师

我们首先是教师,然后才是某一个学科的教师。作为教师,为了刚好的分工合作,教师只教授自己擅长的领域,所以有了学科教师和学科教育。但不能因为自己是物理老师或者生物老师,而就对学生没有任何其他的责任,相反,因为教育的终极目的是自我解放,教师不能只局限与自己的学科教育职责,而必须相互配合为学生成为更好的自己而作额外的事儿。也就是教师必须首先是教师,不分科的对学生具有引领职责的教师,然后才是负责某个科目的教师。教师的眼中是一个完整的希望自我超越和自我解放的人,而不是只关注学科成绩的教师,那是教育的异化,学科教育的异化,它将导致学科的割裂,把教师和学生束缚在认为附加的学科边界束缚之中。不仅不利于学生的整体发展,也不利于教师自身的发展。

比如在各学科布置作业,如果都站在自己的学科的角度,那么布置更多的作业无疑是对提高学科成绩有利的,但是对学生的发展却十分不利,导致这个结局不仅是博弈论的囚徒困境,更根本的原因是教师身份定位的问题,你把自己首先当成一个教师还是一个学科教师,假如所以学科教师都能把自己首先作为一名教师,那么关心孩子的成长、合理布置作业才是正解,而不是陷入学科作业竞赛之中。

教育是艺术也是科学

教育需要符合认知规律和学习科学。教育不是任何方式都可以,也不是怎么教都行。教育方式方法可以多用,但是必须要能充分吸收已有的教育教学经验,从而优化教学过程。教育必然是一个自我迭代的过程,一个反复优化和选择的过程。有方向的多样化,有原则的选择,是教育快速优化的重要保障。从这个意义上来说,教育的发展是进化过程,我们可以借助进化的规律和思想来做教育。

教育的成功可以借鉴,但不可复制

教育的成功不是同样一种成功。有的时候,我们看到某个班级、某位教师、某个学习的教育成功,特别有复制成功的冲动。但是复制的前提是成功是同样的,起点也是相同,这样复制方法和路径才有意义。但是对于教育而言,第一点就不成立,在不同社会环境中,不同的生态环境下,成功的定义也不尽相同。所以整体复制的意义不大。其次学生不同,不同学校、班级学生有显著差别,不同学生个体也有显著差别,所以我们不复制,我们也复制不了。教育的目标不是让所有人都相信同一种成功,教育的目的恰恰是打破这种观念,让个体踏上自己与众不同的自我教育的道路。

大学教育在于开拓你的人生,而不是相反

大学教育不是简单的提供学生达成目标的能力和效率,大学教育更在于帮助学生认识自己和发展自己。有人说教育是为未来做准备,未来要谋生,要从事某一职业,未来有哪些挑战学校教育就要教哪些内容。简单的说人生是一条跑道,学校的作用就是加速,让学生跑的比别人更快。哪是不是也死得更快呢?!教育不该如此之狭隘!为什么是一条跑道,每个人的跑道都不同!跑去哪里?每个人的终点都不一样,当然死亡除外。为什么非要跑,走可不可以,散步可以不,为什么要错过身边的风景。所以,大学教育,不是学生的人生加速器,虽然它会教授你很多学习方法,也会提高你的能力,它是你重新定义人生、认识自己的交叉路口。

学校是一个高效、安全的试错机器

我们总是希望自己少犯错,多正确。但是人生的很多事情,你不尝试永远也不知道自己是否适合。所以,与其说学校是一个教授正确知识的场所,还不如说学校是一个高效试错的安全场所,因为一旦你进入社会犯错成本会非常高,所以同学们,你有理想吗,那么一定在大学期间把自己的想法都试一试,目的当然不是高效的犯错,而是充分利用这段时间和大学场域的天然优势,降低你的人生犯错成本。

从这个意义上说,教师是最幸福的人,因为他一生计划都停留在这个场域,只有他又一颗天真的心,和被讨厌的勇气,那么它就可以通过不断试错找到自己的道路,走在终身学习的路上。

所以教师一定是一个爱学习的人,因为对于爱学习的人,这是一生幸福,是天堂,对于讨厌学习的人,这是地域。天堂地狱只是一念间。

写在前面的话

有一种语言几乎每个没学过编程的人也都会天天接触,这种语言就是html语言。几乎所以的网页都需要它来写,所以的网站都离不开他,所有的电脑都支持它,所以学一点html不一定是要从事web开发,而是让你对互联网世界有更深层的了解,并在必要的时候读懂和改写代码,让创造性得到施展,让工作和生活更顺畅。
本教程将带你快速浏览网页背后的代码,涉及的内容包括html、CSS、JavaScript、Python、Bootstrap、Jquery、SQL。这些语言和工具足够你开发一个自己的网站和实现想要的功能了。下面,就开始你的探索之旅吧!!

出发前的准备

  • 建议安装一个好用的文本编辑器,用于写代码,比如sublime、Visual Studio Code等,如果不按照用系统自动的文本编辑器也可以,只不过用户体验不会很好。
  • 建议选择一个可多端同步笔记软件,比如印象笔记、Onenote、有道云笔记等,实在不行也可以用纸质笔记本记录自己的学习过程,特别是重要的语句和技术思想,这是你能否学以致用的关键。
  • 安装谷歌或者火狐浏览器,便于对网页进行调试和预览。
  • 测试以下代码的方法,拷贝代码,用编辑器新建文件,粘贴代码,另存为test.html,双击用浏览器打开预览效果,如果对效果不满意,可以对文件重新编辑。
  • 在线测试的方法,点击这个链接,然后把代码粘贴进去,运行即可。

html基本

html是网页注释语言,你可以用它来创建自己的网页。

html文档

<!DOCTYPE html>
<html>
<head>
<title>Hello World</title>
</head>
<body>
<h1>这是我的标题</h1>
<p>这是我的段落</p>
</body>
</html>

标题h

<!DOCTYPE html>
<html>
<body>
<h1>This is heading 1</h1>
<h2>This is heading 2</h2>
<h3>This is heading 3</h3>
</body>
</html>

段落p

<!DOCTYPE html>
<html>
<body>
<p>This is a paragraph.</p>
<p>This is another paragraph.</p>
</body>
</html>

超级连接a

<!DOCTYPE html>
<html>
<body>
<h2>HTML Links</h2>
<p>网页链接用a标记</p>
<a href="zhangchunlei.com">连接</a>
</body>
</html>

图片img

<!DOCTYPE html>
<html>
<body>
<h2>HTML Images</h2>
<p>HTML images are defined with the img tag:</p>
<img src="https://www.w3schools.com/html/w3schools.jpg" alt="W3Schools.com" width="104" height="142">
</body>
</html>

按钮和JS特效

<!DOCTYPE html>
<html>
<body>
<h2>按钮</h2>
<p>HTML按钮使用关键字button标记:</p>
<p id="demo" style="display:none">这是JS特性!</p>
<button type="button" onclick="document.getElementById('demo').style.display='block'">点我!</button>
</body>
</html>

列表ul和ol

<!DOCTYPE html>
<html>
<body>
<h2>无序列表</h2>
<ul>
  <li>无丝分裂</li>
  <li>有丝分裂</li>
  <li>减数分裂</li>
</ul>  
<h2>有序列表</h2>
<ol>
  <li>前期</li>
  <li>中期</li>
  <li>后期</li>
</ol> 
</body>
</html>

样式style

<!DOCTYPE html>
<html>
<body>
<p>I am normal</p>
<p style="color:red;">I am red</p>
<p style="color:blue;">I am blue</p>
<p style="font-size:50px;">I am big</p>
</body>
</html>

文本格式

<!DOCTYPE html>
<html>
<body>
<p><b>This text is bold</b></p>
<p><i>This text is italic</i></p>
<p>This is<sub> subscript</sub> and <sup>superscript</sup></p>
</body>
</html>

注释

注释虽然并不显示,但是可以帮助阅读和理解代码。

<!DOCTYPE html>
<html>
<body>
<!-- This is a comment -->
<p>This is a paragraph.</p>
<!-- Comments are not displayed in the browser -->
</body>
</html>

颜色color

<!DOCTYPE html>
<html>
<body>
<h1 style="background-color:Tomato;">Tomato</h1>
<h1 style="background-color:Orange;">Orange</h1>
<h1 style="background-color:DodgerBlue;">DodgerBlue</h1>
<h1 style="background-color:MediumSeaGreen;">MediumSeaGreen</h1>
<h1 style="background-color:Gray;">Gray</h1>
<h1 style="background-color:SlateBlue;">SlateBlue</h1>
<h1 style="background-color:Violet;">Violet</h1>
<h1 style="background-color:LightGray;">LightGray</h1>
</body>
</html>

CSS样式

可以使得代码更简洁

<!DOCTYPE html>
<html>
<head>
<style>
body {background-color: powderblue;}
h1   {color: blue;}
p    {color: red;}
</style>
</head>
<body>
<h1>This is a heading</h1>
<p>This is a paragraph.</p>
</body>
</html>

在新窗口打开连接

<!DOCTYPE html>
<html>
<body>
<h2>The target Attribute</h2>
<a href="https://www.w3schools.com/" target="_blank">Visit W3Schools!</a> 
<p>如果target="_blank",网页会在新窗口或便签页打开。</p>
</body>
</html>

图片大小尺寸width&height

<!DOCTYPE html>
<html>
<body>
<h2>图谱尺寸</h2>
<p>自定义图片长宽</p>
<img src="https://www.w3schools.com/html/img_girl.jpg" alt="Girl in a jacket" width="500" height="600">
</body>
</html>

图片picture

<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<h2>The picture Element</h2>
<picture>
  <source media="(min-width: 650px)" srcset="img_food.jpg">
  <source media="(min-width: 465px)" srcset="img_car.jpg">
  <img src="img_girl.jpg" style="width:auto;">
</picture>
<p>改变浏览器宽度可以自动更换图,部分浏览器版本可能不支持</p>
</body>
</html>

span

<!DOCTYPE html>
<html>
<body>
<p>This is an inline span <span style="border: 1px solid; color:black">Hello World</span> element inside a paragraph.</p>
<p>The SPAN element is an inline element, and will not start on a new line and only takes up as much width as necessary.</p>
</body>
</html>

class

<!DOCTYPE html>
<html>
<head>
<style>
.note {
  font-size: 120%;
  color: red;
}
</style>
</head>
<body>
<h1>My <span class="note">Important</span> Heading</h1>
<p>This is some <span class="note">important</span> text.</p>
</body>
</html>

ID +JS

<!DOCTYPE html>
<html>
<body>
<h2>用JavaScript调用ID</h2>
<p>JavaScript可以使用getElementById()方法来改变元素内容</p>
<h1 id="myHeader">Hello World!</h1>
<button onclick="displayResult()">Change text</button>
<script>
function displayResult() {
  document.getElementById("myHeader").innerHTML = "Have a nice day!";
}
</script>
</body>
</html>

还可以使用JS和getElementById方法改变特定元素的属性。

document.getElementById("demo").style.fontSize = "25px";
document.getElementById("demo").style.color = "red";
document.getElementById("demo").style.backgroundColor = "yellow";
document.getElementById("image").src = "picture.gif";

iframe行内框架

<!DOCTYPE html>
<html>
<body>
<h2>制定特定网页在特定位置打开</h2>
<iframe src="" name="iframe_a" height="300px" width="100%" title="Iframe Example"></iframe>
<p><a href="https://www.w3schools.com" target="iframe_a">W3Schools.com</a></p>
<p>当点击链接时,该页面会在制定框架打开</p>
</body>
</html>

file path

<img src="picture.jpg"> 文件在网页相同目录(当前目录)#相对路径
<img src="images/picture.jpg">  文件在当前目录下的images文件夹中
<img src="/images/picture.jpg"> 文件中根目录下的images文件夹中
<img src="../picture.jpg">  文件中当前目录上一层文件夹中
<img src="https://www.w3schools.com/images/picture.jpg"> #绝对路径

head是一个包含下列元素title, style, meta, link, script,base的容器。 它位于html和body标记之间。例如:

<!DOCTYPE html>
<html>
<head>
  <title>Page Title</title>
  <meta charset="UTF-8">
  <meta name="description" content="Free Web tutorials">
  <meta name="keywords" content="HTML, CSS, JavaScript">
  <meta name="author" content="John Doe">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" href="mystyle.css">
  <base href="https://www.w3schools.com/" target="_blank">
  <script>
  function myFunction() {
    document.getElementById("demo").innerHTML = "Hello JavaScript!";
  }
  </script>
</head>
<body>
<p>All meta information goes inside the head section.</p>
</body>
</html>

canvas

<!DOCTYPE html>
<html>
<body>
<canvas id="myCanvas" width="200" height="100" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML canvas tag.</canvas>
//line
<script>
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.moveTo(0,0);
ctx.lineTo(200,100);
ctx.stroke();
</script>
//circle
<script>
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.beginPath();
ctx.arc(95, 50, 40, 0, 2 * Math.PI);
ctx.stroke();
</script>
//hello world 1
<script>
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.font = "30px Arial";
ctx.fillText("Hello World", 10, 50);
</script>
//hello world 2
<script>
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.font = "30px Arial";
ctx.strokeText("Hello World", 10, 50);
</script>
// gradient
<script>
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
// Create gradient
var grd = ctx.createLinearGradient(0, 0, 200, 0);
grd.addColorStop(0, "red");
grd.addColorStop(1, "white");
// Fill with gradient
ctx.fillStyle = grd;
ctx.fillRect(10, 10, 150, 80);
</script>
</body>
</html>

绘制图片

<!DOCTYPE html>
<html>
<body>
<p>Image to use:</p>
<img id="scream" src="img_the_scream.jpg" alt="The Scream" width="220" height="277">
<p>Canvas to fill:</p>
<canvas id="myCanvas" width="250" height="300"
style="border:1px solid #d3d3d3;">
Your browser does not support the HTML canvas tag.</canvas>
<p><button onclick="myCanvas()">Try it</button></p>
<script>
function myCanvas() {
  var c = document.getElementById("myCanvas");
  var ctx = c.getContext("2d");
  var img = document.getElementById("scream");
  ctx.drawImage(img,10,10);
}
</script>
</body>
</html>

CSS

CSS是定义网页显示风格的语言。

什么是CSS?

CSS是Cascading Style Sheets的缩写
CSS描述了HTML元素如何在屏幕或者其他媒体中现实的样式。
CSS能节省大量的工作。它能够轻松定制多个网页。
外部风格定义表单存储在CSS文件中。我们只需要一个CSS文件,就可以管控所以网页。

CSS插入的3种方式

  • 外部CSS文件
  • 在网页head容器内插入CSS
  • 在元素内插入CSS

外部CSS文件

<link rel="stylesheet" href="mystyle.css">

网页内嵌风格

<!DOCTYPE html>
<html>
<head>
<style>
body {
  background-color: lightblue;
}
h1 {
  color: white;
  text-align: center;
}
p {
  font-family: verdana;
  font-size: 20px;
  color: red;
  text-align: center;
}
p.center {
  text-align: center;
  color: red;
}
.center {
  text-align: center;
  color: red;
}
</style>
</head>
<body>
<h1>My First CSS Example</h1>
<p>This is a paragraph.</p>
<h1 class="center">Red and center-aligned heading</h1>
<p class="center">Red and center-aligned paragraph.</p> 
</body>
</html>

行内插入CSS

<!DOCTYPE html>
<html>
<body>
<h1 style="color:blue;text-align:center;">This is a heading</h1>
<p style="color:red;">This is a paragraph.</p>
</body>
</html>

JavaScript

改变元素内容

<!DOCTYPE html>
<html>
<body>

<h2>What Can JavaScript Do?</h2>

<p id="demo">JavaScript can change HTML content.</p>

<button type="button" onclick='document.getElementById("demo").innerHTML = "Hello JavaScript!"'>Click Me!</button>

</body>
</html>

改变元素属性值

<!DOCTYPE html>
<html>
<body>
<h2>What Can JavaScript Do?</h2>
<p>JavaScript can change HTML attribute values.</p>
<p>In this case JavaScript changes the value of the src (source) attribute of an image.</p>
<button onclick="document.getElementById('myImage').src='https://www.w3schools.com/js/pic_bulbon.gif'">Turn on the light</button>
<img id="myImage" src="pic_bulboff.gif" style="width:100px">
<button onclick="document.getElementById('myImage').src='https://www.w3schools.com/js/pic_bulboff.gif'">Turn off the light</button>
</body>
</html>

对象object

<!DOCTYPE html>
<html>
<body>
<h2>JavaScript Objects</h2>
<p>There are two different ways to access an object property.</p>
<p>You can use person.property or person["property"].</p>
<p id="demo"></p>
<script>
// Create an object:
const person = {
  firstName: "John",
  lastName : "Doe",
  id     :  5566
};
// Display some data from the object:
document.getElementById("demo").innerHTML =
person.firstName + " " + person.lastName;
</script>
</body>
</html>

事件events

<!DOCTYPE html>
<html>
<body>
<button onclick="document.getElementById('demo').innerHTML=Date()">The time is?</button>
<p id="demo"></p>
</body>
</html>

函数调用

<!DOCTYPE html>
<html>
<body>
<h2>JavaScript Math.random()</h2>
<p>Math.random() returns a random number between 0 and 1:</p>
<button type="button" onclick='myFunction()'>Click Me!</button>
<p id="demo"></p>
<script>
  function myFunction() {
    document.getElementById("demo").innerHTML = Math.random();
  }
</script>
</body>
</html>

数据类型

let length = 16;                               // Number
let lastName = "Johnson";                      // String
let x = {firstName:"John", lastName:"Doe"};    // Object

应遵循的良好习惯

best practice you should follow

代码示例

博客网站layout样例

<!DOCTYPE html>
<html>
<head>
<style>
* {
  box-sizing: border-box;
}

body {
  font-family: Arial;
  padding: 10px;
  background: #f1f1f1;
}

/* Header/Blog Title */
.header {
  padding: 30px;
  text-align: center;
  background: white;
}

.header h1 {
  font-size: 50px;
}

/* Style the top navigation bar */
.topnav {
  overflow: hidden;
  background-color: #333;
}

/* Style the topnav links */
.topnav a {
  float: left;
  display: block;
  color: #f2f2f2;
  text-align: center;
  padding: 14px 16px;
  text-decoration: none;
}

/* Change color on hover */
.topnav a:hover {
  background-color: #ddd;
  color: black;
}

/* Create two unequal columns that floats next to each other */
/* Left column */
.leftcolumn {   
  float: left;
  width: 75%;
}

/* Right column */
.rightcolumn {
  float: left;
  width: 25%;
  background-color: #f1f1f1;
  padding-left: 20px;
}

/* Fake image */
.fakeimg {
  background-color: #aaa;
  width: 100%;
  padding: 20px;
}

/* Add a card effect for articles */
.card {
  background-color: white;
  padding: 20px;
  margin-top: 20px;
}

/* Clear floats after the columns */
.row:after {
  content: "";
  display: table;
  clear: both;
}

/* Footer */
.footer {
  padding: 20px;
  text-align: center;
  background: #ddd;
  margin-top: 20px;
}

/* Responsive layout - when the screen is less than 800px wide, make the two columns stack on top of each other instead of next to each other */
@media screen and (max-width: 800px) {
  .leftcolumn, .rightcolumn {   
    width: 100%;
    padding: 0;
  }
}

/* Responsive layout - when the screen is less than 400px wide, make the navigation links stack on top of each other instead of next to each other */
@media screen and (max-width: 400px) {
  .topnav a {
    float: none;
    width: 100%;
  }
}
</style>
</head>
<body>

<div class="header">
  <h1>My Website</h1>
  <p>Resize the browser window to see the effect.</p>
</div>

<div class="topnav">
  <a href="#">Link</a>
  <a href="#">Link</a>
  <a href="#">Link</a>
  <a href="#" style="float:right">Link</a>
</div>

<div class="row">
  <div class="leftcolumn">
    <div class="card">
      <h2>TITLE HEADING</h2>
      <h5>Title description, Dec 7, 2017</h5>
      <div class="fakeimg" style="height:200px;">Image</div>
      <p>Some text..</p>
      <p>Sunt in culpa qui officia deserunt mollit anim id est laborum consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco.</p>
    </div>
    <div class="card">
      <h2>TITLE HEADING</h2>
      <h5>Title description, Sep 2, 2017</h5>
      <div class="fakeimg" style="height:200px;">Image</div>
      <p>Some text..</p>
      <p>Sunt in culpa qui officia deserunt mollit anim id est laborum consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco.</p>
    </div>
  </div>
  <div class="rightcolumn">
    <div class="card">
      <h2>About Me</h2>
      <div class="fakeimg" style="height:100px;">Image</div>
      <p>Some text about me in culpa qui officia deserunt mollit anim..</p>
    </div>
    <div class="card">
      <h3>Popular Post</h3>
      <div class="fakeimg"><p>Image</p></div>
      <div class="fakeimg"><p>Image</p></div>
      <div class="fakeimg"><p>Image</p></div>
    </div>
    <div class="card">
      <h3>Follow Me</h3>
      <p>Some text..</p>
    </div>
  </div>
</div>

<div class="footer">
  <h2>Footer</h2>
</div>

</body>
</html>

钟表代码

<!DOCTYPE html>
<html>
<body>
<canvas id="canvas" width="400" height="400"
style="background-color:#333">
</canvas>
<script>
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var radius = canvas.height / 2;
ctx.translate(radius, radius);
radius = radius * 0.90
setInterval(drawClock, 1000);
//define functions
function drawClock() {
  drawFace(ctx, radius);
  drawNumbers(ctx, radius);
  drawTime(ctx, radius);
}
function drawFace(ctx, radius) {
  var grad;
  ctx.beginPath();
  ctx.arc(0, 0, radius, 0, 2*Math.PI);
  ctx.fillStyle = 'white';
  ctx.fill();
  grad = ctx.createRadialGradient(0,0,radius*0.95, 0,0,radius*1.05);
  grad.addColorStop(0, '#333');
  grad.addColorStop(0.5, 'white');
  grad.addColorStop(1, '#333');
  ctx.strokeStyle = grad;
  ctx.lineWidth = radius*0.1;
  ctx.stroke();
  ctx.beginPath();
  ctx.arc(0, 0, radius*0.1, 0, 2*Math.PI);
  ctx.fillStyle = '#333';
  ctx.fill();
}
function drawNumbers(ctx, radius) {
  var ang;
  var num;
  ctx.font = radius*0.15 + "px arial";
  ctx.textBaseline="middle";
  ctx.textAlign="center";
  for(num = 1; num < 13; num++){
    ang = num * Math.PI / 6;
    ctx.rotate(ang);
    ctx.translate(0, -radius*0.85);
    ctx.rotate(-ang);
    ctx.fillText(num.toString(), 0, 0);
    ctx.rotate(ang);
    ctx.translate(0, radius*0.85);
    ctx.rotate(-ang);
  }
}
function drawTime(ctx, radius){
    var now = new Date();
    var hour = now.getHours();
    var minute = now.getMinutes();
    var second = now.getSeconds();
    //hour
    hour=hour%12;
    hour=(hour*Math.PI/6)+
    (minute*Math.PI/(6*60))+
    (second*Math.PI/(360*60));
    drawHand(ctx, hour, radius*0.5, radius*0.07);
    //minute
    minute=(minute*Math.PI/30)+(second*Math.PI/(30*60));
    drawHand(ctx, minute, radius*0.8, radius*0.07);
    // second
    second=(second*Math.PI/30);
    drawHand(ctx, second, radius*0.9, radius*0.02);
}
function drawHand(ctx, pos, length, width) {
    ctx.beginPath();
    ctx.lineWidth = width;
    ctx.lineCap = "round";
    ctx.moveTo(0,0);
    ctx.rotate(pos);
    ctx.lineTo(0, -length);
    ctx.stroke();
    ctx.rotate(-pos);
}
</script>
</body>
</html>

web game实例

<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<style>
canvas {
    border:1px solid #d3d3d3;
    background-color: #f1f1f1;
}
</style>
</head>
<body onload="startGame()">
<script>
var myGamePiece;
var myObstacles = [];
var myScore;

function startGame() {
    myGamePiece = new component(20, 20, "red", 10, 120);
    myGamePiece.gravity = 0.5;
    myScore = new component("30px", "Consolas", "black", 280, 40, "text");
    myGameArea.start();
}

function myrefresh(){
    window.location.reload();
}

var myGameArea = {
    canvas : document.createElement("canvas"),
    start : function() {
        this.canvas.width = 480;
        this.canvas.height = 270;
        this.context = this.canvas.getContext("2d");
        document.body.insertBefore(this.canvas, document.body.childNodes[0]);
        this.frameNo = 0;
        this.interval = setInterval(updateGameArea, 20);
        },
    clear : function() {
        this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
    }
}

function component(width, height, color, x, y, type) {
    this.type = type;
    this.score = 0;
    this.width = width;
    this.height = height;
    this.speedX = 0;
    this.speedY = 0;    
    this.x = x;
    this.y = y;
    this.gravity = 0;
    this.gravitySpeed = 0;
    this.update = function() {
        ctx = myGameArea.context;
        if (this.type == "text") {
            ctx.font = this.width + " " + this.height;
            ctx.fillStyle = color;
            ctx.fillText(this.text, this.x, this.y);
        } else {
            ctx.fillStyle = color;
            ctx.fillRect(this.x, this.y, this.width, this.height);
        }
    }
    this.newPos = function() {
        this.gravitySpeed = this.gravity;
        this.x += this.speedX;
        this.y += this.speedY + this.gravitySpeed;
        this.hitBottom();
    }
    this.hitBottom = function() {
        var rockbottom = myGameArea.canvas.height - this.height;
        if (this.y > rockbottom) {
            this.y = rockbottom;
            this.gravitySpeed = 0;
        }
    }
    this.crashWith = function(otherobj) {
        var myleft = this.x;
        var myright = this.x + (this.width);
        var mytop = this.y;
        var mybottom = this.y + (this.height);
        var otherleft = otherobj.x;
        var otherright = otherobj.x + (otherobj.width);
        var othertop = otherobj.y;
        var otherbottom = otherobj.y + (otherobj.height);
        var crash = true;
        if ((mybottom < othertop) || (mytop > otherbottom) || (myright < otherleft) || (myleft > otherright)) {
            crash = false;
        }
        return crash;
    }
    //event listener
    document.addEventListener("keydown",keyDownHandler, false); 
    document.addEventListener("keyup",keyUpHandler, false); 
}

function updateGameArea() {
    var x, height, gap, minHeight, maxHeight, minGap, maxGap;
    for (i = 0; i < myObstacles.length; i += 1) {
        if (myGamePiece.crashWith(myObstacles[i])) {
            return;
        } 
    }
    myGameArea.clear();
    myGameArea.frameNo += 1;
    if (myGameArea.frameNo == 1 || everyinterval(150)) {
        x = myGameArea.canvas.width;
        minHeight = 20;
        maxHeight = 200;
        height = Math.floor(Math.random()*(maxHeight-minHeight+1)+minHeight);
        minGap = 50;
        maxGap = 200;
        gap = Math.floor(Math.random()*(maxGap-minGap+1)+minGap);
        myObstacles.push(new component(10, height, "green", x, 0));
        myObstacles.push(new component(10, x - height - gap, "green", x, height + gap));
    }
    for (i = 0; i < myObstacles.length; i += 1) {
        myObstacles[i].x += -1;
        myObstacles[i].update();
    }
    myScore.text="SCORE: " + myGameArea.frameNo;
    myScore.update();
    myGamePiece.newPos();
    myGamePiece.update();
}

function everyinterval(n) {
    if ((myGameArea.frameNo / n) % 1 == 0) {return true;}
    return false;
}

function accelerate(n) {
    myGamePiece.gravity = n;
}

//------------
//Key Handlers
//------------
function keyDownHandler(event)
{
    var keyPressed = String.fromCharCode(event.keyCode);
    if ((keyPressed == "W") || (keyPressed == "&"))
    {       
        accelerate(-1.5);
    }
}
function keyUpHandler(event)
{
    var keyPressed = String.fromCharCode(event.keyCode);
    if ((keyPressed == "W") || (keyPressed == "&") )
    {
        accelerate(1);
    }
}
</script>

<br>
<button onmousedown="accelerate(-0.2)" onmouseup="accelerate(0.05)">ACCELERATE</button>
<button onclick="myrefresh()">Restart</button>
<p>使用上下方向键控制</p>
<p>看你能坚持多久?</p>
</body>
</html>

自己写一个主页index.html,替代原有的padlet,原有是padlet间歇性无法访问。但是发现提交到服务器没有反应。

问题是网站使用的是python django框架,每次更新页面需要重启python manage.py。重启的办法是首先要找到并关闭该进程,然后再重新开启。

###找到服务进程、kill并重启

netstat -tnlp #查看端口
kill 18283 # 关闭python所在进程
nohup python manage.py runserver 0.0.0.0:3000 #重新开启

这时本地服务就开启了,但是还需要开启反向代理才能访问。注意,这一步需要新建一个端口,否则会导致刚开启的3000服务终止。

/bin/systemctl restart nginx.service

服务器上让代码生效

至于上传代码,则可以依靠强大的github来完成,其原理是更新本地代码,然后推送到github,然后登录服务器pull远程代码到本地,这样就实现了代码上传服务器。

cd /var/djangoweb/ictweb/ 
git status
git pull

其实也快成自己上传代码到服务器,只不过不便于多人协作管理。

###遇到的问题:
图片无法正常显示,需要使用static/images/logo.png这样的相对路径。

git合并冲突,需要先手动解决冲突,然后commit,之后就正常了。可以参考这里

下面是使用neo4j构建知识图谱的简明教程,通过一番折腾发现,学习使用一个工具最快的方法不是看文档,而是看视频,然后实操,并记录。

neo4j功能简介

neo4j是一个图形数据关联软件。

可以使用它来构建和维护知识图谱。

知识图谱是智能教育的基础,它是学习者画像、智能推荐、学习分析、智慧内容以及智能导师的前提。

本案例尝试使用三元组构建图谱,所谓三元组是:节点1-连接-节点2。

首先导入csv需要将文件放置在import文件夹中,从neo4j面板可以打开这个文件夹。

每次修改这个文件夹,可能需要重启neo4j,否则可能无法加载。另外确保文件名一致。

常用命令

清空已有节点和关系
MATCH (n) DETACH DELETE n

导入CSV文件

LOAD CSV WITH HEADERS FROM "file:///node1.csv" AS line
MERGE (z:概念1{name:line.node1}) 

LOAD CSV WITH HEADERS FROM "file:///node2.csv" AS line
MERGE (z:概念2{name:line.node2}) 

LOAD CSV WITH HEADERS FROM "file:///tup.csv" AS line  
match (from:概念1{name:line.node1}),(to:概念2{name:line.node2})  
merge (from)-[r:关联{name:line.link}]->(to)

导入并创建节点和关系

LOAD CSV FROM 'file:///tup.csv' AS line CREATE (:Map { linkID: line[0], nod1: line[1], link: line[2], nod2:line[3] });

LOAD CSV FROM 'file:///tup.csv' AS line 
CREATE (line[1])-[r:line[2]]->(line[3]);

显示所有关系

MATCH (n) RETURN (n)

MATCH (n:概念1{name:"细胞"}) RETURN n

MATCH (n:概念1{name:"细胞"})-[]-() RETURN n

利用apoc创建三元图

apoc是一个插件,需要先安装,然后才能调用。

创建概念1节点

LOAD CSV WITH HEADERS FROM "file:///node1.csv" AS line
call apoc.create.node(["Concept1",line.node1],{name:line.node1}) yield node
return node

创建概念2节点

LOAD CSV WITH HEADERS FROM "file:///node2.csv" AS line
call apoc.create.node(["Concept2",line.node2],{name:line.node2}) yield node
return node

创建关联

LOAD CSV WITH HEADERS FROM "file:///tup.csv" AS line
match (c1:Concept1{name:line.node1}),(c2:Concept2{name:line.node2}) 
call apoc.create.relationship(c1,line.link,line{.type},c2) yield rel
return rel

清除重复节点和关系

MATCH (n:Tag)
WITH n.name AS name, COLLECT(n) AS nodelist, COUNT(*) AS count
WHERE count > 1
CALL apoc.refactor.mergeNodes(nodelist) YIELD node
RETURN node

MATCH (n:Concept2)
WITH n.name AS name, COLLECT(n) AS nodelist, COUNT(*) AS count
WHERE count > 1
CALL apoc.refactor.mergeNodes(nodelist) YIELD node
RETURN node

MATCH (a:Concept1)-[r]-(b:Concept2)
WITH a, b, collect(r) as rels
CALL apoc.refactor.mergeRelationships(rels,{properties:"combine"})
YIELD rel 
RETURN count(rel)

路径查询命令

# 两节点之间的所有路径
MATCH p=(a)-[*]->(b)
RETURN p
# a->b 直接连接
MATCH p=(a)-[]->(b)
RETURN p

MATCH p=(:Concept1{name:"细胞"})-[]->(:Concept2{name:"蛋白质"})
RETURN p

# a-...>b a、b之间有三个关系及两个节点
# 等价于 (a) - () - () -> (b)
MATCH p=(a)-[*3]->(b)
RETURN p

# 路径包含2个以上关系
MATCH p=(a)-[*2..]->(b)
RETURN p

# 路径包含6个以内关系
MATCH p=(a)-[*..6]->(b)
RETURN p

# 路径包含3~5个关系
MATCH p=(a)-[*3..5]->(b)
RETURN p

通过三元组csv数据表创建概念网络

这个工作用cmap或者node4j都可以做,cmap适合简单的制图,node4j更适合在服务器端构建知识图谱。下面介绍一下如何通过node4j和一个数据表来生成图库。

部分csv数据表结构如下

hc link tc role
细胞 包含 细胞膜
细胞 包含 细胞质
细胞 多包含 细胞核
细胞 包含 三分之二

其中hc表示head Concept,tc表示tail concept, link是连续词,role是补充说明。

添加节点

LOAD CSV WITH HEADERS FROM "file:///relation.csv" AS line
call apoc.create.node(["Concept",line.hc],{name:line.hc}) yield node
return node

LOAD CSV WITH HEADERS FROM "file:///relation.csv" AS line
call apoc.create.node(["Concept",line.tc],{name:line.tc}) yield node
return node

去除重复节点

MATCH (n:Concept)
WITH n.name AS name, COLLECT(n) AS nodelist, COUNT(*) AS count
WHERE count > 1
CALL apoc.refactor.mergeNodes(nodelist) YIELD node
RETURN node

添加链接

LOAD CSV WITH HEADERS FROM "file:///relation.csv" AS line
match (c1:Concept{name:line.hc}),(c2:Concept{name:line.tc}) 
call apoc.create.relationship(c1,line.link,line{.role},c2) yield rel
return rel

查看效果

MATCH p=()-->() RETURN p LIMIT 100

MATCH p=(:Concept{name:"细胞"})-[]->(:Concept{name:"蛋白质"})
RETURN p

MATCH p=(:Concept{name:"细胞"})-[*]->(:Concept{name:"蛋白质"})
RETURN p

显示结果如下:
map show all the linke between conception cell and protein

修改和完善图谱

增加节点

CREATE (n:Person {name:'John'}) RETURN n

CREATE (n:Concept {name:'细胞呼吸'}) RETURN n

增加链接

MATCH (a:Person {name:'Liz'}), 
      (b:Person {name:'Mike'}) 
MERGE (a)-[:FRIENDS]->(b)

MATCH (a:Concept {name:'光合作用'}), 
      (b:Concept {name:'光反应'}) 
MERGE (a)-[:包含]->(b)

MATCH (a:Concept {name:'光合作用'}), 
      (b:Concept {name:'暗反应'}) 
MERGE (a)-[:包含]->(b)

MATCH p=(:Concept{name:"光合作用"})-[*..3]->()
RETURN p LIMIT 100

数据库操作

备份数据库

如果你对数据库进行了修改,想保留一个备份以备今后使用,那么可以使用neo4j-admin dump命令。

首先先停止服务,然后在shell环境下,运行:

bin/neo4j-admin dump --database=neo4j --to=/dumps/neo4j/neo4j-<timestamp>.dump

具体可以参考官方文档

加载数据库

你还可以使用neo4j-admin load命令加载一个数据库。如果是替换一个已有数据库,你需要先将其停止运行。

bin/neo4j-admin load --from=/dumps/neo4j/neo4j-<timestamp>.dump --database=neo4j --force

复制数据库

使用neo4j-admin copy复制或者选择性复制

STOP DATABASE neo4j

bin/neo4j-admin copy --from-database=neo4j --to-database=copy

ls -al ../data/databases

CREATE DATABASE copy

SHOW DATABASES

还可以筛选数据,下面的命令就是删除cat,dog标签的节点

bin/neo4j-admin copy --from-database=neo4j --to-database=copy --delete-nodes-with-labels="Cat,Dog"

参考官方文档

GWD下载页面,这样写道:Create engaging, interactive HTML5-based designs and motion graphics that can run on any device.

这是GWD对自己的定位,而我接触GWD则是因为再寻找一个替代animate动画制作软件。居然真的被我找到了。GWD应该说是一个不错的替代品。第一它是免费的,第二它是谷歌出品的,第三它支持脚本交互。此外,它符合个人的开发思维习惯。

除了用它可以实现基本动画之外,还可以用它开发小游戏,比如:https://html5advertising.de/2015/09/game-development-with-google-web-designer-ninja-jump-part-i/

视频教程:https://www.youtube.com/watch?v=BPa9Z_t-Wxo

此外,Patrick Voelcker还提供了一个作弊清单如下:

Google Web Designer API Cheatsheet

Change Content:

Textfield: 
gwd.actions.events.getElementById(textFieldId:String).​textContent​= content:String;

Image: 
gwd.actions.events.getElementById(imageId:String).​setAttribute(​"source", imageUrl:String);

Video Player: 
gwd.actions.events.getElementById(videoId:String).s​etAttribute(​"sources", videoUrls:String);

YouTube Player:
gwd.actions.gwdYoutube.​setYouTubeId​(ytPlayerId:String, ytId:String, cueOnly:Boolean);

Exit: 
gwd.actions.events.getElementById(tapAreaId:String).​setAttribute​("data­exit­url", url:String);

CSS: 
gwd.actions.events.s​etInlineStyle(​objectId:String, cssCode:String);

Timeline

gwd.actions.timeline.​play​(objectId:String);
gwd.actions.timeline.​pause​(objectId:String); 
gwd.actions.timeline.​togglePlay​(objectId:String); gwd.actions.timeline.​gotoAndPlay​(objectId:String, labelName:String); gwd.actions.timeline.​gotoAndPause​(objectId:String, labelName:String);

Page Deck

gwd.actions.gwdPagedeck.​goToPage(​'gwd­ad', pageId:String, transitionStyle:String, duration:Number, transitionTiming:String, direction:String)

TaP Aera

gwd.actions.events.getElementById(tapAreaId:String).​setAttribute(​"data­exit­url", url:String) gwd.actions.gwdIframe.​setUrl​(iframeId:String, url:String)
gwd.actions.gwdDoubleclick.​initAd​('gwd­ad');
gwd.actions.gwdDoubleclick.​goToPage​('gwd­ad', pageId:String, transitionStyle:String, duration:Number,
transitionTiming:String, direction:String); gwd.actions.gwdDoubleclick.​exit​('gwd­ad', exitName:String, url:String, collapse:Boolean, pauseMedia:Boolean);
gwd.actions.gwdDoubleclick.​exitOverride​('gwd­ad', exitName:String, url:String, collapse:Boolean, pauseMedia:Boolean);
gwd.actions.gwdDoubleclick.​incrementCounter​('gwd­ad', counterName:String, isCumulative:Boolean); 
gwd.actions.gwdDoubleclick.​startTimer​('gwd­ad', timerName:String); 
gwd.actions.gwdDoubleclick.​stopTimer​('gwd­ad', timerName:String); 
gwd.actions.gwdDoubleclick.​reportManualClose​('gwd­ad‘);
gwd.actions.gwdSwipegallery.​goToFrame​(galleryId:String, frameNumber:Number, transitionStyle:String); 
gwd.actions.gwdSwipegallery.​goForwards​(galleryId:String); 
gwd.actions.gwdSwipegallery.​goBackwards​(galleryId:String); 
gwd.actions.gwdSwipegallery.​rotateOnce​(galleryId:String, duration:Number, direction:String); 
gwd.actions.gwdSwipegallery.​stopRotation​(galleryId:String);
gwd.actions.gwdCarouselgallery.​goToFrame​(galleryId:String, frameNumber:Number, transitionStyle:String); 
gwd.actions.gwdCarouselgallery.​goForwards​(galleryId:String); 
gwd.actions.gwdCarouselgallery.​goBackwards​(galleryId:String); 
gwd.actions.gwdCarouselgallery.​rotateOnce​(galleryId:String, duration:Number, direction:String); 
gwd.actions.gwdCarouselgallery.​stopRotation​(galleryId:String);
gwd.actions.gwd360gallery.​goToFrame​(galleryId:String, frameNumber:Number, transitionStyle:String, direction:String);
gwd.actions.gwd360gallery.​goForwards​(galleryId:String); 
gwd.actions.gwd360gallery.​goBackwards​(galleryId:String); 
gwd.actions.gwd360gallery.​rotateOnce​(galleryId:String, duration:Number, direction:String);

Audio Player

gwd.actions.gwdAudio.​play​(audioPlayerId:String); 
gwd.actions.gwdAudio.​pause​(audioPlayerId:String); 
gwd.actions.gwdAudio.​mute​(audioPlayerId:String); 
gwd.actions.gwdAudio.​replay​(audioPlayerId:String); 
gwd.actions.gwdAudio.​seek​(audioPlayerId:String, time:Number);

Video Player

gwd.actions.gwdVideo.​play​(videoPlayerId:String); 
gwd.actions.gwdVideo.​pause​(videoPlayerId:String); 
gwd.actions.gwdVideo.​mute​(videoPlayerId:String); 
gwd.actions.gwdVideo.​replay​(videoPlayerId:String); 
gwd.actions.gwdVideo.​seek​(videoPlayerId:String, time:Number);

从整个开发流程上,GWD与早期的Flash是否相似,便于快速上手。只不过有缺憾的是,中文教程几乎没有,需要自己试水。

作为动画制作软件,我最先接触的是Flash,完全是出于兴趣自学的业余爱好者。但是,由于教学的需要,偶尔需要动画制作,于是居然摸索着做了不少动画作品。所以,一旦喜欢上什么,潜力是无限的。

新教师是一个特殊群体,他们有热情和理想,却缺乏资源和经验。他们是一群可能会在复杂教育生态中受伤的群体,他们也是教育改革的希望。不知道出于何种原因,新教师可能会承担超负荷的期望和工作量,也许是因为他们脾气好,又或者是他们还缺乏话语权,再或者是给别人别人也不干,最后又只能给新教师。

当然,也有别的可能,比如领导信任或者新教师主动承担额外的工作,但无论是哪一种原因,这都不错一个好兆头。原因是它可能让新教师急于开展教学,而无暇思考教学。如果一名新手生物学教师一周的工作量超过15节,那么就会有问题了,如果超过20节,那么,问题会非常大。原因是新教师需要双倍或更多的时间备课,而且还需要参与培训和班主任工作。

为什么需要那么长的时间呢,因为他们缺少特定主题的教学资源和教学经验,缺乏学科教学知识,也就是把一个内容主题用何种方式能让学生达成更好的理解的知识,比如如何举例,开展何种活动,如何组织,如何评价,使用何种资源,如何使用,这些问题会消耗新手教师相当多的时间。很多老师因此只能疲于应付,结果是简单潦草的教学,失去了教学原本应有的从容和快乐。

如何解决这个问题,如何让新手教师真正的喜欢上教学、热爱教学、学会教学、善于教学,教学资源就是一个所有老师都关心和期待解决的问题。它不是简单的提供和获取资源,它好包括利用和完善资源、创造和交流资源。教学资源成为教师专业成长的关键一环。

sublime 支持正则表达式

#(#{1,})    #可以匹配##,###,####,#####等

更多可以参考廖雪峰的博客:https://www.liaoxuefeng.com/wiki/1252599548343744/1304066080636961

sublime 支持多文件搜索和替换

也就是你可以打开一个文件夹,然搜索该文件夹的所有文件中,是否有指定字符

sublime 支持在replace中使用捕获的字符

find:

my name is (\w+)

replace:

my name used to be $1

在比如,我想把博文中所以##,###,####后面都加上一个空格

find:

"#(#{1,})"

replace:

"#$1 "

为了让大家看到那个空格,我都加了””,实际使用时去除””。

常用的HEXO命令

hexo g #完整命令为hexo generate,用于生成静态文件
hexo s #完整命令为hexo server,用于启动服务器,主要用来本地预览
hexo d #完整命令为hexo deploy,用于将本地文件发布到github上
hexo n #完整命令为hexo new,用于新建一篇文章
hexo g -d #两个命令的合成,一般在修改或者添加博文后直接使用这个命令

pyenv是一个python环境版本管理器,当你有甚多项目,但是用的python版本不同时,为了让程序运行,你需要设定特点的py版本。这时pyenv就能发挥作用了。pyenv也能让你装多个py版本。

# 查看当前版本
pyenv version
# 查看所有版本
pyenv versions
# 查看所有可安装的版本
pyenv install --list
# 安装指定版本
pyenv install 3.6.5
# 安装新版本后rehash一下
pyenv rehash
# 删除指定版本
pyenv uninstall 3.5.2
# 指定全局版本
pyenv global 3.6.5
# 指定多个全局版本, 3版本优先
pyenv global 3.6.5 2.7.14
# 实际上当你切换版本后, 相应的pip和包仓库都是会自动切换过去的

virtualenv是一个虚拟环境管理器,当你的呈现需要不同的程序包版本支持的时候,而且它们往往还是相互排斥的,那么你就可以用它来解决,首先你创建一个虚拟环境,然后在这个环境下安装所需要的包,这样就可以运行相应的呈现了,前提是你需要先进入并激活对应的虚拟环境。

参考:这里

创建并进入虚拟环境

cd code/python_envs
# 方式1:
mkvirtualenv envname01  # 创建完毕会自动进入该虚拟环境
# 方式2:
virtualenv envname02
workon envname02  # 进入该虚拟环境
# 方式3:
virtualenv envname03
cd envname03
source bin/activate  # 激活并进入虚拟环境

配置环境

pip3 install flask
pip3 install django
pip3 install Scipy 

退出环境

deactivate

基于某Python环境创建虚拟环境:

mkvirtualenv -p python2.7 envname01
mkvirtualenv -p python3.6 envname02

常用命令:

mkvirtualenv envname02 #创建并进入虚拟环境
mkvirtualenv -p python3.6 envname02 #基于某Python3.6环境创建虚拟环境
workon #列出虚拟环境:
deactivate #退出虚拟环境
workon envname02  # 切换虚拟环境2
pip3 install 模块名 #为虚拟环境安装模块
pip3 uninstall 模块名 #为虚拟环境卸载模块
lssitepackages  |  pip list  |  pip3 list #查看虚拟环境里安装了哪些包
cpvirtualenv env1 env2  # 复制环境 前面的是原文件 后面的拷贝后的新文件
rmvirtualenv env2  #删除虚拟环境

用pyenv安装python3.6.14遇到的坑

最近升级了Big Sur mac系统,但是用pyenv安装python3.6.14失活不成功,运行:

CFLAGS="-I$(brew --prefix openssl)/include -I$(brew --prefix bzip2)/include -I$(brew --prefix readline)/include -I$(xcrun --show-sdk-path)/usr/include" LDFLAGS="-L$(brew --prefix openssl)/lib -L$(brew --prefix readline)/lib -L$(brew --prefix zlib)/lib -L$(brew --prefix bzip2)/lib" pyenv install --patch 3.6.14 < <(curl -sSL https://github.com/python/cpython/commit/8ea6353.patch\?full_index\=1)

提示如下:

-c ./Modules/pwdmodule.c -o Modules/pwdmodule.o
./Modules/posixmodule.c:8210:15: error: implicit declaration of function 'sendfile' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
        ret = sendfile(in, out, offset, &sbytes, &sf, flags);
              ^
./Modules/posixmodule.c:10432:5: warning: code will never be executed [-Wunreachable-code]
    Py_FatalError("abort() called from Python code didn't abort!");
    ^~~~~~~~~~~~~
1 warning and 1 error generated.
make: *** [Modules/posixmodule.o] Error 1
make: *** Waiting for unfinished jobs....

后来,参考了这篇,运行了下面的代码:(功能是在bash_profile里添加环境判断):

echo -e 'if command -v pyenv 1>/dev/null 2>&1; then\n  eval "$(pyenv init -)"\nfi' >> ~/.bash_profile #添加环境判断
source ~/.bash_profile #更新配置文件

最终才成功安装,这个坑很深。

在线教学在疫情期间成为唯一教学选择,那么教师真实的教学体验如何?通过问卷我们收集到了一些老师的回答,量化数据分析还好说,但是对于老师们的文字反馈,确实让人头疼。

如果严格的分析,需要使用质性分析的方法,通过逐句逐句阅读和编码,形成初步的一级编码,然后对一级编辑进行概括和联系形成二级编码,最后识别主要的theme,进而对问题形成解释模型。但是,时间关系我根本来不及做这样的分析,我只想得到一个大体的结果,形成一个具有概括性的图示来揭示问题。

于是我首先对每个回答进行的标签标记,再经过3个半天的工作后,终于完成了对1000多条反馈的初步标记。最终形成18个重要的类别,不同的教师反馈的标签组合也不同。我最终获得的数据就是1000X18的一个数据表,某个标签出现标记为1,否则0。标签工作是做完了,但是我总不能把这么大的一个表展示给同行吧,于是任务的关键变成了如何将这个数据表可视化。于是我想到了python。我在做博士论文数据可视化的时候就用过,但是还是zoom quite帮我编的程序,这次又需要它救场了。

首先我查了一下python可视化的方法,很多,比较常用的法案是matplotlib+pandas+networkx,其中pandas对接数据,networkx对接网图,matplot对接制图。

可视化的关键是找到绘图思路,我的思路就是如果哪些关键词同时出现,那么这些关键词之间就存在联系,如果同时出现的频率越高,联系也就越紧,所以我想用数据绘制一个关键词网络,进而反应关键词之间的关系和主体划分。

下面我解释一下代码实现过程,下面就是完整的代码:

#!/usr/bin/python
# -*- coding: UTF-8 -*-

声明编码类型,这里选择UTF-8是为了兼容中英文。

# libraries
import pandas as pd
import numpy as np
import networkx as nx
import matplotlib.pyplot as plt

导入相应的库,python就一个优点,库多,没有找不到的,只有你想不到的,扩张了:)。

df = pd.read_csv('map.csv')  
#print df[1]

使用pd阅读csv文件,确保文件与程序文件在相同目录。

df=df.fillna(np.random.rand()*0.1)

填充缺省值,数据表中很多数据缺失,这里使用了一个小于0.1的随机数进行替换。

print(df.loc[0,:])

检测一下数据是否成功获取

# Calculate the correlation between individuals. We have to transpose first, because the corr function calculate the pairwise correlations between columns.
corr = df.corr()

# Transform it in a links data frame (3 columns only):
links = corr.stack().reset_index()
links.columns = ['var1', 'var2', 'value']

计算相关系数,并把计算结果储存在links中

# Keep only correlation over a threshold and remove self correlation (cor(A,A)=1)
links_filtered=links.loc[ (links['value'] > 0.1) & (links['var1'] != links['var2']) ]

筛选相关系数大于特点临界值的关联。

# Build your graph
G=nx.from_pandas_edgelist(links_filtered, 'var1', 'var2')
# Plot the network:
nx.draw(G, with_labels=True, node_color='orange', node_size=400, edge_color='black', linewidths=1, font_size=10)

基于links_filtered,利用nx构建和绘制网图

plt.show()

如果你的图没显示出来,上面的命令就是把绘制好的图展示出来。