“Talk is cheap, show me your code!”

当一个程序员在做技术分享的时候, 代码演示经常是不可或缺的一个环节。然而在你的演示PPT和代码运行之间切换是一件非常恼人事情,而且非常影响演示的节奏和流畅性。要做一个完美的技术分享,能不能把代码的运行嵌入到PPT中呢?

当然可以,我前不久(几年前把 )在公司内部分享了一起关于Python的小谜题,大家可以到斗鱼去观看这次分享的视频录播 (很糟糕的是在36分钟后,摄像头偏移了,拍了大半天挂钟)

为了实现代码嵌入ppt,我用到的关键技术包括:

  • Microsoft PowerPoint
  • Glot Code Runner
  • Docker

首先,演示常用的是微软的PowerPoint(至于苹果的Keynote,我暂时还没有找到解决方案),所以你需要安装PowerPoint,在最新的Office套件中,微软提供了一个Webview的插件,有了这个插件,可以直接把一个Web页面,嵌入到Office文档中,自然也就包含了PPT。

注意,为了安全性的考虑,嵌入的web页面必须是https的。

好了有了这个,我们就可以把一个代码运行的web页面直接嵌入到演示文档中,剩下的事情,就是做一个可以运行不同代码的Web应用了。

Glot 是一个开源的在线代码运行平台。其架构如下图所示。

利用Glot的代码运行的核心功能,我们就可以很方便的开发一个可以运行各种代码的web应用。

利用容器,我们可以把整个应用分为以下的几个层次:

  • Base
    提供基本的代码运行的环境,包含了代码执行的必要的解释器和编译器。在本次演示中,我使用了golang:latest,但是碰巧的是这个镜像是拥有Python的解释器的,我的代码演示都是python,省去了我安装Python的步骤。如果是别的不同的语言的演示,注意安装对应的环境。
  • Code Runner https://github.com/gangtao/code_runner
    我的Code Runner是对Glot的Code Runner的一个增强,该项目提供一个运行代码的服务。
    项目的Dockerfile:
FROM golang:latestMAINTAINER gangtao@outlook.comENV GOPATH=/home/glot
ENV GOROOT=/usr/local/go# Add user
RUN groupadd glot
RUN useradd -m -d /home/glot -g glot -s /bin/bash glot# Copy files
Add ./build/release/server /home/glot/
# Add ./vendor/. /home/glot/srcUSER glot
WORKDIR /home/glot/# generate certificate
RUN go run $GOROOT/src/crypto/tls/generate_cert.go --host localhostEXPOSE 8080# CMD ["/home/glot/runner"]
ENTRYPOINT ["/home/glot/server"]

  • 通过Dockerfile我们可以看出该项目主要的内容:利用Glot实现代码运行,产生证书用于https,利用echo实现web 服务。
    Web服务的代码如下:
package code_runnerimport ("fmt""github.com/prasmussen/glot-code-runner/cmd""github.com/prasmussen/glot-code-runner/language""io/ioutil""os""path/filepath"
)type Payload struct {Language string          `json:"language"`Files    []*InMemoryFile `json:"files"`Stdin    string          `json:"stdin"`Command  string          `json:"command"`
}type InMemoryFile struct {Name    string `json:"name"`Content string `json:"content"`
}type Result struct {Stdout string `json:"stdout"`Stderr string `json:"stderr"`Error  string `json:"error"`
}func Run(payload *Payload) *Result {// Ensure that we have at least one fileif len(payload.Files) == 0 {exitF("No files givenn")}// Check if we support given languageif !language.IsSupported(payload.Language) {exitF("Language '%s' is not supportedn", payload.Language)}// Write files to diskfilepaths, err := writeFiles(payload.Files)if err != nil {exitF("Failed to write file to disk (%s)", err.Error())}var stdout, stderr string// Execute the given command or run the code with// the language runner if no command is givenif payload.Command == "" {stdout, stderr, err = language.Run(payload.Language, filepaths, payload.Stdin)} else {workDir := filepath.Dir(filepaths[0])stdout, stderr, err = cmd.RunBashStdin(workDir, payload.Command, payload.Stdin)}result := &Result{Stdout: stdout,Stderr: stderr,Error:  errToStr(err),}return result
}// Writes files to disk, returns list of absolute filepaths
func writeFiles(files []*InMemoryFile) ([]string, error) {// Create temp dirtmpPath, err := ioutil.TempDir("", "")if err != nil {return nil, err}paths := make([]string, len(files), len(files))for i, file := range files {path, err := writeFile(tmpPath, file)if err != nil {return nil, err}paths[i] = path}return paths, nil
}// Writes a single file to disk
func writeFile(basePath string, file *InMemoryFile) (string, error) {// Get absolute path to file inside basePathabsPath := filepath.Join(basePath, file.Name)// Create all parent dirserr := os.MkdirAll(filepath.Dir(absPath), 0775)if err != nil {return "", err}// Write file to diskerr = ioutil.WriteFile(absPath, []byte(file.Content), 0664)if err != nil {return "", err}// Return absolute path to filereturn absPath, nil
}func exitF(format string, a ...interface{}) {fmt.Fprintf(os.Stderr, format, a...)os.Exit(1)
}func errToStr(err error) string {if err != nil {return err.Error()}return ""
}

  • 可以通过容器方便的启动该服务,然后就可以通过Rest请求,执行Python(Golang)的代码。
curl -X POST http://localhost:8080/run -H 'Content-Type: application/json' -d '{"language":"python","files":[{"name":"main.py","content":"print(42)"}]}'{"stdout":"42n","stderr":"","error":""}

  • 在这个项目中,我用了echo来实现一个轻量级的Web服务,而没有使用Glot自带的基于Ruby的服务,这样做的好处是技术栈的统一,因为echo和glot的核心都是用的Golang。
  • Code Runner Web https://github.com/gangtao/code_runner_web
    有了服务,下面就是前端的UI了。
    UI使用了codemirror来做编辑器。Dockerfile如下:
FROM naughtytao/code_runnerMAINTAINER gangtao@outlook.comAdd ./static /home/glot/static

  • 运行Code Runner Web后,就可以在以下的web界面中输入你想要运行的结果,并实时的显示想要运行的结果了。

好了,剩下的还有一些事情要做,就是准备你的演示代码,大家可以参考这个项目,这里缺省是将所有的代码片段放在code/python/ 目录下。运行:http://localhost:8080/#2 就会加载第二个代码片段。

这个是嵌入后的效果:

好了,是不是很Coooooool呢?

另外利用容器来构建应用真的非常非常方便。

页面 动态显示cmd执行结果_把代码执行演示嵌在你的PPT中相关推荐

  1. python如何执行代码漏洞_任意代码执行漏洞

    背景介绍 当应用在调用一些能将字符串转化成代码的函数(如php中的eval)时,没有考虑到用户是否能控制这个字符串,将造成代码注入漏洞.狭义的代码注入通常指将可执行代码注入到当前页面中,如php的ev ...

  2. 远程命令执行漏洞与远程代码执行漏洞33333

    远程命令执行漏洞的概念 远程命令执行漏洞,指用户通过浏览器提交执行操作命令, 由于服务器端,没有针对执行函数做过滤,就执行了恶意命令 远程代码执行漏洞概念 代码执行漏洞也叫代码注入漏洞,指用户通过浏览 ...

  3. rmi远程代码执行漏洞_fastjson远程代码执行漏洞复现

    漏洞原理fastjson提供了autotype功能,在请求过程中,我们可以在请求包中通过修改@type的值,来反序列化为指定的类型,而fastjson在反序列化过程中会设置和获取类中的属性,如果类中存 ...

  4. rmi远程代码执行漏洞_WebSphere 远程代码执行漏洞浅析(CVE20204450)

    作者:beijixiong404    文章来源:先知社区 漏洞简介 WebSphere是IBM的软件平台,它包含了编写.运行和监视全天候的工业强度的随需应变 Web 应用程序和跨平台.跨产品解决方案 ...

  5. 查询sql执行计划_使用SQL执行计划进行查询性能调整

    查询sql执行计划 In the previous articles of this series (see the index at bottom), we went through many as ...

  6. mysql sql执行cmd命令行_命令行执行MySQL的sql文件

    在项目开发过程中, 可能存在数据库导入导出,如果文件过大,会发现通过数据库(MySQL等)管理工具进行文件导入会报错,超出最大文件的限制. 需要更改工具的文件大小限制,网上有很多教程,比较麻烦,这里介 ...

  7. shellexecute 执行完成_用ShellExecute执行cmd命令遇到的问题总结

    1.如果命令中的路径包含空格,要把路径去掉头尾用双引号包含起来. 例:strPath = ""D:\\\"te st\\\"test.exe:(用"\ ...

  8. mysql运行正确结果显示_以下代码执行的结果是()

    1.链接完数据库后并没有选择数据库 2.sql中也没有给出 select id,namefrom tb1 . 3.sql 语句错误   select id,namefrom tb1. 4.MYSQL_ ...

  9. ssis 执行 依赖_从SSIS执行您自己的.NET控制台应用程序

    ssis 执行 依赖 介绍 (Introduction) The SSIS Script Task is a very powerful component to use in a SSIS pack ...

最新文章

  1. poj1012(约瑟夫环问题)
  2. spring bean scope作用域及多线程安全问题场景分析
  3. js 获取鼠标在画布的位置_javascript求鼠标在canvas画布里的坐标
  4. processing link链接
  5. 中法线如何反转_凹凸贴图、法线贴图、置换贴图傻傻分不清?
  6. JAVA程序中 + 号的使用
  7. 什么是Cookie对象,Session对象,Application对象等问题
  8. android 自定义库,Android自定义Log库
  9. SQL - 通过某个字段名称找到数据库中对应的表
  10. MSI/MSI-X Capability结构 (转)
  11. zookeeper使用分布式锁
  12. spring配置数据源错误记录
  13. 在Mysql中遇到关于区间范围内的索引优化
  14. mysql 三种循环的区别_mysql存储过程中的三种循环
  15. OA办公系统如何实现最佳界面效果
  16. Faraway(枚举 去绝对值)
  17. 王可欣作业一 统计软件简介与数据操作
  18. mysql查询慢的原因_MySQL查询缓慢的N种原因,以及N+1种解决方法
  19. 2020牛客暑期多校训练营Groundhog and Gaming Time(数学期望,线段树,逆元)
  20. 关于电信重组(华为中兴观察员出品,必属精品)

热门文章

  1. 完了!Oracle 被虐!MySQL 登顶 Top1!原来这么多人都在用
  2. 那个分分钟处理 10 亿节点图计算的 Plato,现在怎么样了?
  3. 从青铜到王者,来聊聊 Synchronized 底层实现原理 | 原力计划
  4. ​​​​​​​微信、Facebook牵手合作,抗击全球新冠肺炎疫情
  5. 微信小程序直播正式公测;刘强东 2020 年已卸任 8 家公司高管;React 16.13.0 发布| 极客头条...
  6. 延迟上班别发愁,远程办公抗疫情!
  7. 改写画质、突破性能, Unity 全面升级!
  8. 技术开发者应该如何构建小团队的微服务方案?
  9. 如何快速优化 Linux 内核 UDP 收包效率? | CSDN 博文精选
  10. 苹果输了,赔了高通 2 个亿