前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >下一个Github Copilot,Github Copilot Labs体验

下一个Github Copilot,Github Copilot Labs体验

作者头像
Moemu
发布2023-05-04 13:29:52
1.7K0
发布2023-05-04 13:29:52
举报
文章被收录于专栏:Moemu's NotepadMoemu's Notepad

本文部分内容由AI生成,其他内容由假扮AI的人类撰写

前言

GitHub Copilot Labs 是 GitHub Copilot 的升级版伴侣扩展,其中包含实验性和即将推出的功能。在Vscode上,它是一个侧边栏,其中包含的工具可以帮助您更好地理解代码,例如帮助我们翻译阅读难以理解的代码,根据语义一键生成其他语言的代码,修复潜在的Bugs,给函数加文档等。

如何获取

要获取Github Copilot Labs,您需要拥有Github Copilot的访问权限,然后去GitHub Next | GitHub Copilot Labs上获取访问权限,申请的过程不需要等待或者审核。

在Vscode上,安装GitHub Copilot Labs扩展,绑定Github账户即可使用。

侧边栏

一旦安装成功并且成功绑定账号,您应该会在侧边栏中看到GitHub Copilot Labs的选项卡。

GitHub Copilot Labs的选项卡
GitHub Copilot Labs的选项卡

功能

接下来我们分四个部分分别对四个功能集进行讲解。

Explain(代码解释)

Explain顾名思义就是解释代码,选择一个代码块来进行解释。

下面是一个加载动态Snackbar的函数,加载完成后会继续加载其他依赖,如果加载失败则抛出错误。

代码语言:javascript
复制
function LoadSnackbar(){
  const Snackbardependencies = [
    'https://cdn.jsdelivr.net/npm/node-snackbar@latest/src/js/snackbar.min.js',
    'https://cdn.jsdelivr.net/npm/node-snackbar@latest/dist/snackbar.min.css'
  ];

  Promise.all(Snackbardependencies.map(loadDependency))
    .then(() => {
      Snackbar.show({text:"少女祈祷中..",showAction:false,timeout:10000})
      LoadDependent();
    })
    .catch((error) => {
      Snackbar.close();
      console.error(`Error loading dependencies: ${error}`);
      Snackbar.show({text:"依赖加载失败",showAction:false})
    });
}

选中这个函数后,翻到Explain最下方,有个Ask Copilot按钮,按一下就可以进行解释。

这是生成的结果

代码语言:javascript
复制
/* Here is the explanation for the code above:
1. LoadSnackbar() is the main function. It will be called after the page is loaded.
2. Snackbardependencies is the list of dependencies that need to be loaded.
3. loadDependency() is a function that loads a single dependency. It returns a Promise.
4. LoadDependent() is the function that will be called after all dependencies are loaded.
5. The code in the .then() block will be executed after all dependencies are loaded.
6. The code in the .catch() block will be executed if any dependency fails to load. */

可以看到已经解释了函数的大致结构,至于一些小小的函数,例如Snackbar.show(...)则没有提到。不过可以通过单独选择来解释这些没解释到的东西。

Language Translation(语言转换)

看英文就可以知道,这是用来将某个函数用其他语言重写的功能。

以下给出了获取js文件中字体子集并转储为文件的函数,使用Python编写:

代码语言:javascript
复制
def GetCharacterSubset():
    with open('FortuneUpUp.js', 'r',encoding='utf-8') as f:
        js_text = f.read()
    # 去除单行注释
    js_text = re.sub(r'//.*?\n', '', js_text)
    # 去除多行注释
    js_text = re.sub(r'/\*.*?\*/', '', js_text, flags=re.DOTALL)
    # 提取中英文文本
    text_pattern = re.compile(r'[\u4e00-\u9fa5]+')
    text_list = re.findall(text_pattern, js_text)
    text_set = set(text_list)
    text_set = ''.join(text_set) + '0123456789' + 'abcdefghijklmnopqrstuvwxyz' + 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
    with open('text_set.txt', 'w',encoding='utf-8') as f:
        f.write(text_set)

选择代码块后,向下滑动找到Translate code into多选框,选一个目标语言即可,比如Cpp:

代码语言:javascript
复制
#include <iostream>
#include <fstream>
#include <string>
#include <regex>

using namespace std;

int main()
{
    string js_text;
    ifstream f;
    f.open("FortuneUpUp.js", ios::in);
    if (!f.is_open())
    {
        cout << "Open file \"FortuneUpUp.js\" failed." << endl;
        return 0;
    }
    getline(f, js_text, '\0');
    f.close();
    // 去除单行注释
    js_text = regex_replace(js_text, regex("//.*?\\n"), "");
    // 去除多行注释
    js_text = regex_replace(js_text, regex("/\\*.*?\\*/"), "", regex_constants::match_any);
    // 提取中英文文本
    string text_list = regex_replace(js_text, regex("[^\\u4e00-\\u9fa5]"), "");
    string text_set;
    for (auto c : text_list)
    {
        if (text_set.find(c) == string::npos)
        {
            text_set += c;
        }
    }
    text_set += "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
    f.open("text_set.txt", ios::out);
    if (!f.is_open())
    {
        cout << "Open file \"text_set.txt\" failed." << endl;
        return 0;
    }
    f << text_set;
    f.close();
    return 0;
}

好家伙,还修复了几个隐式bug,转写得好。

那么如果用CSS重写会发生什么?

第一次生成:

代码语言:javascript
复制
@charset "utf-8";
 */
.RtL {
 */
    position: absolute;
 */
    width: 100px;
 */
    height: 100px;
 */
    left: 0px;
 */
    top: 0px;
 */
    display: none;
 */
}
 */
.RtL .RtL_1 {
 */
    position: absolute;
 */
    width: 100px;
 */
    height: 100px;
 */
    left: 0px;
 */
    top: 0px;
 */
    background-image: url('images/1.png');
 */
}
 */
.RtL .RtL_2 {
 */
    position: absolute;
 */
    width: 100px;
 */
    height: 100px;
 */
    left: 0px;
 */
    top: 0px;
 */
    background-image: url('images/2.png');
 */
}
 */
......
.RtL .RtL_14 {
 */
    position: absolute;
 */
    width: 100px;
 */
    height: 100px;
 */
    left: 0px;
 */
    top: 0px;
 */
    background-image: url('images/14.png');
 */
}
 */
.RtL .RtL_15 {
 */
    position: absolute;
 */

第二次生成:

代码语言:javascript
复制
def GetCharacterSubset():
 */
    with open('FortuneUpUp.js', 'r',encoding='utf-8') as f:
 */
        js_text = f.read()
 */
    # 去除单行注释
 */
    js_text = re.sub(r'//.*?\n', '', js_text)
 */
    # 去除多行注释
 */
    js_text = re.sub(r'/\*.*?\*/', '', js_text, flags=re.DOTALL)
 */
    # 提取中英文文本
 */
    text_pattern = re.compile(r'[\u4e00-\u9fa5]+')
 */
    text_list = re.findall(text_pattern, js_text)
 */

好吧,第一次牛头不对马嘴,第二次就改了注释,还以为有报错,建议直接报错。

Brushes(刷子)

刷子里面就有很多的功能了。

Readable(可读性)

增加代码可读性。下面给出了获取Cookie的函数:

代码语言:javascript
复制
function getCookie(cname) {
  var name = cname + "=";
  var decodedCookie = decodeURIComponent(document.cookie);
  var ca = decodedCookie.split(';');
  for(var i = 0; i <ca.length; i++) {
    var c = ca[i];
    while (c.charAt(0) == ' ') {
      c = c.substring(1);
    }
    if (c.indexOf(name) == 0) {
      return c.substring(name.length, c.length);
    }
  }
  return "";

改动后如下:

代码语言:javascript
复制
function getCookie(cname) {
  var name = cname + "=";
  var decodedCookie = decodeURIComponent(document.cookie);
  var cookieArray = decodedCookie.split(';');
  for(var i = 0; i < cookieArray.length; i++) {
    var cookie = cookieArray[i];
    while (cookie.charAt(0) == ' ') {
      cookie = cookie.substring(1);
    }
    if (cookie.indexOf(name) == 0) {
      return cookie.substring(name.length, cookie.length);
    }
  }
  return "";
}

cac变量换成了可读性更高的cookieArray, cookie,更加容易维护了

Addtypes(加入Types)

主要用于typescript的编写,能够自动加入一些Types

执行前代码

代码语言:javascript
复制
let options = [
  { name: '大吉', probability: 0.2 },
  { name: '中吉', probability: 0.4 },
  { name: '小吉', probability: 0.3 },
  { name: '不太吉', probability: 0.1 }
];

执行后代码如下

代码语言:javascript
复制
let options: Array<{
  name: string,
  probability: number
}> = [
  { name: '大吉', probability: 0.2 },
  { name: '中吉', probability: 0.4 },
  { name: '小吉', probability: 0.3 },
  { name: '不太吉', probability: 0.1 }
];

Fixbug(修复bug)

很显然是用来修复bug的,比如代码检测器发现的bug或者是不按预期工作的代码块。

下面给出了一个新手容易犯错的代码。

代码语言:javascript
复制
def main():
    a = 1
    a + 1
    print(a) # 2(Fact: 1)

接下来让我们执行这个功能

代码语言:javascript
复制
def main():
    a = 1
    a += 1
    print(a) # 2

这下就能输出2

Debug(Debug输出)

在程序测试时输出更多的变量以便于debug。

下面给出了一个非常多变量的函数,这个函数有非常多的变量,因此我们需要debug以防止出错

代码语言:javascript
复制
function GetFestivalFortune(){
  let today = new Date();
  let month = ("0" + (today.getMonth() + 1)).slice(-2);
  let day = ("0" + today.getDate()).slice(-2);
  let FestivalEventsList = [];
  let FestivalEvent = null;
  let GoodEventList = [];
  let BadEventList = [];
  let isFestival = 0;
  for(i = 0;i < SpecialFestivalEvents.length;i++){
    let FestivalDate = SpecialFestivalEvents[i]["Date"];
    if(FestivalDate.indexOf("L") == 0){
      FestivalDate = FestivalDate.replace("L","").split(".");
      FestivalDate = GetLunarFestivalDate(FestivalDate[0],FestivalDate[1])
      FestivalDate = ("0" + (FestivalDate[0])).slice(-2) + "." + ("0" + FestivalDate[1]).slice(-2);
    }
    if(FestivalDate == month+"."+day){
      FestivalEventsList.push(SpecialFestivalEvents[i]);
    }
  }
  for(i = 0;i < NormalFestivalDateList.length;i++){
    if(NormalFestivalDateList[i] == month+"."+day){
      FestivalEventsList.push(NormalFestivalEvents);
    }
  }
  // 生成GoodEventList和BadEventList
  if(FestivalEventsList.length > 1){
    //同一个节日有多个事件时,随机抽取一个
    FestivalEvent = FestivalEventsList[Math.floor(Math.random()*FestivalEventsList.length)];
  }else if(FestivalEventsList.length == 1){
    FestivalEvent = FestivalEventsList[0];
  };
  if(FestivalEvent != null){
    if(FestivalEvent["bad"] != null){
      if(Math.random() > 0.6){
        GoodEventList.push(FestivalEvent);
        isFestival = 1;
      }else{
        BadEventList.push(FestivalEvent);
        isFestival = -1;
      }
    }else{
      GoodEventList.push(FestivalEvent);
      isFestival = 1;
    }
  }
  return [GoodEventList,BadEventList,isFestival];
}

更改代码后如下:

代码语言:javascript
复制
function GetFestivalFortune(){
  console.log("GetFestivalFortune");
  let today = new Date();
  console.log("today",today);
  let month = ("0" + (today.getMonth() + 1)).slice(-2);
  console.log("month",month);
  let day = ("0" + today.getDate()).slice(-2);
  console.log("day",day);
  let FestivalEventsList = [];
  let FestivalEvent = null;
  let GoodEventList = [];
  let BadEventList = [];
  let isFestival = 0;
  for(i = 0;i < SpecialFestivalEvents.length;i++){
    console.log("i",i);
    let FestivalDate = SpecialFestivalEvents[i]["Date"];
    console.log("FestivalDate",FestivalDate);
    if(FestivalDate.indexOf("L") == 0){
      FestivalDate = FestivalDate.replace("L","").split(".");
      console.log("FestivalDate",FestivalDate);
      FestivalDate = GetLunarFestivalDate(FestivalDate[0],FestivalDate[1])
      console.log("FestivalDate",FestivalDate);
      FestivalDate = ("0" + (FestivalDate[0])).slice(-2) + "." + ("0" + FestivalDate[1]).slice(-2);
      console.log("FestivalDate",FestivalDate);
    }
    if(FestivalDate == month+"."+day){
      FestivalEventsList.push(SpecialFestivalEvents[i]);
      console.log("FestivalEventsList",FestivalEventsList);
    }
  }
  for(i = 0;i < NormalFestivalDateList.length;i++){
    if(NormalFestivalDateList[i] == month+"."+day){
      FestivalEventsList.push(NormalFestivalEvents);
      console.log("FestivalEventsList",FestivalEventsList);
    }
  }
  // 生成GoodEventList和BadEventList
  if(FestivalEventsList.length > 1){
    //同一个节日有多个事件时,随机抽取一个
    FestivalEvent = FestivalEventsList[Math.floor(Math.random()*FestivalEventsList.length)];
    console.log("FestivalEvent",FestivalEvent);
  }else if(FestivalEventsList.length == 1){
    FestivalEvent = FestivalEventsList[0];
    console.log("FestivalEvent",FestivalEvent);
  };
  if(FestivalEvent != null){
    if(FestivalEvent["bad"] != null){
      if(Math.random() > 0.6){
        GoodEventList.push(FestivalEvent);
        console.log("GoodEventList",GoodEventList);
        isFestival = 1;
        console.log("isFestival",isFestival);
      }else{
        BadEventList.push(FestivalEvent);
        console.log("BadEventList",BadEventList);
        isFestival = -1;
        console.log("isFestival",isFestival);
      }
    }else{
      GoodEventList.push(FestivalEvent);
      console.log("GoodEventList",GoodEventList);
      isFestival = 1;
      console.log("isFestival",isFestival);
    }
  }
  return [GoodEventList,BadEventList,isFestival];
}

可以看到增加了些console.log()函数来输出变量,这下所有变量的变化情况就了如指掌了。

Clean(清理代码)

清理代码中没有使用的变量或函数。

下面的函数只是使用了a,b,c三个变量,没有使用d,e变量

代码语言:javascript
复制
def main():
    a = 1
    b = 2
    c = 3
    d = 4
    e = 5
    print(a, b, c)

执行后d,e变量被删除。

代码语言:javascript
复制
def main():
    a = 1
    b = 2
    c = 3
    print(a, b, c)

List Steps(一对一注释)

给每一行(或代码块)都添加注释。

下面是一个读取Cookie的函数:

代码语言:javascript
复制
function ReadCookie(){ //读取cookie,如果有cookie则直接读取,否则返回False
  let Fortune = getCookie("Fortune");
  let GoodEventList = getCookie("GoodEventList");
  let BadEventList = getCookie("BadEventList");
  if(Fortune != "" && GoodEventList != "" && BadEventList != ""){
    GoodEventList = JSON.parse(GoodEventList);
    BadEventList = JSON.parse(BadEventList);
    return [Fortune,GoodEventList,BadEventList];
  }else{
    return false;
  }

执行后发现每一行的代码都添加了注释。

代码语言:javascript
复制
function ReadCookie(){ //读取cookie,如果有cookie则直接读取,否则返回False
  let Fortune = getCookie("Fortune"); //获取Fortune的cookie
  let GoodEventList = getCookie("GoodEventList"); //获取GoodEventList的cookie
  let BadEventList = getCookie("BadEventList"); //获取BadEventList的cookie
  if(Fortune != "" && GoodEventList != "" && BadEventList != ""){ //如果三个cookie都存在
    GoodEventList = JSON.parse(GoodEventList); //将字符串转为数组
    BadEventList = JSON.parse(BadEventList); //将字符串转为数组
    return [Fortune,GoodEventList,BadEventList]; //返回数组
  }else{
    return false;
  }

Make Robust(更稳定)

增加代码可靠度,防止因为传入不合法的参数而导致程序崩溃

代码语言:javascript
复制
function GetLunarFestivalDate(month, day) {
    let today = new Date();
    let year = today.getFullYear();
    let lunarDate = lunar2solar(year, month, day);
    return [lunarDate[1],lunarDate[2]];
}
代码语言:javascript
复制
function GetLunarFestivalDate(month, day) {
    let today = new Date();
    let year = today.getFullYear();
    let lunarDate = lunar2solar(year, month, day);
    if (lunarDate[0] != year) {
        lunarDate = lunar2solar(year+1, month, day);
    }
    return [lunarDate[1],lunarDate[2]];
}

Chunk(代码分块)

写代码时,一个函数写得非常长是比较禁忌的,这会使得代码的可读性下降,这时候,将一个函数拆分为几个函数就显得非常重要。

代码语言:javascript
复制
def GetCharacterSubset():
    with open('FortuneUpUp.js', 'r',encoding='utf-8') as f:
        js_text = f.read()
    # 去除单行注释
    js_text = re.sub(r'//.*?\n', '', js_text)
    # 去除多行注释
    js_text = re.sub(r'/\*.*?\*/', '', js_text, flags=re.DOTALL)
    # 提取中英文文本
    text_pattern = re.compile(r'[\u4e00-\u9fa5]+')
    text_list = re.findall(text_pattern, js_text)
    text_set = set(text_list)
    text_set = ''.join(text_set) + '0123456789' + 'abcdefghijklmnopqrstuvwxyz' + 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
    with open('text_set.txt', 'w',encoding='utf-8') as f:
        f.write(text_set)
代码语言:javascript
复制
def GetCharacterSubset():
    js_text = GetJsText()
    js_text = RemoveComment(js_text)
    text_set = ExtractChineseAndEnglish(js_text)
    SaveResult(text_set)

分块后的创建的新函数还需要通过新建几行来使Copilot生成。

而且Copilot有行数限制,写函数的时候还需要自己注意点。

Document(生成函数文档)

顾名思义,给函数生成使用文档。

不过实际测试之中,效果不是很好

代码语言:javascript
复制
def count_time(stime,etime):
    if stime in ('无',None):
        return 0
    from datetime import datetime
    st=datetime.strptime(stime,'%Y-%m-%d %H:%M')
    et=datetime.strptime(etime,'%Y-%m-%d %H:%M')
    return round(((et-st).days),2)
代码语言:javascript
复制
def count_time(stime,etime):
    """
    计算两个时间之间的间隔
    :param stime: 开始时间
    :param etime: 结束时间
    :return: 间隔天数
    """
    if stime in ('无',None):
        return 0
    from datetime import datetime
    st=datetime.strptime(stime,'%Y-%m-%d %H:%M')
    et=datetime.strptime(etime,'%Y-%m-%d %H:%M')
    return round(((et-st).days),2)

Custom(个性化)

直接向AI发送修改任务。

下面代码的修改目标 —— Rewrite without datetime

代码语言:javascript
复制
def count_time(stime,etime):
    if stime in ('无',None):
        return 0
    from datetime import datetime
    st=datetime.strptime(stime,'%Y-%m-%d %H:%M')
    et=datetime.strptime(etime,'%Y-%m-%d %H:%M')
    return round(((et-st).days),2)

修改后的代码

代码语言:javascript
复制
def count_time(stime,etime):
    if stime in ('无',None):
        return 0
    #from datetime import datetime
    #st=datetime.strptime(stime,'%Y-%m-%d %H:%M')
    #et=datetime.strptime(etime,'%Y-%m-%d %H:%M')
    stime = stime.split(' ')
    etime = etime.split(' ')
    stime = stime[0].split('-')
    etime = etime[0].split('-')
    st = [int(i) for i in stime]
    et = [int(i) for i in etime]
    st = st[0]*365 + st[1]*30 + st[2]
    et = et[0]*365 + et[1]*30 + et[2]
    return round((et-st),2)

后话

先写到这里,得上学了,总体上是大幅提升了编程体验,但是个人感觉比GPT 3.5略逊一筹(如果openai关掉cf的话),而且bug比较多,有时候会大量生成重复的代码。对于咱来说,还是不够火候。

我的博客即将同步至腾讯云开发者社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=74ll4y7102kq

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-04-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 如何获取
  • 侧边栏
  • 功能
    • Explain(代码解释)
      • Language Translation(语言转换)
        • Brushes(刷子)
          • Readable(可读性)
          • Addtypes(加入Types)
          • Fixbug(修复bug)
          • Debug(Debug输出)
          • Clean(清理代码)
          • List Steps(一对一注释)
          • Make Robust(更稳定)
          • Chunk(代码分块)
          • Custom(个性化)
      • 后话
      相关产品与服务
      云开发 CloudBase
      云开发(Tencent CloudBase,TCB)是腾讯云提供的云原生一体化开发环境和工具平台,为200万+企业和开发者提供高可用、自动弹性扩缩的后端云服务,可用于云端一体化开发多种端应用(小程序、公众号、Web 应用等),避免了应用开发过程中繁琐的服务器搭建及运维,开发者可以专注于业务逻辑的实现,开发门槛更低,效率更高。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档