learning

vscode 方便的配置

消除include的报错/ vscode引入第三方库

在这里插入图片描述
使用第三方库无法打开文件怎么办?
1.搜索库文件路径
在这里插入图片描述
使用 sudo find / -name " gazebo.hh "
找到在 /usr/include/gazebo-11 路径下
2.配置vscod

打开vscod c/c++插件的扩展设置
在这里插入图片描述

找到
default:include path选项
在这里插入图片描述

输入 /usr/include/gazebo-11

python launch 的代码模板设置

在使用 Python 版的 launch 文件时,涉及的 API 众多,为了提高编码效率可以在 VScode 中设置 launch 文件的代码模板,将 VScode 的配置文件 python.json 修改

请添加图片描述

搜索找到python.json
修改为:

{
	// Place your snippets for python here. Each snippet is defined under a snippet name and has a prefix, body and 
	// description. The prefix is what is used to trigger the snippet and the body will be expanded and inserted. Possible variables are:
	// $1, $2 for tab stops, $0 for the final cursor position, and ${1:label}, ${2:another} for placeholders. Placeholders with the 
	// same ids are connected.
	// Example:
	// "Print to console": {
	// 	"prefix": "log",
	// 	"body": [
	// 		"console.log('$1');",
	// 		"$2"
	// 	],
	// 	"description": "Log output to console"
	// }
	"ros2 node": {
		"prefix": "ros2_node_py",
		"body": [
			"\"\"\" ",
			"需求:",
			"流程:",
			"1.导包;",
			"2.初始化 ROS2 客户端;",
			"3.自定义节点类;",
			"         ",
			"4.调用 spain 函数,并传入节点对象;",
			"5.资源释放。 ",
			"",
			"",
			"\"\"\"",
			"# 1.导包;",
			"import rclpy",
		 	"from rclpy.node import Node",
			 "",
			 "# 3.自定义节点类;",
			"class MyNode(Node):",
			"def __init__(self):",
		
		"   super().__init__(\"mynode_node_py\")",
		"",
		"def main():",
		"# 2.初始化 ROS2 客户端;",
		"rclpy.init()",
		"# 4.调用 spain 函数,并传入节点对象;",
		"rclpy.spin(MyNode())",
		"# 5.资源释放。 ",
		"rclpy.shutdown()",
		"",
		"if __name__ == '__main__':",
		"main()",
		],
		"description": "ros2 node"
	},
	"ros2 launch py": {
		"prefix": "ros2_launch_py",
		"body": [
			"from launch import LaunchDescription",
			"from launch_ros.actions import Node",
			"# 封装终端指令相关类--------------",
			"# from launch.actions import ExecuteProcess",
			"# from launch.substitutions import FindExecutable",
			 "# 参数声明与获取-----------------",
			"# from launch.actions import DeclareLaunchArgument",
			"# from launch.substitutions import LaunchConfiguration",
			"# 文件包含相关-------------------",
			"# from launch.actions import IncludeLaunchDescription",
			"# from launch.launch_description_sources import PythonLaunchDescriptionSource",
			"# 分组相关----------------------",
			 
			"# from launch_ros.actions import PushRosNamespace",
			"# from launch.actions import GroupAction",
			 
			"# 事件相关----------------------",
			"# from launch.event_handlers import OnProcessStart, OnProcessExit",
			"# from launch.actions import ExecuteProcess, RegisterEventHandler,LogInfo",

			"# 获取功能包下 share 目录路径-------",
			"# from ament_index_python.packages import get_package_share_directory",
			"",
			"def generate_launch_description():",
			"   ",
			"   return LaunchDescription([])"
		],


			"description": "ros2 launch"
		}s
}


使用示例

CPP

1.智能指针

1.shared

使用 std::make_shared 实例化类后,返回的是指向该类对象的 std::shared_ptr 智能指针。要调用类的方法,你需要通过智能指针来访问对象,并使用箭头操作符 -> 来调用方法。以下是一个示例:

#include <memory>
#include <iostream>

class MyClass {
public:
    void myMethod() {
        std::cout << "Hello from MyClass!" << std::endl;
    }
};

int main() {
    // 使用 std::make_shared 实例化类,并返回指向该类对象的 shared_ptr
    auto obj = std::make_shared<MyClass>();

    // 通过 shared_ptr 调用对象的方法
    obj->myMethod();

    return 0;
}

在这个示例中,std::make_shared 用于实例化 MyClass 类,并返回一个指向该对象的 std::shared_ptr。然后,我们使用 obj->myMethod() 来调用 MyClass 类的 myMethod 方法

ros2应用
#include "rclcpp/rclcpp.hpp"
#include <cstdio>
#include <iostream>
#include <fcntl.h>
#include <unistd.h>
#include <cstring>
#include <termios.h>
#include <memory>
#include <chrono>
#include <functional>
#include "geometry_msgs/msg/twist.hpp"
using std::placeholders::_1;
class Cmd_velSubscriber : public rclcpp::Node
{
public:
  int serial_port;
  Cmd_velSubscriber()
      : Node("Cmd_velSubscriber")
  {
    subscription_ = this->create_subscription<geometry_msgs::msg::Twist>(
        "cmd_vel", 10, std::bind(&Cmd_velSubscriber::topic_callback, this, _1));

      // 打开串口设备
      serial_port = open("/dev/ttyUSB0", O_RDWR);
      if (serial_port == -1)
      {
        std::cerr << "无法打开串口设备" << std::endl;
        exit(1);
      }

      // 配置串口属性
      struct termios tty;
      memset(&tty, 0, sizeof(tty));
      if (tcgetattr(serial_port, &tty) != 0)
      {
        std::cerr << "无法获取串口属性" << std::endl;
        exit(1);
      }
      tty.c_cflag &= ~PARENB;        // 无奇偶校验
      tty.c_cflag &= ~CSTOPB;        // 1 位停止位
      tty.c_cflag |= CS8;            // 8 位数据位
      tty.c_cflag &= ~CRTSCTS;       // 禁用硬件流控
      tty.c_cflag |= CREAD | CLOCAL; // 允许读取,并使本地连接
      tty.c_lflag &= ~ICANON;        // 禁用标准模式
      tty.c_lflag &= ~ECHO;          // 禁用回显
      tty.c_lflag &= ~ECHOE;         // 禁用回车删掉
      tty.c_lflag &= ~ECHONL;        // 禁用新行回显
      tty.c_oflag &= ~OPOST;         // 禁用输出处理

      tty.c_cc[VMIN] = 1;  // 非规范模式下的最小字节数
      tty.c_cc[VTIME] = 0; // 非规范模式下的超时时间(以 0.1 秒为单位)

      if (cfsetospeed(&tty, B115200) != 0)
      { // 设置波特率为 115200
        std::cerr << "无法设置输出波特率" << std::endl;
        exit(1);
      }
      if (cfsetispeed(&tty, B115200) != 0)
      { // 设置波特率为 115200
        std::cerr << "无法设置输入波特率" << std::endl;
        exit(1);
      }

      // 应用新的设置
      if (tcsetattr(serial_port, TCSANOW, &tty) != 0)
      {
        std::cerr << "无法应用新的串口设置" << std::endl;
        exit(1);
      }
  }
  void Send_Cmd_Data(uint8_t cmd, const uint8_t *datas, uint8_t len)
  {
    uint8_t buf[300], i, cnt = 0;
    uint16_t crc16;
    buf[cnt++] = 0xA5;
    buf[cnt++] = 0x5A;
    buf[cnt++] = len;
    buf[cnt++] = cmd;
    for (i = 0; i < len; i++)
    {
      buf[cnt++] = datas[i];
    }
    crc16 = CRC16_Check(buf, len + 4);
    buf[cnt++] = crc16 >> 8;
    buf[cnt++] = crc16 & 0xFF;
    buf[cnt++] = 0xFF;
    Send(buf, cnt);
  }

private:
  void my_send_data(  const uint8_t *data, uint8_t len)
  {
    if (write(serial_port, data, len) < 0)
   {
     std::cerr << "发送数据时发生错误" << std::endl;
   }
  }
  void Send(const uint8_t *data, uint8_t len )
  {
    my_send_data(  data, len);
  }


  uint16_t CRC16_Check(const uint8_t *data, uint8_t len)
  {
    uint16_t CRC16 = 0xFFFF;
    uint8_t state, i, j;
    for (i = 0; i < len; i++)
    {
      CRC16 ^= data[i];
      for (j = 0; j < 8; j++)
      {
        state = CRC16 & 0x01;
        CRC16 >>= 1;
        if (state)
        {
          CRC16 ^= 0xA001;
        }
      }
    }
    return CRC16;
  }
  void topic_callback(const geometry_msgs::msg::Twist &msg) const
  {
    RCLCPP_INFO(this->get_logger(), "I heard:linear.x='%.2f'  linear.y='%.2f' linear.z='%.2f' angular.z='%.2f' ",
                msg.linear.x,
                msg.linear.y,
                msg.linear.z,
                msg.angular.z);
  }
  rclcpp::Subscription<geometry_msgs::msg::Twist>::SharedPtr subscription_;
};
int main(int argc, char *argv[])
{
  rclcpp::init(argc, argv);
  auto node_my = std::make_shared<Cmd_velSubscriber>();
  rclcpp::spin(node_my);
  uint8_t data[5]={0x10,0x78,0x20,0x35,0x71};
  node_my->Send_Cmd_Data(0x00, data, 5);
  rclcpp::shutdown();
  return 0;
}

其中 node_my->Send_Cmd_Data(0x00, data, 5)就是通过make_shared实现类的实例化 后调用类的方法

ROS2

查看ros2 安装的功能包

ros2 pkg list //列出全部功能包
ros2 pkg list |grep -i xxx //如果有输出则xxx功能包安装了已经

Launch

<node pkg="turtlesim" exec="turtlesim_node" name="t1" namespace="t1_ns"
 exec_name="t1_label" respawn="true"/>

pkg:功能包猛
exec:可执行文件;
name:节点名称;
namespace:命名空间;
exec_name:流程标签;
respawn:节点关闭后是否重启集
args:调用指令时的参数列表;
ros_args:相当于args 前缀 --ros-args。

执行命令

<launch>
  <node pkg="turtlesim" exec="turtlesim_node" />
  <executable cmd="ros2 run turtlesim turtlesim_node" output="both" >
</launch>

cmd:被执行的命令;
output:日志输出目的地设置。

参数设置 动态传参

需求:启动 turtlesim_node 节点时,可以动态设置背景色
在 cpp01_launch/launch/xml 目录下新建 xml03_args.launch.xml 文件,输入如下内容:

<launch>
  <arg name="bg_r" default="255"/>
  <arg name="bg_b" default="255"/>
  <arg name="bg_g" default="255"/>
  <node pkg="turtlesim" exec="turtlesim_node">
    <param name="background_r" value="$(var bg_r)" />
    <param name="background_g"  value="$(var bg_g)" /> 
    <param name="background_b" value="$(var bg_b)" />
  </node>
</launch>
 

name:参数名称;
default:参数默认值。
参数的调用语法为:
$(var 参数名称)。

在ros2 cpp中使用ros::param::get("~usb_number",usb_number);

使用

串口通信并且打包

1.面相过程tx

#include <cstdio>
#include <iostream>
#include <fcntl.h>
#include <unistd.h>
#include <cstring>
#include <termios.h>
#include <memory>
#include <chrono>
#include <functional>
#include "geometry_msgs/msg/twist.hpp"

 
// uint16_t CRC16_Check(const uint8_t *data, uint8_t len);
// void Send_Cmd_Data(uint8_t cmd, const uint8_t *datas, uint8_t len, int serial_port);
// void my_send_data(int serial_port, const uint8_t *data, uint8_t len);

// int main(int argc, char **argv)
// { // 创建节点
//   rclcpp::init(argc, argv);
//   auto node = rclcpp::Node::make_shared("send_data_usart");
//   // 输出文本
//   RCLCPP_INFO(node->get_logger(), "\n----------start send_data-------------\n ");

//   // 打开串口设备
//   int serial_port = open("/dev/ttyUSB0", O_RDWR);
//   if (serial_port == -1)
//   {
//     std::cerr << "无法打开串口设备" << std::endl;
//     return 1;
//   }

//   // 配置串口属性
//   struct termios tty;
//   memset(&tty, 0, sizeof(tty));
//   if (tcgetattr(serial_port, &tty) != 0)
//   {
//     std::cerr << "无法获取串口属性" << std::endl;
//     return 1;
//   }
//   tty.c_cflag &= ~PARENB;        // 无奇偶校验
//   tty.c_cflag &= ~CSTOPB;        // 1 位停止位
//   tty.c_cflag |= CS8;            // 8 位数据位
//   tty.c_cflag &= ~CRTSCTS;       // 禁用硬件流控
//   tty.c_cflag |= CREAD | CLOCAL; // 允许读取,并使本地连接
//   tty.c_lflag &= ~ICANON;        // 禁用标准模式
//   tty.c_lflag &= ~ECHO;          // 禁用回显
//   tty.c_lflag &= ~ECHOE;         // 禁用回车删掉
//   tty.c_lflag &= ~ECHONL;        // 禁用新行回显
//   tty.c_oflag &= ~OPOST;         // 禁用输出处理

//   tty.c_cc[VMIN] = 1;  // 非规范模式下的最小字节数
//   tty.c_cc[VTIME] = 0; // 非规范模式下的超时时间(以 0.1 秒为单位)

//   if (cfsetospeed(&tty, B115200) != 0)
//   { // 设置波特率为 115200
//     std::cerr << "无法设置输出波特率" << std::endl;
//     return 1;
//   }
//   if (cfsetispeed(&tty, B115200) != 0)
//   { // 设置波特率为 115200
//     std::cerr << "无法设置输入波特率" << std::endl;
//     return 1;
//   }

//   // 应用新的设置
//   if (tcsetattr(serial_port, TCSANOW, &tty) != 0)
//   {
//     std::cerr << "无法应用新的串口设置" << std::endl;
//     return 1;
//   }

//   uint8_t data[20] = {0xA7,0x6A,0x01,0xff,0x35,0x16,0xeb,0x7f,0xef};
//   //my_send_data(serial_port, data, 5);
//   //uint8_t data[3] = { 0x21};
//   //write(serial_port, &data, 10);
//   Send_Cmd_Data(0x00, data, 9, serial_port);
//   //write(serial_port, "\n\r", 3);
//   // 关闭串口设备
//   close(serial_port);
//   return 0;
// }

// void my_send_data(int serial_port, const uint8_t *data, uint8_t len)
// {
//   if (write(serial_port, data, len) < 0)
//  {
//    std::cerr << "发送数据时发生错误" << std::endl;
//  }
// }

// // void Send(const uint8_t *data, uint8_t len, int serial_port)
// // {
// //   for (uint8_t i = 0; i < len; i++)
// //   {
// //     my_send_data(serial_port, (data + i), 1); // 发送一个字节
// //   }
// // }
// void Send(const uint8_t *data, uint8_t len, int serial_port)
// {
//   my_send_data(serial_port, data, len);
// }

// void Send_Cmd_Data(uint8_t cmd, const uint8_t *datas, uint8_t len, int serial_port)
// {
//   uint8_t buf[300], i, cnt = 0;
//   uint16_t crc16;
//   buf[cnt++] = 0xA5;
//   buf[cnt++] = 0x5A;
//   buf[cnt++] = len;
//   buf[cnt++] = cmd;
//   for (i = 0; i < len; i++)
//   {
//     buf[cnt++] = datas[i];
//   }
//   crc16 = CRC16_Check(buf, len + 4);
//   buf[cnt++] = crc16 >> 8;
//   buf[cnt++] = crc16 & 0xFF;
//   buf[cnt++] = 0xFF;
// Send(buf, cnt, serial_port); 
// }

// uint16_t CRC16_Check(const uint8_t *data, uint8_t len)
// {
//   uint16_t CRC16 = 0xFFFF;
//   uint8_t state, i, j;
//   for (i = 0; i < len; i++)
//   {
//     CRC16 ^= data[i];
//     for (j = 0; j < 8; j++)
//     {
//       state = CRC16 & 0x01;
//       CRC16 >>= 1;
//       if (state)
//       {
//         CRC16 ^= 0xA001;
//       }
//     }
//   }
//   return CRC16;
// }

2.面相过程rx

#include <cstdio>
#include <iostream>
#include <fcntl.h>
#include <unistd.h>
#include <cstring>
#include <termios.h>
#include "rclcpp/rclcpp.hpp"
#include <iomanip>//测试使用
uint16_t CRC16_Check(const uint8_t *data, uint8_t len);
void Receive(uint8_t bytedata);
int main(int argc, char **argv)
{
  rclcpp::init(argc, argv);
  auto node = rclcpp::Node::make_shared("receive_data_usart");
  // 输出文本
  RCLCPP_INFO(node->get_logger(), "\n----------start receive_data-------------\n ");

  //   // 打开串口设备
  int serial_port = open("/dev/ttyUSB0", O_RDWR);
  if (serial_port == -1)
  {
    std::cerr << "无法打开串口设备" << std::endl;
    return 1;
  }

  // 配置串口属性
  struct termios tty;
  memset(&tty, 0, sizeof(tty));
  if (tcgetattr(serial_port, &tty) != 0)
  {
    std::cerr << "无法获取串口属性" << std::endl;
    return 1;
  }
  tty.c_cflag &= ~PARENB;        // 无奇偶校验
  tty.c_cflag &= ~CSTOPB;        // 1 位停止位
  tty.c_cflag |= CS8;            // 8 位数据位
  tty.c_cflag &= ~CRTSCTS;       // 禁用硬件流控
  tty.c_cflag |= CREAD | CLOCAL; // 允许读取,并使本地连接

  tty.c_cc[VMIN] = 1;  // 非规范模式下的最小字节数
  tty.c_cc[VTIME] = 0; // 非规范模式下的超时时间(以 0.1 秒为单位)

  if (cfsetospeed(&tty, B115200) != 0)
  { // 设置波特率为 115200
    std::cerr << "无法设置输出波特率" << std::endl;
    return 1;
  }
  if (cfsetispeed(&tty, B115200) != 0)
  { // 设置波特率为 115200
    std::cerr << "无法设置输入波特率" << std::endl;
    return 1;
  }

  // 应用新的设置
  if (tcsetattr(serial_port, TCSANOW, &tty) != 0)
  {
    std::cerr << "无法应用新的串口设置" << std::endl;
    return 1;
  }

  // 接收数据
  uint8_t receive_data;
  ssize_t bytes_read;
  while (true)
  {
    bytes_read = read(serial_port, &receive_data, sizeof(receive_data));
    if (bytes_read < 0)
    {
      std::cerr << "读取数据时发生错误" << std::endl;
      break;
    }
    else if (bytes_read == 0)
    {
      std::cerr << "未收到数据" << std::endl;
     // continue;
      break;
    }
    Receive(receive_data);
    // 处理接收到的数据
 
    //std::cout << "hex: " << std::hex << static_cast<int>(receive_data) << std::endl;
    //std::cout << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(receive_data) << " ";
  }

  // 关闭串口设备
  close(serial_port);
  return 0;
}
uint16_t CRC16_Check(const uint8_t *data, uint8_t len)
{
  uint16_t CRC16 = 0xFFFF;
  uint8_t state, i, j;
  for (i = 0; i < len; i++)
  {
    CRC16 ^= data[i];
    for (j = 0; j < 8; j++)
    {
      state = CRC16 & 0x01;
      CRC16 >>= 1;
      if (state)
      {
        CRC16 ^= 0xA001;
      }
    }
  }
  return CRC16;
}
// 数据帧解析   自己写
void Data_Analysis(uint8_t cmd, const uint8_t *datas, uint8_t len)
{
  switch (cmd)
  {
  case 0x00:
    // 解析命令1的数据
    // 这里可以根据具体情况进行相应的操作
    //------------------------------------------------测试代码---------------------------------------------------
    for (uint8_t i = 0; i < len; i++)
    {
      std::cout << "hex:"<<std::hex << static_cast<int>(*datas) << " ";
      datas++;
    }
    std::cout << std::endl;
    //-----------------------------------------------------------------------------------------------------------
    break;
  case 0x01:
    // 解析命令2的数据
    break;
    // 添加更多命令的解析逻辑...
  default:
    // 未知命令,进行错误处理或者忽略
    std::cerr << "Unknown command: " << cmd << std::endl;
    break;
  }
}
void Receive(uint8_t bytedata)
{

  static uint8_t step = 0; // 状态变量初始化为0 在函数中必须为静态变量
  static uint8_t cnt = 0, Buf[300], len, cmd, *data_ptr;
  static uint16_t crc16;
  // 进行数据解析 状态机
  switch (step)
  {
  case 0: // 接收帧头1状态
    if (bytedata == 0xA5)
    {
      step++;
      cnt = 0;
      Buf[cnt++] = bytedata;
    }
    break;
  case 1: // 接收帧头2状态
    if (bytedata == 0x5A)
    {
      step++;
      Buf[cnt++] = bytedata;
    }
    else if (bytedata == 0xA5)
    {
      step = 1;
    }
    else
    {
      step = 0;
    }
    break;
  case 2: // 接收数据长度字节状态
    step++;
    Buf[cnt++] = bytedata;
    len = bytedata;
    break;
  case 3: // 接收命令字节状态
    step++;
    Buf[cnt++] = bytedata;
    cmd = bytedata;
    data_ptr = &Buf[cnt]; // 记录数据指针首地址
    if (len == 0)
      step++; // 数据字节长度为0则跳过数据接收状态
    break;
  case 4: // 接收len字节数据状态
    Buf[cnt++] = bytedata;
    if (data_ptr + len == &Buf[cnt]) // 利用指针地址偏移判断是否接收完len位数据
    {
      step++;
    }
    break;
  case 5: // 接收crc16校验高8位字节
    step++;
    crc16 = bytedata;
    break;
  case 6: // 接收crc16校验低8位字节
    crc16 <<= 8;
    crc16 += bytedata;
    if (crc16 == CRC16_Check(Buf, cnt)) // 校验正确进入下一状态
    {
      step++;
    }
    else if (bytedata == 0xA5)
    {
      step = 1;
    }
    else
    {
      step = 0;
    }
    break;
  case 7:                 // 接收帧尾
    if (bytedata == 0xFF) // 帧尾接收正确
    {
      Data_Analysis(cmd, data_ptr, len); // 数据解析
      step = 0;
    }
    else if (bytedata == 0xA5)
    {
      step = 1;
    }
    else
    {
      step = 0;
    }
    break;
  default:
    step = 0;
    break; // 多余状态 正常情况下不可能出现
  }
}

话题通信

标准消息std::msgs

发布
#include<functional>
#include<memory>
#include<string>
#include<chrono>
#include"std_msgs/msg/string.hpp"
#include"rclcpp/rclcpp.hpp"

using namespace std::chrono_literals;
/* This example creates a subclass of Node and uses std::bind() to register a
* member function as a callback from the timer. */
class MinimalPublisher : public rclcpp::Node
{
public:
MinimalPublisher()
: Node("minimal_publisher"), count_(0)
{
publisher_ = this->create_publisher<std_msgs::msg::String>("topic", 10);
timer_ = this->create_wall_timer(
500ms, std::bind(&MinimalPublisher::timer_callback, this));
}
private:
void timer_callback()
{
auto message = std_msgs::msg::String();
message.data = "Hello, world! " + std::to_string(count_++);
RCLCPP_INFO(this->get_logger(), "Publishing: '%s'", message.data.c_str());
publisher_->publish(message);
}
rclcpp::TimerBase::SharedPtr timer_;
rclcpp::Publisher<std_msgs::msg::String>::SharedPtr publisher_;
size_t count_;
};
接收

MARKDOWN

代码块

代码块使用 ```前后包裹

linux

CMAKE

LINUX

.dep格式文安装

sudo dpkg -i 文件名.dep

  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
About This Book, Leverage Python' s most powerful open-source libraries for deep learning, data wrangling, and data visualization, Learn effective strategies and best practices to improve and optimize machine learning systems and algorithms, Ask – and answer – tough questions of your data with robust statistical models, built for a range of datasets, Who This Book Is For, If you want to find out how to use Python to start answering critical questions of your data, pick up Python Machine Learning – whether you want to get started from scratch or want to extend your data science knowledge, this is an essential and unmissable resource., What You Will Learn, Explore how to use different machine learning models to ask different questions of your data, Learn how to build neural networks using Keras and Theano, Find out how to write clean and elegant Python code that will optimize the strength of your algorithms, Discover how to embed your machine learning model in a web application for increased accessibility, Predict continuous target outcomes using regression analysis, Uncover hidden patterns and structures in data with clustering, Organize data using effective pre-processing techniques, Get to grips with sentiment analysis to delve deeper into textual and social media data, Style and approach, Python Machine Learning connects the fundamental theoretical principles behind machine learning to their practical application in a way that focuses you on asking and answering the right questions. It walks you through the key elements of Python and its powerful machine learning libraries, while demonstrating how to get to grips with a range of statistical models.

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值