codesignal practice 3

7

You are given three integers in the form of strings: firstnum, secondnum, and thirdnum. Your task is to check whether it is possible to erase at most one digit from firstnum, so that the resulting string contains at least one digit, has no leading zeros and the value of thirdnum is equal to the sum of the values of firstnum and secondnum.

Return true if it's possible, otherwise return false.

Note: All three strings are provided without leading zeros.

Example

For firstnum = "10534", secondnum = "67", and thirdnum = "1120", the output should be eraseOneDigit(firstnum, secondnum, thirdnum) = true.

By erasing the 5th digit of firstnum, the result is 1053, and 1053 + 67 = 1120. So the answer is true.

For firstnum = "10000", secondnum = "67", and thirdnum = "1120", the output should be eraseOneDigit(firstnum, secondnum, thirdnum) = false.

The only possible modified values of firstnum would be 10000 (nothing was deleted), 0000 (first digit was deleted), and 1000 (any zero was deleted); none of which would produce the required sum, so the answer is false.

For firstnum = "1067", secondnum = "33", and thirdnum = "100", the output should be eraseOneDigit(firstnum, secondnum, thirdnum) = false.

We could delete the first digit of firstnum, resulting in 067 (and 67 + 33 = 100), but since in this case new firstnum value has a leading zero, it's considered invalid. So the answer is false.

For firstnum = "153", secondnum = "153", and thirdnum = "306", the output should be eraseOneDigit(firstnum, secondnum, thirdnum) = true.

Because 153 + 153 = 306, there's no need to delete a digit from firstnum, and the result is true.

Input/Output

[execution time limit] 4 seconds (php)

[input] string firstnum

A string representing an integer.

Guaranteed constraints:
2 ≤ firstnum.length ≤ 9.

[input] string secondnum

A string representing an integer.

Guaranteed constraints:
1 ≤ secondnum.length ≤ 9.

[input] string thirdnum

A string representing an integer.

Guaranteed constraints:
1 ≤ thirdnum.length ≤ 9.

[output] boolean

Return true if it's possible to erase at most one digit from firstnum such that the value of thirdnum is equal to the sum of the values of firstnum and secondnum. Otherwise return false.

8

You are given two arrays of integers a and b, and two integers lower and upper. Your task is to find the number of pairs (i, j) such that lower ≤ a[i] * a[i] + b[j] * b[j] ≤ upper.

Example

For a = [3, -1, 9], b = [100, 5, -2], lower = 7, and upper = 99, the output should be boundedSquareSum(a, b, lower, upper) = 4.

There are only four pairs that satisfy the requirement:

If i = 0 and j = 1, then a[0] = 3, b[1] = 5, and 7 ≤ 3 * 3 + 5 * 5 = 9 + 25 = 36 ≤ 99.
If i = 0 and j = 2, then a[0] = 3, b[2] = -2, and 7 ≤ 3 * 3 + (-2) * (-2) = 9 + 4 = 13 ≤ 99.
If i = 1 and j = 1, then a[1] = -1, b[1] = 5, and 7 ≤ (-1) * (-1) + 5 * 5 = 1 + 25 = 26 ≤ 99.
If i = 2 and j = 2, then a[2] = 9, b[2] = -2, and 7 ≤ 9 * 9 + (-2) * (-2) = 81 + 4 = 85 ≤ 99.
For a = [1, 2, 3, -1, -2, -3], b = [10], lower = 0, and upper = 100, the output should be boundedSquareSum(a, b, lower, upper) = 0.

Since the array b contains only one element 10 and the array a does not contain 0, it is not possible to satisfy 0 ≤ a[i] * a[i] + 10 * 10 ≤ 100.

Input/Output

[execution time limit] 4 seconds (php)

[input] array.integer a

A first array of integers.

Guaranteed constraints:
1 ≤ a.length ≤ 105,
-104 ≤ a[i] ≤ 104.

[input] array.integer b

A second array of integers.

Guaranteed constraints:
1 ≤ b.length ≤ 105,
-104 ≤ b[i] ≤ 104.

[input] integer lower

An integer representing a lower bound of a satisfiable square sum.

Guaranteed constraints:
0 ≤ lower ≤ 109.

[input] integer upper

An integer representing an upper bound of a satisfiable square sum.

Guaranteed constraints:
lower ≤ upper,
0 ≤ upper ≤ 109.

[output] integer

The number of pairs (i, j) such, that lower ≤ a[i] * a[i] + b[j] * b[j] ≤ upper. It is guaranteed that the answer fits in 32-bit value type.

9

Given an integer n and an array a of length n, your task is to apply the following mutation to a:

Array a mutates into a new array b of length n.
For each i from 0 to n - 1, b[i] = a[i - 1] + a[i] + a[i + 1].
If some element in the sum a[i - 1] + a[i] + a[i + 1] does not exist, it should be set to 0. For example, b[0] should be equal to 0 + a[0] + a[1].
Example

For n = 5 and a = [4, 0, 1, -2, 3], the output should be mutateTheArray(n, a) = [4, 5, -1, 2, 1].

b[0] = 0 + a[0] + a[1] = 0 + 4 + 0 = 4
b[1] = a[0] + a[1] + a[2] = 4 + 0 + 1 = 5
b[2] = a[1] + a[2] + a[3] = 0 + 1 + (-2) = -1
b[3] = a[2] + a[3] + a[4] = 1 + (-2) + 3 = 2
b[4] = a[3] + a[4] + 0 = (-2) + 3 + 0 = 1
So, the resulting array after the mutation will be [4, 5, -1, 2, 1].

Input/Output

[execution time limit] 4 seconds (php)

[input] integer n

An integer representing the length of the given array.

Guaranteed constraints:
1 ≤ n ≤ 103.

[input] array.integer a

An array of integers that needs to be mutated.

Guaranteed constraints:
a.length = n,
-103 ≤ a[i] ≤ 103.

[output] array.integer

The resulting array after the mutation.

codesignal practice 2

4

Given an array of integers a, your task is to count the number of pairs i and j (where 0 ≤ i < j < a.length), such that a[i] and a[j] are digit anagrams.

Two integers are considered to be digit anagrams if they contain the same digits. In other words, one can be obtained from the other by rearranging the digits (or trivially, if the numbers are equal). For example, 54275 and 45572 are digit anagrams, but 321 and 782 are not (since they don't contain the same digits). 220 and 22 are also not considered as digit anagrams, since they don't even have the same number of digits.

Example

For a = [25, 35, 872, 228, 53, 278, 872], the output should be digitAnagrams(a) = 4.

There are 4 pairs of digit anagrams:

a[1] = 35 and a[4] = 53 (i = 1 and j = 4),
a[2] = 872 and a[5] = 278 (i = 2 and j = 5),
a[2] = 872 and a[6] = 872 (i = 2 and j = 6),
a[5] = 278 and a[6] = 872 (i = 5 and j = 6).
Input/Output

[execution time limit] 4 seconds (php)

[input] array.integer a

An array of non-negative integers.

Guaranteed constraints:
1 ≤ a.length ≤ 105,
0 ≤ a[i] ≤ 109.

[output] integer64

The number of pairs i and j, such that a[i] and a[j] are digit anagrams.

5

You are given an array of strings arr. Your task is to construct a string from the words in arr, starting with the 0th character from each word (in the order they appear in arr), followed by the 1st character, then the 2nd character, etc. If one of the words doesn't have an ith character, skip that word.

Return the resulting string.

Example

For arr = ["Daisy", "Rose", "Hyacinth", "Poppy"], the output should be readingVertically(arr) = "DRHPaoyoisapsecpyiynth".

First, we append all 0th characters and obtain string "DRHP";
Then we append all 1st characters and obtain string "DRHPaoyo";
Then we append all 2nd characters and obtain string "DRHPaoyoisap";
Then we append all 3rd characters and obtain string "DRHPaoyoisapaecp";
Then we append all 4th characters and obtain string "DRHPaoyoisapaecpyiy";
Finally, only letters in the arr[2] are left, so we append the rest characters and get "DRHPaoyoisapaecpyiynth";
example

For arr = ["E", "M", "I", "L", "Y"], the output should be readingVertically(arr) = "EMILY".

Since each of these strings have only one character, the answer will be concatenation of each string in order, so the answer is EMILY.

Input/Output

[execution time limit] 4 seconds (php)

[input] array.string arr

An array of strings containing alphanumeric characters.

Guaranteed constraints:
1 ≤ arr.length ≤ 100,
1 ≤ arr[i].length ≤ 100.

[output] string

Return the resulting string.

6

Given an integer n and an array a of length n, your task is to apply the following mutation to a:

Array a mutates into a new array b of length n.
For each i from 0 to n - 1, b[i] = a[i - 1] + a[i] + a[i + 1].
If some element in the sum a[i - 1] + a[i] + a[i + 1] does not exist, it should be set to 0. For example, b[0] should be equal to 0 + a[0] + a[1].
Example

For n = 5 and a = [4, 0, 1, -2, 3], the output should be mutateTheArray(n, a) = [4, 5, -1, 2, 1].

b[0] = 0 + a[0] + a[1] = 0 + 4 + 0 = 4
b[1] = a[0] + a[1] + a[2] = 4 + 0 + 1 = 5
b[2] = a[1] + a[2] + a[3] = 0 + 1 + (-2) = -1
b[3] = a[2] + a[3] + a[4] = 1 + (-2) + 3 = 2
b[4] = a[3] + a[4] + 0 = (-2) + 3 + 0 = 1
So, the resulting array after the mutation will be [4, 5, -1, 2, 1].

Input/Output

[execution time limit] 4 seconds (php)

[input] integer n

An integer representing the length of the given array.

Guaranteed constraints:
1 ≤ n ≤ 103.

[input] array.integer a

An array of integers that needs to be mutated.

Guaranteed constraints:
a.length = n,
-103 ≤ a[i] ≤ 103.

[output] array.integer

The resulting array after the mutation.

UUID理解

简单说明

V2、V5可以理解为V1、V3的升级版本

版本 说明
V1/V2 基于timestamp+MAC生成,V2加上域名
V3/V5 基于输入的namespace和值生成,v3(md5)v5(sha1)可重复生成; 如用户根据用户信息生成用户唯一id
V4 根据伪随机数生成

UUID V3/4/5的PHP实现

<?php
class UUID {
  public static function v3($namespace, $name) {
    if(!self::is_valid($namespace)) return false;

    // Get hexadecimal components of namespace
    $nhex = str_replace(array('-','{','}'), '', $namespace);

    // Binary Value
    $nstr = '';

    // Convert Namespace UUID to bits
    for($i = 0; $i < strlen($nhex); $i+=2) {
      $nstr .= chr(hexdec($nhex[$i].$nhex[$i+1]));
    }

    // Calculate hash value
    $hash = md5($nstr . $name);

    return sprintf('%08s-%04s-%04x-%04x-%12s',

      // 32 bits for "time_low"
      substr($hash, 0, 8),

      // 16 bits for "time_mid"
      substr($hash, 8, 4),

      // 16 bits for "time_hi_and_version",
      // four most significant bits holds version number 3
      (hexdec(substr($hash, 12, 4)) & 0x0fff) | 0x3000,

      // 16 bits, 8 bits for "clk_seq_hi_res",
      // 8 bits for "clk_seq_low",
      // two most significant bits holds zero and one for variant DCE1.1
      (hexdec(substr($hash, 16, 4)) & 0x3fff) | 0x8000,

      // 48 bits for "node"
      substr($hash, 20, 12)
    );
  }

  public static function v4() {
    return sprintf('%04x%04x-%04x-%04x-%04x-%04x%04x%04x',

      // 32 bits for "time_low"
      mt_rand(0, 0xffff), mt_rand(0, 0xffff),

      // 16 bits for "time_mid"
      mt_rand(0, 0xffff),

      // 16 bits for "time_hi_and_version",
      // four most significant bits holds version number 4
      mt_rand(0, 0x0fff) | 0x4000,

      // 16 bits, 8 bits for "clk_seq_hi_res",
      // 8 bits for "clk_seq_low",
      // two most significant bits holds zero and one for variant DCE1.1
      mt_rand(0, 0x3fff) | 0x8000,

      // 48 bits for "node"
      mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff)
    );
  }

  public static function v5($namespace, $name) {
    if(!self::is_valid($namespace)) return false;

    // Get hexadecimal components of namespace
    $nhex = str_replace(array('-','{','}'), '', $namespace);

    // Binary Value
    $nstr = '';

    // Convert Namespace UUID to bits
    for($i = 0; $i < strlen($nhex); $i+=2) {
      $nstr .= chr(hexdec($nhex[$i].$nhex[$i+1]));
    }

    // Calculate hash value
    $hash = sha1($nstr . $name);

    return sprintf('%08s-%04s-%04x-%04x-%12s',

      // 32 bits for "time_low"
      substr($hash, 0, 8),

      // 16 bits for "time_mid"
      substr($hash, 8, 4),

      // 16 bits for "time_hi_and_version",
      // four most significant bits holds version number 5
      (hexdec(substr($hash, 12, 4)) & 0x0fff) | 0x5000,

      // 16 bits, 8 bits for "clk_seq_hi_res",
      // 8 bits for "clk_seq_low",
      // two most significant bits holds zero and one for variant DCE1.1
      (hexdec(substr($hash, 16, 4)) & 0x3fff) | 0x8000,

      // 48 bits for "node"
      substr($hash, 20, 12)
    );
  }

  public static function is_valid($uuid) {
    return preg_match('/^\{?[0-9a-f]{8}\-?[0-9a-f]{4}\-?[0-9a-f]{4}\-?'.
                      '[0-9a-f]{4}\-?[0-9a-f]{12}\}?$/i', $uuid) === 1;
  }
}

PHP实现随机红包

    //随机红包(总份数、最大金额、最小金额、总数)
    protected function random_redpaper($total, $max, $min, $sum){
        $sum = $sum * 100;
        //按分单位,后面全部用整数金额

        $users = array_fill(0, $total, $min);
        $left = $sum - $min * $total;

        //将剩余金额按rand(1, ceil($left/$total))每次进行随机分配, $left 小于50直接分配完成
        for(;$left > 0;){
            $amount = $left > 50 ? rand(1, ceil($left/$total)) : $left;
            $user_index = rand(0, $total-1);
            if($users[$user_index] + $amount > $max){
                $amount = $max - $users[$user_index];
                $users[$user_index] = $max;
            }else{
                $users[$user_index] += $amount;
            }
            $left -= $amount;
        }

        //恢复按元单位
        foreach($users as &$user){
            $user = $user/100;
        }
        return $users;
    }

centos7 yum 安装 rabbitMQ

引用自https://www.rabbitmq.com/install-rpm.html

Install on Older Distributions (CentOS 7, RHEL 7) Using PackageCloud Yum Repository

添加sign

## primary RabbitMQ signing key
rpm --import https://github.com/rabbitmq/signing-keys/releases/download/2.0/rabbitmq-release-signing-key.asc
## modern Erlang repository
rpm --import https://packagecloud.io/rabbitmq/erlang/gpgkey
## RabbitMQ server repository
rpm --import https://packagecloud.io/rabbitmq/rabbitmq-server/gpgkey

添加repo

创建文件/etc/yum.repos.d/rabbitmq.repo

##
## Zero dependency Erlang
##

[rabbitmq_erlang]
name=rabbitmq_erlang
baseurl=https://packagecloud.io/rabbitmq/erlang/el/7/$basearch
repo_gpgcheck=1
gpgcheck=1
enabled=1
# PackageCloud's repository key and RabbitMQ package signing key
gpgkey=https://packagecloud.io/rabbitmq/erlang/gpgkey
       https://github.com/rabbitmq/signing-keys/releases/download/2.0/rabbitmq-release-signing-key.asc
sslverify=1
sslcacert=/etc/pki/tls/certs/ca-bundle.crt
metadata_expire=300

[rabbitmq_erlang-source]
name=rabbitmq_erlang-source
baseurl=https://packagecloud.io/rabbitmq/erlang/el/7/SRPMS
repo_gpgcheck=1
gpgcheck=0
enabled=1
gpgkey=https://packagecloud.io/rabbitmq/erlang/gpgkey
sslverify=1
sslcacert=/etc/pki/tls/certs/ca-bundle.crt
metadata_expire=300

##
## RabbitMQ server
##

[rabbitmq_server]
name=rabbitmq_server
baseurl=https://packagecloud.io/rabbitmq/rabbitmq-server/el/7/$basearch
repo_gpgcheck=1
gpgcheck=1
enabled=1
# PackageCloud's repository key and RabbitMQ package signing key
gpgkey=https://packagecloud.io/rabbitmq/rabbitmq-server/gpgkey
       https://github.com/rabbitmq/signing-keys/releases/download/2.0/rabbitmq-release-signing-key.asc
sslverify=1
sslcacert=/etc/pki/tls/certs/ca-bundle.crt
metadata_expire=300

[rabbitmq_server-source]
name=rabbitmq_server-source
baseurl=https://packagecloud.io/rabbitmq/rabbitmq-server/el/7/SRPMS
repo_gpgcheck=1
gpgcheck=0
enabled=1
gpgkey=https://packagecloud.io/rabbitmq/rabbitmq-server/gpgkey
sslverify=1
sslcacert=/etc/pki/tls/certs/ca-bundle.crt
metadata_expire=300

更新yum

yum update -y

报错

Delta RPMs disabled because /usr/bin/applydeltarpm not installed

再安装deltarpm

yum install deltarpm
yum clean all
yum update -y

执行安装

yum install socat logrotate -y
yum install erlang rabbitmq-server -y

关联单次查询 vs 单表多次查询

问题

最近开发时,看到别人代码里一大段的join语句,这样做相比在应用层对主表查询后再根据关联条件查询分表有什么优缺点呢?

讨论

  • 代码复用
    如果用join的话大部分代码都无法重复使用,每次都要对每个表的查询条件重新编辑,分表查胜出。

  • 消耗资源不同
    用联表查询把任务都交给数据库处理,数据库处理的压力会变大,而且使用事务的话可能会锁表锁行,影响并发性能。
    而使用分表查询,由于需要与数据库多次切换,会增加与数据库IO操作的开销。

  • 筛选分页
    这种情况下单表查询就很吃力了,感觉只能把分表的筛选条件作为主表的冗余字段来查询。
    不然还是用联表查询比较好了。

  • 分库分表
    这种感觉就只能选择分表查询了吧?

制作一个通过wifi联网,可以远程控制的小车(二)

毁了,烧毁了

是的,本来想通过L298P上的引脚驱动舵机,把ESP32的GPIO5接到L298P的ANALOG0, 然后就烧掉了,烧不进去程序了,毁了!!!

淘宝下单了两片新的ESP32,肉痛———-

总结一下:就是尽量单独给芯片供电,别用其他芯片给单片机供电。

新的开始

终于到了,加油干吧!!!

先搞一下舵机控制

这里需要通过PWM来控制舵机的角度,用的舵机是MG996R
这里参考这个页面的说明

https://components101.com/motors/mg996r-servo-motor-datasheet

参考这个图片
周期20ms, 有效占空比是1ms-2ms,1ms时0°,2ms时120°
PWM的位数设置为10,精度2^10=1024,那么有效占空比就是51-102,51时0°,102时120°

话说这里研究了好久

看看连接

然后是效果

然后是代码
初始化PWM输出参数

const int freq = 50;
const int ledChannel = 0;
const int resolution = 10;//精度1024

setup里面设置

ledcSetup(ledChannel, freq, resolution);
ledcAttachPin(ledPin, ledChannel);

loop里面控制舵机来回摇

  for(int i=0; i<120; i+=5){
    ledcWrite(ledChannel, map(i, 0, 180, 51, 102));
    get_pwm_info();
    delay(500);
  }

  for(int i=120; i>0; i-=5){
    ledcWrite(ledChannel, map(i, 0, 180, 51, 102));
    get_pwm_info();
    delay(500);
  }

完整的,之前连MQTT的先注释了,下次再加上MQTT的控制

#include <WiFi.h>
#include <Ethernet.h>
#include <PubSubClient.h>

const char* ssid     = "***";
const char* password = "***";
int currentDirection = 90;

const int freq = 50;
const int ledChannel = 0;
const int resolution = 10;//精度1024

const int ledPin = 5;

WiFiClient wifiClient;
PubSubClient client(wifiClient);

void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  int signal;
  for (int i=0;i<length;i++) {
    if((char)payload[i] == 'b'){

      digitalWrite(4, HIGH);
    }

    if((char)payload[i] == 'a'){
      digitalWrite(4, LOW);
    }

    if((char)payload[i] == 'r'){

    }

    if((char)payload[i] == 'l'){

    }
    Serial.print((char)payload[i]);
  }
  Serial.println();
}

void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    if (client.connect("arduinoClient")) {
      Serial.println("connected");
      // Once connected, publish an announcement...
      client.publish("outTopic","hello world");
      // ... and resubscribe
      client.subscribe("inTopic");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

void setup()
{
    Serial.begin(115200);
    delay(10);

    // We start by connecting to a WiFi network

    Serial.println(ssid);
    Serial.println(password);
    Serial.print("Connecting to ");
    Serial.println(ssid);

    WiFi.begin(ssid, password);

    while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
    }

    Serial.println("");
    Serial.println("WiFi connected");
    Serial.println("IP address: ");
    Serial.println(WiFi.localIP());

    client.setServer("*.*.*.*", 1883);
    client.setCallback(callback);

    pinMode(4, OUTPUT);

    ledcSetup(ledChannel, freq, resolution);
    ledcAttachPin(ledPin, ledChannel);
}

void loop()
{
//  if (!client.connected()) {
//    reconnect();
//  }
//
//  client.loop();

  //周期20ms, 有效占空比是1ms-2ms,1ms时0°,2ms时120°
  //精度2^10=1024,那么有效占空比就是51-102,51时0°,102时120°
  //90°时就是(51+102)/2 = 76
//  ledcWrite(ledChannel, 76);

  for(int i=0; i<120; i+=5){
    ledcWrite(ledChannel, map(i, 0, 120, 51, 102));
    get_pwm_info();
    delay(500);
  }

  for(int i=120; i>0; i-=5){
    ledcWrite(ledChannel, map(i, 0, 120, 51, 102));
    get_pwm_info();
    delay(500);
  }
}

制作一个通过wifi联网,可以远程控制的小车(一)

小车

车身就直接购买了,后轮俩直流电机带动,前轮由一个舵机控制。

硬件

ESP32 连接wifi,提供网络通信能力
L298P 电机驱动,可以同时驱动两路直流电机,11V供电,然后将5V供电再提供给ESP32。



这个L298P原本是搭配UNO版的esp8266的,可以直接叠在上面的,结果装好插上电源8266就毁了,我也不知道咋回事,只能又买了个EPS32了。

软件方面

云端用mosquitto建立mqtt BROKER
ESP32上 建立mqtt客户端,通过云端broker和控制端利用发布订阅方式通信。

arduinoIDE用到的库:
WIFI — 连接wifi
SubPubClient — mqtt发布订阅客户端

实际操作

这个是接收到订阅的消息时的回调函数,这里用4引脚作为输出,当收到消息第一个字符是b时高,a时低,
然后把IO4接到驱动的蜂鸣器引脚上,就可以控制发声了(蜂鸣器的控制在D4引脚)

这里测试的话可以用一个mqtt客户端工具mqttx来进行测试

完成这一步,和小车的通信就打通了,下一步就是怎么通过消息来实现小车的控制了

void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  char m = (char)payload[0];
  if(m == 'b'){
  digitalWrite(4, HIGH);
  }

  if(m == 'a'){
    digitalWrite(4, LOW);
  }
  Serial.println(m);
  Serial.println();
}

这段代码呢,就是先连wifi,然后客户端连mqtt broker

完整代码

#include <WiFi.h>
#include <Ethernet.h>
#include <PubSubClient.h>

const char* ssid     = "***";
const char* password = "***";

WiFiClient wifiClient;
PubSubClient client(wifiClient);

void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  char m = (char)payload[0];
  if(m == 'b'){
  digitalWrite(4, HIGH);
  }

  if(m == 'a'){
    digitalWrite(4, LOW);
  }
  Serial.println(m);
  Serial.println();
}

void reconnect() {
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    if (client.connect("arduinoClient")) {
      Serial.println("connected");
      client.publish("outTopic","hello world");
      client.subscribe("inTopic");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      delay(5000);
    }
  }
}

void setup()
{
    Serial.begin(115200);
    delay(10);

    // We start by connecting to a WiFi network

    Serial.println(ssid);
    Serial.println(password);
    Serial.print("Connecting to ");
    Serial.println(ssid);

    WiFi.begin(ssid, password);

    while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
    }

    Serial.println("");
    Serial.println("WiFi connected");
    Serial.println("IP address: ");
    Serial.println(WiFi.localIP());

    client.setServer("81.*.*.*", 1883);
    client.setCallback(callback);

    pinMode(4, OUTPUT);
}

void loop()
{
  if (!client.connected()) {
    reconnect();
  }
  client.loop();
}

Laravel model 使用trait+boot初始化

目标

用trait来给一些model添加通用的boot方法,加上相同的globalscope

解决方法

试了一下,直接在trait里面写boot方法是没用的,然后找到了这个问答

https://laracasts.com/discuss/channels/eloquent/cant-use-trait-if-i-have-a-boot-method-declared

原来源码里已经写好了这个调用了,搜索一下model里面的boot方法

/**
     * Bootstrap the model and its traits.
     *
     * @return void
     */
    protected static function boot()
    {
        static::bootTraits();
    }

    /**
     * Boot all of the bootable traits on the model.
     *
     * @return void
     */
    protected static function bootTraits()
    {
        $class = static::class;

        $booted = [];

        static::$traitInitializers[$class] = [];

        foreach (class_uses_recursive($class) as $trait) {
            $method = 'boot'.class_basename($trait);

            if (method_exists($class, $method) && ! in_array($method, $booted)) {
                forward_static_call([$class, $method]);

                $booted[] = $method;
            }

            if (method_exists($class, $method = 'initialize'.class_basename($trait))) {
                static::$traitInitializers[$class][] = $method;

                static::$traitInitializers[$class] = array_unique(
                    static::$traitInitializers[$class]
                );
            }
        }
    }

哈哈,原来框架已经实现好了,感叹一下确实想的太周到了哈!!
只要在trait里面写
‘boot’.class_basename($trait)
也就是boot+trait名字的方法就会被调用了。