EOS开发实战


  在上一篇文章《EOS开发入门》中,我们为大家介绍了EOS的节点启动和合约部署和调用等入门知识。本次我们来实现一个复杂的例子,可以为其取一个高大上的名字-悬赏任务管理系统。这可以是我们身边的一个例子,在工作中我们也许会碰到需要周围人帮助实现工作以外的问题,这往往需要靠交情来做到。我们使用eos可以实现这样一个任务管理系统,任务发起人可以发布一个任务给某个赏金猎人,指定任务的赏金。在任务完成后,发起人将约定的赏金交给完成者。

1. 合约设计

  通过故事背景介绍,我们可以察觉我们需要支付赏金的部分,这个可以使用区块链的token来实现。另外还需要一个实现一个对任务的管理,token的实现可以直接使用eosio.token,任务的管理我们需要实现3个action,创建任务,提交任务,验收任务。总结如下:

  • token合约:创建,发行,转账

  • task合约:创建,提交,验收

2. 合约实现

任务需要包含的信息:

  1. struct [[eosio::table]] task {
  2. uint64_t taskID;//任务编号
  3. name creator; //创建者
  4. name worker;//执行者
  5. asset bonus;//承诺奖励
  6. uint8_t status = 0;//状态
  7. string remark;//任务描述
  8. string comment;//评价
  9. uint64_t primary_key()const { return taskID; }
  10. };

2.1 token合约

  • pdjtoken.hpp
  1. /**
  2. * @file pdjtoken.hpp
  3. * @company http://pdjedu.com/
  4. */
  5. #pragma once
  6. #include <eosiolib/asset.hpp>
  7. #include <eosiolib/eosio.hpp>
  8. #include <string>
  9. namespace eosiosystem {
  10. class system_contract;
  11. }
  12. namespace eosio {
  13. using std::string;
  14. class [[eosio::contract("pdjtoken")]] pdjtoken : public contract {
  15. public:
  16. using contract::contract;
  17. pdjtoken(name receiver, name code, datastream<const char*> ds): contract(receiver, code, ds) {}
  18. [[eosio::action]]
  19. void create( name issuer,
  20. asset maximum_supply);
  21. [[eosio::action]]
  22. void issue( name to, asset quantity, string memo );
  23. [[eosio::action]]
  24. void transfer( name from,
  25. name to,
  26. asset quantity,
  27. string memo );
  28. private:
  29. inline asset get_supply( name token_contract_account, symbol_code sym_code )const;
  30. inline asset get_balance( name token_contract_account, name owner, symbol_code sym_code )const;
  31. private:
  32. struct [[eosio::table]] account {
  33. asset balance;
  34. uint64_t primary_key()const { return balance.symbol.code().raw(); }
  35. };
  36. struct [[eosio::table]] currency_stats {
  37. asset supply;
  38. asset max_supply;
  39. name issuer;
  40. uint64_t primary_key()const { return supply.symbol.code().raw(); }
  41. };
  42. typedef eosio::multi_index< "accounts"_n, account > accounts;
  43. typedef eosio::multi_index< "stat"_n, currency_stats > stats;
  44. void sub_balance( name owner, asset value );
  45. void add_balance( name owner, asset value, name ram_payer );
  46. };
  47. asset pdjtoken::get_supply( name token_contract_account, symbol_code sym_code )const
  48. {
  49. stats statstable( token_contract_account, sym_code.raw() );
  50. const auto& st = statstable.get( sym_code.raw() );
  51. return st.supply;
  52. }
  53. asset pdjtoken::get_balance( name token_contract_account, name owner, symbol_code sym_code )const
  54. {
  55. accounts accountstable( token_contract_account, owner.value );
  56. const auto& ac = accountstable.get( sym_code.raw() );
  57. return ac.balance;
  58. }
  59. } /// namespace eosio
  • pdjtoken.cpp
  1. /**
  2. * @file pdjtoken.cpp
  3. * @copyright http://pdjedu.com/
  4. */
  5. #include "pdjtoken.hpp"
  6. namespace eosio {
  7. //创建
  8. void pdjtoken::create( name issuer,
  9. asset maximum_supply )
  10. {
  11. require_auth( _self );
  12. auto sym = maximum_supply.symbol;
  13. eosio_assert( sym.is_valid(), "invalid symbol name" );
  14. eosio_assert( maximum_supply.is_valid(), "invalid supply");
  15. eosio_assert( maximum_supply.amount > 0, "max-supply must be positive");
  16. stats statstable( _self, sym.code().raw() );
  17. auto existing = statstable.find( sym.code().raw() );
  18. eosio_assert( existing == statstable.end(), "token with symbol already exists" );
  19. statstable.emplace( _self, [&]( auto& s ) {
  20. s.supply.symbol = maximum_supply.symbol;
  21. s.max_supply = maximum_supply;
  22. s.issuer = issuer;
  23. });
  24. }
  25. //发行
  26. void pdjtoken::issue( name to, asset quantity, string memo )
  27. {
  28. auto sym = quantity.symbol;
  29. eosio_assert( sym.is_valid(), "invalid symbol name" );
  30. eosio_assert( memo.size() <= 256, "memo has more than 256 bytes" );
  31. stats statstable( _self, sym.code().raw() );
  32. auto existing = statstable.find( sym.code().raw() );
  33. eosio_assert( existing != statstable.end(), "token with symbol does not exist, create token before issue" );
  34. const auto& st = *existing;
  35. require_auth( st.issuer );
  36. eosio_assert( quantity.is_valid(), "invalid quantity" );
  37. eosio_assert( quantity.amount > 0, "must issue positive quantity" );
  38. eosio_assert( quantity.symbol == st.supply.symbol, "symbol precision mismatch" );
  39. eosio_assert( quantity.amount <= st.max_supply.amount - st.supply.amount, "quantity exceeds available supply");
  40. statstable.modify( st, same_payer, [&]( auto& s ) {
  41. s.supply += quantity;
  42. });
  43. add_balance( st.issuer, quantity, st.issuer );
  44. if( to != st.issuer ) {
  45. SEND_INLINE_ACTION( *this, transfer, { {st.issuer, "active"_n} },
  46. { st.issuer, to, quantity, memo }
  47. );
  48. }
  49. }
  50. //转账
  51. void pdjtoken::transfer( name from,
  52. name to,
  53. asset quantity,
  54. string memo )
  55. {
  56. eosio_assert( from != to, "cannot transfer to self" );
  57. require_auth( from );
  58. eosio_assert( is_account( to ), "to account does not exist");
  59. auto sym = quantity.symbol.code();
  60. stats statstable( _self, sym.raw() );
  61. const auto& st = statstable.get( sym.raw() );
  62. require_recipient( from );
  63. require_recipient( to );
  64. eosio_assert( quantity.is_valid(), "invalid quantity" );
  65. eosio_assert( quantity.amount > 0, "must transfer positive quantity" );
  66. eosio_assert( quantity.symbol == st.supply.symbol, "symbol precision mismatch" );
  67. eosio_assert( memo.size() <= 256, "memo has more than 256 bytes" );
  68. auto payer = has_auth( to ) ? to : from;
  69. sub_balance( from, quantity );
  70. add_balance( to, quantity, payer );
  71. }
  72. void pdjtoken::sub_balance( name owner, asset value ) {
  73. accounts from_acnts( _self, owner.value );
  74. const auto& from = from_acnts.get( value.symbol.code().raw(), "no balance object found" );
  75. eosio_assert( from.balance.amount >= value.amount, "overdrawn balance" );
  76. from_acnts.modify( from, owner, [&]( auto& a ) {
  77. a.balance -= value;
  78. });
  79. }
  80. void pdjtoken::add_balance( name owner, asset value, name ram_payer )
  81. {
  82. accounts to_acnts( _self, owner.value );
  83. auto to = to_acnts.find( value.symbol.code().raw() );
  84. if( to == to_acnts.end() ) {
  85. to_acnts.emplace( ram_payer, [&]( auto& a ){
  86. a.balance = value;
  87. });
  88. } else {
  89. to_acnts.modify( to, same_payer, [&]( auto& a ) {
  90. a.balance += value;
  91. });
  92. }
  93. }
  94. } /// namespace eosio
  95. EOSIO_DISPATCH( eosio::pdjtoken, (create)(issue)(transfer) )

2.2 task合约

  • pdjtask.hpp
  1. /**
  2. * @file pdjtask.hpp
  3. * @company http://pdjedu.com/
  4. */
  5. #pragma once
  6. #include <eosiolib/asset.hpp>
  7. #include <eosiolib/eosio.hpp>
  8. #include <string>
  9. namespace eosiosystem {
  10. class system_contract;
  11. }
  12. namespace eosio {
  13. using std::string;
  14. class [[eosio::contract]] pdjtask : public contract {
  15. public:
  16. pdjtask(name receiver, name code, datastream<const char*> ds): contract(receiver, code, ds) {}
  17. //创建任务
  18. [[eosio::action]]
  19. void createtk( name creator, name worker, asset taskBonus, string memo );
  20. //提交任务
  21. [[eosio::action]]
  22. void commit( uint64_t taskID, string memo );
  23. //验收任务
  24. [[eosio::action]]
  25. void confirm( uint64_t taskID, uint8_t ok = 1 );
  26. private:
  27. struct [[eosio::table]] task {
  28. uint64_t taskID;
  29. name creator;
  30. name worker;
  31. asset bonus;
  32. uint8_t status = 0;
  33. string remark;
  34. string comment;
  35. uint64_t primary_key()const { return taskID; }
  36. };
  37. typedef eosio::multi_index< "tasks"_n, task > tasks;
  38. private:
  39. /*
  40. void transfer( name from,
  41. name to,
  42. asset quantity,
  43. string memo );
  44. */
  45. void task_commit(name from, name to, asset bonus, string memo) {
  46. action act = action(
  47. permission_level{from,"active"_n},
  48. "pdjtoken"_n,
  49. "transfer"_n,
  50. std::make_tuple(from, to, bonus, memo)
  51. );
  52. act.send();
  53. }
  54. };
  55. } /// namespace eosio
  • pdjtask.cpp
  1. /**
  2. * @file pdjtask.cpp
  3. * @company http://pdjedu.com/
  4. */
  5. #include "pdjtask.hpp"
  6. namespace eosio {
  7. //创建任务
  8. void pdjtask::createtk( name creator, name worker, asset taskBonus, string memo )
  9. {
  10. require_auth(creator);
  11. //require_auth(worker);
  12. auto sym = taskBonus.symbol;
  13. eosio_assert( sym.is_valid(), "invalid symbol name" );
  14. tasks tk( _code, _code.value );
  15. tk.emplace( creator, [&](auto &t){
  16. t.creator = creator;
  17. t.worker = worker;
  18. t.taskID = tk.available_primary_key();
  19. t.bonus = taskBonus;
  20. t.remark = memo;
  21. });
  22. }
  23. //提交任务
  24. void pdjtask::commit( uint64_t taskID, string memo )
  25. {
  26. //提交任务者必须与任务分配者是一个人
  27. print("hi,",name{_self});
  28. //require_auth(worker);
  29. tasks tk( _code, _code.value );
  30. auto tkobj = tk.find(taskID);
  31. eosio_assert( tkobj != tk.end(), "taskid not exists" );
  32. require_auth(tkobj->worker );
  33. //eosio_assert( tkobj->worker == worker, "worker not same" );
  34. tk.modify(tkobj, tkobj->worker ,[&](auto &t){
  35. t.status = 1;
  36. t.comment = memo;
  37. });
  38. }
  39. //验收任务
  40. void pdjtask::confirm( uint64_t taskID, uint8_t ok )
  41. {
  42. //require_auth(creator);
  43. tasks tk( _code, _code.value );
  44. auto tkobj = tk.find(taskID);
  45. eosio_assert( tkobj != tk.end(), "taskid not exists" );
  46. uint8_t status = 2;
  47. print("confirm---",name{tkobj->creator});
  48. require_auth(tkobj->creator);
  49. if ( !ok ) {
  50. // re do
  51. status = 0;
  52. }
  53. tk.modify(tkobj, tkobj->creator, [&](auto &t){
  54. t.status = status;
  55. t.comment = "well done!";
  56. });
  57. if ( ok ){
  58. //发币刺激
  59. //transfer( creator, tkobj->worker, tkobj->bonus, "very good!" );
  60. task_commit(tkobj->creator, tkobj->worker, tkobj->bonus, "very good!");
  61. }
  62. }
  63. } /// namespace eosio
  64. EOSIO_DISPATCH( eosio::pdjtask, (createtk)(commit)(confirm) )

3. eosjs调用合约

  在合约编写完成后,我们还需要编写一个页面来调用智能合约,这就需要用到eosjs。eosjs集成了EOSIO RPC API,用于与EOS区块链交互,查阅官方文档可获取更多详细信息。



monkeysun和laowang已经收到了任务奖励的token

3.1 核心代码

  • index.js
  1. $(function() {
  2. var userAccount;
  3. var userPrivateKey;
  4. $("#LoginWindow").modal();
  5. $(".Login").on("click", function() {
  6. userAccount = $("#userAcc").val();
  7. userPrivateKey = $("#PrivateKey").val();
  8. config = {
  9. chainId: 'cf057bbfb72640471fd910bcb67639c22df9f92470936cddc1ade0e2f2e7dc4f', // 32 byte (64 char) hex string
  10. keyProvider: [userPrivateKey], // WIF string or array of keys.. //5J2ZC6ZbtoFnTsZofTnMaTQmZSkdx9DnM9QZbuYTvDS2AgQaGzX
  11. httpEndpoint: 'http://127.0.0.1:8888',
  12. expireInSeconds: 60,
  13. broadcast: true,
  14. verbose: false, // API activity
  15. sign: true
  16. }
  17. eos = Eos(config);
  18. eos.getAccount(userAccount).then(result => {
  19. console.log(result);
  20. alert("欢迎回来," + userAccount);
  21. $(".userName span:nth-child(2)").html("账户:" + userAccount);
  22. getBalance();
  23. }).catch(err => {
  24. console.log(err);
  25. alert("错误:账户不存在!");
  26. });
  27. $(".close_win").click();
  28. getTaskList();
  29. });
  30. //发布任务
  31. $(".Createtk").on("click", function() {
  32. console.log("发布任务");
  33. console.log(userPrivateKey);
  34. $("#ReleaseTask").modal();
  35. getTaskList();
  36. });
  37. //确认发布任务
  38. $(".ConfirmRelease").on("click", function() {
  39. var WorkerAcc = $("#GetWorker").val();
  40. var TaskToken = $("#GetToken").val();
  41. var TaskInfo = $("#GetTaskInfo").val();
  42. console.log(WorkerAcc,TaskToken,TaskInfo);
  43. $(".close_win").click();
  44. eos.transaction({
  45. actions: [
  46. {
  47. account: 'pdjtask',
  48. name: 'createtk',
  49. authorization: [{
  50. actor: userAccount,
  51. permission: 'active'
  52. }],
  53. data: {
  54. creator: userAccount,
  55. worker: WorkerAcc,
  56. taskBonus: TaskToken,
  57. memo: TaskInfo
  58. }
  59. }
  60. ]
  61. }).then(result => {
  62. console.log(result);
  63. alert("发布成功!");
  64. getTaskList();
  65. })
  66. .catch(error => {console.error(error);alert("发生错误!" + error)});
  67. });
  68. //领取任务
  69. $(".Receive").on("click", function() {
  70. console.log("领取任务");
  71. $("#ReceiveTask").modal();
  72. getTaskList();
  73. });
  74. //确认领取
  75. $(".ConfirmReceive").on("click", function() {
  76. var TaskID = $("#ReceiveTaskID").val();
  77. console.log(TaskID);
  78. $(".close_win").click();
  79. eos.transaction({
  80. actions: [
  81. {
  82. account: 'pdjtask',
  83. name: 'receivetk',
  84. authorization: [{
  85. actor: userAccount,
  86. permission: 'active'
  87. }],
  88. data: {
  89. taskID: TaskID,
  90. worker: userAccount
  91. }
  92. }
  93. ]
  94. }).then(result => {
  95. console.log(result);
  96. alert("领取成功");
  97. getTaskList();
  98. })
  99. .catch(error => {console.error(error);alert("发生错误!" + error)});
  100. });
  101. //提交任务
  102. $(".Commit").on("click", function() {
  103. console.log("提交任务");
  104. $("#SubmitTask").modal();
  105. getTaskList();
  106. });
  107. //确认提交
  108. $(".ConfirmSubmission").on("click", function() {
  109. var TaskID = $("#GetTaskID").val();
  110. var TaskInfo = $("#TaskInformation").val();
  111. console.log(TaskInfo);
  112. $(".close_win").click();
  113. eos.transaction({
  114. actions: [
  115. {
  116. account: 'pdjtask',
  117. name: 'commit',
  118. authorization: [{
  119. actor: userAccount,
  120. permission: 'active'
  121. }],
  122. data: {
  123. taskID: TaskID,
  124. memo: TaskInfo
  125. }
  126. }
  127. ]
  128. }).then(result => { console.log(result);
  129. alert("提交成功");
  130. getTaskList();
  131. })
  132. .catch(error => {console.error(error);alert("发生错误!" + error)});
  133. });
  134. //验收任务
  135. $(".Confirm").on("click", function() {
  136. console.log("验收任务");
  137. $("#ConfirmTask").modal();
  138. getTaskList();
  139. });
  140. //确认验收
  141. $(".TaskConfirm").on("click", function() {
  142. var TaskID = $("#taskid").val();
  143. var TaskStatus = $("#TaskStatus").val();
  144. TaskStatus = parseInt(TaskStatus);
  145. console.log(TaskID,TaskStatus);
  146. $(".close_win").click();
  147. eos.transaction({
  148. actions: [
  149. {
  150. account: 'pdjtask',
  151. name: 'confirm',
  152. authorization: [{
  153. actor: userAccount,
  154. permission: 'active'
  155. }],
  156. data: {
  157. taskID: TaskID,
  158. ok: TaskStatus
  159. }
  160. }
  161. ]
  162. }).then(result => {
  163. console.log(result);
  164. alert("任务验收成功");
  165. getTaskList();
  166. getBalance();
  167. })
  168. .catch(error => {console.error(error);alert("发生错误!" + error)});
  169. });
  170. //查看余额
  171. function getBalance(){
  172. eos.getCurrencyBalance({
  173. account: userAccount,
  174. code: 'pdjtoken',
  175. symbol: 'PTK'
  176. })
  177. .then(result => { console.log(result);
  178. if(result.length == 0)
  179. $(".balance span:nth-child(2)").html("余额:0");
  180. else
  181. $(".balance span:nth-child(2)").html("余额:" + result);
  182. })
  183. .catch(error => console.error(error));
  184. }
  185. //console.log(eos);
  186. //任务列表
  187. function getTaskList(){
  188. eos.getTableRows({
  189. scope: 'pdjtask',
  190. code: 'pdjtask',
  191. table: 'tasks',
  192. json: true,
  193. lower_bound: 0,
  194. upper_bound: -1,
  195. limit: 20
  196. })
  197. .then(function(result){
  198. console.log(result.rows);
  199. var tr;
  200. var tkStatus = "";
  201. for(var i = 0; i < result.rows.length; i++){
  202. if(result.rows[i].status == 0)
  203. tkStatus = "未领取";
  204. else if(result.rows[i].status == 1)
  205. tkStatus = "已领取";
  206. else if(result.rows[i].status == 2)
  207. tkStatus = "已提交";
  208. else
  209. tkStatus = "已结束";
  210. tr += '<tr>';
  211. tr += '<td class="active">'+result.rows[i].taskID+'</td>';
  212. tr += '<td class="success">'+result.rows[i].creator+'</td>';
  213. tr += '<td class="warning">'+result.rows[i].worker+'</td>';
  214. tr += '<td class="danger">'+result.rows[i].bonus+'</td>';
  215. tr += '<td class="info">'+tkStatus+'</td>';
  216. tr += '<td class="active">'+result.rows[i].remark+'</td>';
  217. tr += '<td class="success">'+result.rows[i].comment+'</td>';
  218. tr += '</tr>';
  219. }
  220. //console.log(tr);
  221. $("#list").html(tr);
  222. })
  223. .catch(error => console.error(error));
  224. }
  225. });

  本文只包含部分核心代码,点击这里可获取全部代码和文件。以上就是本次分享的内容,欢迎大家学习交流。



EOS开发实战的更多相关文章

  1. EOS开发入门

    EOS开发入门   在上一篇文章<EOS开发环境搭建>中,我们已经完成了EOS开发环境的搭建,本次为大家带来的是EOS开发入门的相关内容. 1. EOS的合约开发基础   智能合约是一种旨 ...

  2. chrome拓展开发实战:页面脚本的拦截注入

    原文请访问个人博客:chrome拓展开发实战:页面脚本的拦截注入 目前公司产品的无线站点已经实现了业务平台组件化,所有业务组件的转场都是通过路由来完成,而各个模块是通过requirejs进行统一管理, ...

  3. 《Android NFC 开发实战详解 》简介+源码+样章+勘误ING

    <Android NFC 开发实战详解>简介+源码+样章+勘误ING SkySeraph Mar. 14th  2014 Email:skyseraph00@163.com 更多精彩请直接 ...

  4. CSS高效开发实战:CSS 3、LESS、SASS、Bootstrap、Foundation --读书笔记(1)设定背景图

    技术的新发展,除计算机可以接入互联网之外,平板电脑.智能手机.智能电视等其他设备均可访问互联网.在多设备时代,构建多屏体验也不是听说的那么难. 但是这也增加了学习CSS的难度?不知道如何上手,只懂一点 ...

  5. 《Node.js开发实战详解》学习笔记

    <Node.js开发实战详解>学习笔记 ——持续更新中 一.NodeJS设计模式 1 . 单例模式 顾名思义,单例就是保证一个类只有一个实例,实现的方法是,先判断实例是否存在,如果存在则直 ...

  6. 第九篇 :微信公众平台开发实战Java版之如何实现自定义分享内容

    第一部分:微信JS-SDK介绍 微信JS-SDK是微信公众平台面向网页开发者提供的基于微信内的网页开发工具包. 通过使用微信JS-SDK,网页开发者可借助微信高效地使用拍照.选图.语音.位置等手机系统 ...

  7. 第八篇 :微信公众平台开发实战Java版之如何网页授权获取用户基本信息

    第一部分:微信授权获取基本信息的介绍 我们首先来看看官方的文档怎么说: 如果用户在微信客户端中访问第三方网页,公众号可以通过微信网页授权机制,来获取用户基本信息,进而实现业务逻辑. 关于网页授权回调域 ...

  8. 第七篇 :微信公众平台开发实战Java版之如何获取微信用户基本信息

    在关注者与公众号产生消息交互后,公众号可获得关注者的OpenID(加密后的微信号,每个用户对每个公众号的OpenID是唯一的.对于不同公众号,同一用户的openid不同). 公众号可通过本接口来根据O ...

  9. 第六篇 :微信公众平台开发实战Java版之如何自定义微信公众号菜单

    我们来了解一下 自定义菜单创建接口: http请求方式:POST(请使用https协议) https://api.weixin.qq.com/cgi-bin/menu/create?access_to ...

随机推荐

  1. Linux启动Redis失败/没有那个文件或目录

    没有那个文件或目录问题,可能是你选择的目录不对. 应切换到Redis目录下启动.

  2. Python内置函数(15)——dict

    英文文档: class dict(**kwarg) class dict(mapping, **kwarg) class dict(iterable, **kwarg) Return a new di ...

  3. 有了这 4 大特性,CDN 好用到飞起

    随着 CDN 市场的快速发展和网络新技术的不断涌现,目前的 CDN 已不仅仅是当初简单的内容分发,同时也是新特性研发.新技术推广及实践的平台.这些新技术.新特性,或者能够保障 CDN 安全性,或是提升 ...

  4. TDX指标的理解与改造(价格到达指标线提醒)

    目的:画线指标理解,并同时改造成条件选股指标. 参考:https://mp.csdn.net/postedit/83176406 #ff7700 hex color  https://www.colo ...

  5. java基础(二)-----java的三大特性之继承

    在<Think in java>中有这样一句话:复用代码是Java众多引人注目的功能之一.但要想成为极具革命性的语言,仅仅能够复制代码并对加以改变是不够的,它还必须能够做更多的事情.在这句 ...

  6. asp.net core系列 33 EF查询数据 (2)

    一. 原生SQL查询 接着上篇讲.通过 Entity Framework Core 可以在使用关系数据库时下降到原始 SQL 查询. 在无法使用 LINQ 表达要执行的查询时,或因使用 LINQ 查询 ...

  7. C++中int与string的转化

    C++中int与string的转化 int本身也要用一串字符表示,前后没有双引号,告诉编译器把它当作一个数解释.缺省情况下,是当成10进制(dec)来解释,如果想用8进制,16进制,怎么办?加上前缀, ...

  8. [开发技巧]·TensorFlow中numpy与tensor数据相互转化

    [开发技巧]·TensorFlow中numpy与tensor数据相互转化 个人主页–> https://xiaosongshine.github.io/ - 问题描述 在我们使用TensorFl ...

  9. Linux 进程管理工具 supervisord 安装及使用

    Supervisor是用Python实现的一款非常实用的进程管理工具 1.安装过程非常简单 安装python 安装meld3-0.6.8.tar.gz 安装supervisor-3.0a12.tar. ...

  10. [51nod1355] 斐波那契的最小公倍数

    Description 给定 \(n\) 个正整数 \(a_1,a_2,...,a_n\),求 \(\text{lcm}(f_{a_1},f_{a_2},...,f_{a_n})\).其中 \(f_i ...