Browse Source

delete educoder created file

pull/4/head
abnerhexu 1 year ago
parent
commit
3901279620
31 changed files with 797 additions and 0 deletions
  1. +4
    -0
      .gitignore
  2. +37
    -0
      programmming/01-class-construct/main.cc
  3. +31
    -0
      programmming/02-class-destruct/main.cc
  4. +42
    -0
      programmming/03-class-clone/main.cc
  5. +67
    -0
      programmming/04-class-move/main.cc
  6. +52
    -0
      programmming/05-class-derive/main.cc
  7. +82
    -0
      programmming/06-class-virtual/main.cc
  8. +62
    -0
      programmming/07-class-virtual-destruct/main.cc
  9. +112
    -0
      programmming/08-class-template/main.cc
  10. +19
    -0
      programmming/checker.h
  11. +11
    -0
      snippets/lec1/01-const-expr.cc
  12. +12
    -0
      snippets/lec1/02-structured-binding.cc
  13. +10
    -0
      snippets/lec1/03-type-inference-auto.cc
  14. +11
    -0
      snippets/lec1/04-type-inference-decltype.cc
  15. +13
    -0
      snippets/lec1/05-template-add.cc
  16. +16
    -0
      snippets/lec1/06-template-with-auto.cc
  17. +14
    -0
      snippets/lec1/07-template-args.cc
  18. +16
    -0
      snippets/lec1/08-template-recursive-args.cc
  19. +12
    -0
      snippets/lec1/09-template-unwrap-args.cc
  20. +16
    -0
      snippets/lec1/10-vec-for-loop.cc
  21. +8
    -0
      snippets/lec1/11-class-template.cc
  22. +19
    -0
      snippets/lec1/12-non-class-template.cc
  23. +30
    -0
      snippets/lec2/01-comparison.cc
  24. +12
    -0
      snippets/lec2/02-pythonic-add.cc
  25. +33
    -0
      snippets/lec2/03-higher-order-functions.cc
  26. +6
    -0
      snippets/lec2/py-01-lambda.py
  27. +13
    -0
      snippets/lec2/py-02-higher-order-functions.py
  28. +12
    -0
      snippets/lec3/01-std-shared-ptr.cc
  29. +15
    -0
      snippets/lec3/py-gc.py
  30. +10
    -0
      snippets/lec3/py-ref-count.py
  31. +0
    -0
      src/.gitkeep

+ 4
- 0
.gitignore View File

@@ -0,0 +1,4 @@
.vscode
cc/build
*/__pycache__
*.pyc

+ 37
- 0
programmming/01-class-construct/main.cc View File

@@ -0,0 +1,37 @@
#include "../checker.h"
#include <vector>
// C++ 中,`class` 和 `struct` 之间的**唯一区别**是
// `class` 默认访问控制符是 `private`,
// `struct` 默认访问控制符是 `public`。
// READ: 访问说明符 <https://zh.cppreference.com/w/cpp/language/access>

// 这个 class 中的字段被 private 修饰,只能在 class 内部访问。
// 因此必须提供构造器来初始化字段。
// READ: 构造器 <https://zh.cppreference.com/w/cpp/language/constructor>

// 缓存的Fibonacci数列计算:
// 可以考虑将之前计算好的结果保存到vector中,计算时先检查是否已经计算过,如果已经计算过,
// 直接返回结果,反之按照递推公式进行计算

class Fibonacci {
std::vector<size_t> cache;
int cached;

public:
// 实现构造器 初始化Fibonacci类的某些字段
Fibonacci() {}

// TODO: 实现正确的缓存优化斐波那契计算
size_t get(int i) {
}
};

int main() {
// 现在类型拥有无参构造器,声明时会直接调用。
// 这个写法不再是未定义行为了。
Fibonacci fib;
ASSERT(fib.get(10) == 55, "fibonacci(10) should be 55");
std::cout << "fibonacci(10) = " << fib.get(10) << std::endl;
return 0;
}

+ 31
- 0
programmming/02-class-destruct/main.cc View File

@@ -0,0 +1,31 @@
#include "../checker.h"

// READ: 析构函数 <https://zh.cppreference.com/w/cpp/language/destructor>
// READ: RAII <https://learn.microsoft.com/zh-cn/cpp/cpp/object-lifetime-and-resource-management-modern-cpp?view=msvc-170>

// 构造任意缓存容量的斐波那契类型。
// 可以在构造时传入缓存容量,因此需要动态分配缓存空间。

class DynFibonacci {
size_t *cache;
int cached;

public:
// TODO: 实现动态设置容量的构造器
DynFibonacci(int capacity) {}

// TODO: 实现析构器,释放缓存空间
~DynFibonacci() {}

// TODO: 实现正确的缓存优化斐波那契计算
size_t get(int i) {
}
};

int main(int argc, char **argv) {
DynFibonacci fib(12);
ASSERT(fib.get(10) == 55, "fibonacci(10) should be 55");
std::cout << "fibonacci(10) = " << fib.get(10) << std::endl;
return 0;
}

+ 42
- 0
programmming/03-class-clone/main.cc View File

@@ -0,0 +1,42 @@
#include "../checker.h"
#include <vector>

// READ: 复制构造函数 <https://zh.cppreference.com/w/cpp/language/copy_constructor>
// READ: 函数定义(显式弃置)<https://zh.cppreference.com/w/cpp/language/function>


class Fibonacci {
std::vector<size_t> cache;
int cached;

public:
// TODO: 实现动态设置容量的构造器
Fibonacci(int capacity) {}

// TODO: 实现复制构造器
Fibonacci(Fibonacci const &other) {}

// TODO: 实现正确的缓存优化斐波那契计算
size_t get(int i) {
}

// NOTICE: 不要修改这个方法
// NOTICE: 名字相同参数也相同,但 const 修饰不同的方法是一对重载方法,可以同时存在
// 本质上,方法是隐藏了 this 参数的函数
// const 修饰作用在 this 上,因此它们实际上参数不同
size_t get(int i) const {
if (i <= cached) {
return cache[i];
}
ASSERT(false, "i out of range");
}
};

int main(int argc, char **argv) {
Fibonacci fib(12);
ASSERT(fib.get(10) == 55, "fibonacci(10) should be 55");
Fibonacci const fib_ = fib;
ASSERT(fib_.get(10) == fib.get(10), "Object cloned");
return 0;
}

+ 67
- 0
programmming/04-class-move/main.cc View File

@@ -0,0 +1,67 @@
#include "../checker.h"
#include <vector>

// READ: 左值右值(概念)<https://learn.microsoft.com/zh-cn/cpp/c-language/l-value-and-r-value-expressions?view=msvc-170>
// READ: 左值右值(细节)<https://zh.cppreference.com/w/cpp/language/value_category>
// READ: 关于移动语义 <https://learn.microsoft.com/zh-cn/cpp/cpp/rvalue-reference-declarator-amp-amp?view=msvc-170#move-semantics>
// READ: 如果实现移动构造 <https://learn.microsoft.com/zh-cn/cpp/cpp/move-constructors-and-move-assignment-operators-cpp?view=msvc-170>

// READ: 移动构造函数 <https://zh.cppreference.com/w/cpp/language/move_constructor>
// READ: 移动赋值 <https://zh.cppreference.com/w/cpp/language/move_assignment>
// READ: 运算符重载 <https://zh.cppreference.com/w/cpp/language/operators>

class DynFibonacci {
size_t *cache;
int cached;

public:
// TODO: 实现动态设置容量的构造器
DynFibonacci(int capacity) {}

// TODO: 实现移动构造器
DynFibonacci(DynFibonacci && other) {
};

// TODO: 实现移动赋值
// NOTICE: ⚠ 注意移动到自身问题 ⚠
DynFibonacci &operator=(DynFibonacci && other) noexcept {
// ASK AI: 这里的 noexcept 是什么含义?
}

// TODO: 实现正确的缓存优化斐波那契计算
// 我们重载了下标运算符,请给出正确的实现
size_t operator[](int i) {
}

// NOTICE: 不要修改这个方法
// THINK: 这个方法和上面的方法有什么不同?
size_t operator[](int i) const {
ASSERT(i <= cached, "i out of range");
return cache[i];
}

// NOTICE: 不要修改这个方法
bool is_alive() const {
return cache;
}
};

int main(int argc, char **argv) {
DynFibonacci fib(12);
ASSERT(fib[10] == 55, "fibonacci(10) should be 55");

DynFibonacci const fib_ = std::move(fib);
ASSERT(!fib.is_alive(), "Object moved");
ASSERT(fib_[10] == 55, "fibonacci(10) should be 55");

DynFibonacci fib0(6);
DynFibonacci fib1(12);

fib0 = std::move(fib1);
fib0 = std::move(fib0);
ASSERT(fib0[10] == 55, "fibonacci(10) should be 55");

return 0;
}

+ 52
- 0
programmming/05-class-derive/main.cc View File

@@ -0,0 +1,52 @@
#include "../checker.h"

// READ: 派生类 <https://zh.cppreference.com/w/cpp/language/derived_class>

class Instruction {
public:
uint32_t raw;
public:
Instruction(uint32_t raw) : raw(raw) {}
};

class RTypeInstruction: public Instruction {
public:
RTypeInstruction(uint32_t raw) : Instruction(raw) {}
void get_rs1() {
std::cout << ((this->raw >> 15) & 0b11111) << std::endl;
}
void get_rs2() {
std::cout << ((this->raw >> 20) & 0b11111) << std::endl;
}
void get_rd() {
std::cout << ((this->raw >> 7) & 0b11111) << std::endl;
}
std::string get_op() {
return "Not implementaed due to unknown instruction type";
}
};

class AddInst: public RTypeInstruction {
public:
AddInst(uint32_t raw) : RTypeInstruction(raw) {}
std::string get_op() {
return "add op";
}
};

int main() {
auto inst = AddInst(0x00728b33);
inst.get_rs1();
inst.get_rs2();
inst.get_rd();
inst.get_op();
auto rinst1 = dynamic_cast<RTypeInstruction*>(&inst);
if (rinst1) {
// TODO: 填入正确答案
ASSERT(rinst1->get_op() == "", "get_op() should return " + rinst1->get_op());
}
RTypeInstruction rinst2 = inst;
// TODO: 填入正确答案
ASSERT(rinst2.get_op() == "", "get_op() should return " + rinst2.get_op());
return 0;
}

+ 82
- 0
programmming/06-class-virtual/main.cc View File

@@ -0,0 +1,82 @@
#include "../checker.h"

// READ: 虚函数 <https://zh.cppreference.com/w/cpp/language/virtual>

struct A {
virtual char virtual_name() const {
return 'A';
}
char direct_name() const {
return 'A';
}
};
struct B : public A {
// READ: override <https://zh.cppreference.com/w/cpp/language/override>
char virtual_name() const override {
return 'B';
}
char direct_name() const {
return 'B';
}
};
struct C : public B {
// READ: final <https://zh.cppreference.com/w/cpp/language/final>
char virtual_name() const final {
return 'C';
}
char direct_name() const {
return 'C';
}
};
struct D : public C {
char direct_name() const {
return 'D';
}
};

int main(int argc, char **argv) {
constexpr auto MSG = "Replace '?' with its correct name.";

A a;
B b;
C c;
D d;

ASSERT(a.virtual_name() == '?', MSG);
ASSERT(b.virtual_name() == '?', MSG);
ASSERT(c.virtual_name() == '?', MSG);
ASSERT(d.virtual_name() == '?', MSG);
ASSERT(a.direct_name() == '?', MSG);
ASSERT(b.direct_name() == '?', MSG);
ASSERT(c.direct_name() == '?', MSG);
ASSERT(d.direct_name() == '?', MSG);

A &rab = b;
B &rbc = c;
C &rcd = d;

ASSERT(rab.virtual_name() == '?', MSG);
ASSERT(rbc.virtual_name() == '?', MSG);
ASSERT(rcd.virtual_name() == '?', MSG);
ASSERT(rab.direct_name() == '?', MSG);
ASSERT(rbc.direct_name() == '?', MSG);
ASSERT(rcd.direct_name() == '?', MSG);

A &rac = c;
B &rbd = d;

ASSERT(rac.virtual_name() == '?', MSG);
ASSERT(rbd.virtual_name() == '?', MSG);
ASSERT(rac.direct_name() == '?', MSG);
ASSERT(rbd.direct_name() == '?', MSG);

A &rad = d;

ASSERT(rad.virtual_name() == '?', MSG);
ASSERT(rad.direct_name() == '?', MSG);

return 0;
}

// READ: 扩展阅读-纯虚、抽象 <https://zh.cppreference.com/w/cpp/language/abstract_class>
// READ: 扩展阅读-虚继承 <https://zh.cppreference.com/w/cpp/language/derived_class>

+ 62
- 0
programmming/07-class-virtual-destruct/main.cc View File

@@ -0,0 +1,62 @@
#include "../checker.h"

struct A {
// TODO: 正确初始化静态字段
static int num_a = 0;

A() {
++num_a;
}
~A() {
--num_a;
}

virtual char name() const {
return 'A';
}
};
struct B final : public A {
// TODO: 正确初始化静态字段
static int num_b = 0;

B() {
++num_b;
}
~B() {
--num_b;
}

char name() const final {
return 'B';
}
};

int main(int argc, char **argv) {
auto a = new A;
auto b = new B;
ASSERT(A::num_a == ?, "Fill in the correct value for A::num_a");
ASSERT(B::num_b == ?, "Fill in the correct value for B::num_b");
ASSERT(a->name() == '?', "Fill in the correct value for a->name()");
ASSERT(b->name() == '?', "Fill in the correct value for b->name()");

delete a;
delete b;
ASSERT(A::num_a == 0, "Every A was destroyed");
ASSERT(B::num_b == 0, "Every B was destroyed");

A *ab = new B;// 派生类指针可以随意转换为基类指针
ASSERT(A::num_a == ?, "Fill in the correct value for A::num_a");
ASSERT(B::num_b == ?, "Fill in the correct value for B::num_b");
ASSERT(ab->name() == '?', "Fill in the correct value for ab->name()");

// TODO: 基类指针无法随意转换为派生类指针,补全正确的转换语句
B &bb = *ab;
ASSERT(bb.name() == '?', "Fill in the correct value for bb->name()");

// TODO: ---- 以下代码不要修改,通过改正类定义解决编译问题 ----
delete ab;// 通过指针可以删除指向的对象,即使是多态对象
ASSERT(A::num_a == 0, "Every A was destroyed");
ASSERT(B::num_b == 0, "Every B was destroyed");

return 0;
}

+ 112
- 0
programmming/08-class-template/main.cc View File

@@ -0,0 +1,112 @@
#include "../checker.h"
#include <cstring>
// READ: 类模板 <https://zh.cppreference.com/w/cpp/language/class_template>

template<class T>
struct Tensor4D {
unsigned int shape[4];
T *data;

Tensor4D(unsigned int const shape_[4], T const *data_) {
unsigned int size = 1;
// TODO: 填入正确的 shape 并计算 size
data = new T[size];
std::memcpy(data, data_, size * sizeof(T));
}
~Tensor4D() {
delete[] data;
}

// 为了保持简单,禁止复制和移动
Tensor4D(Tensor4D const &) = delete;
Tensor4D(Tensor4D &&) noexcept = delete;

// 这个加法需要支持“单向广播”。
// 具体来说,`others` 可以具有与 `this` 不同的形状,形状不同的维度长度必须为 1。
// `others` 长度为 1 但 `this` 长度不为 1 的维度将发生广播计算。
// 例如,`this` 形状为 `[1, 2, 3, 4]`,`others` 形状为 `[1, 2, 1, 4]`,
// 则 `this` 与 `others` 相加时,3 个形状为 `[1, 2, 1, 4]` 的子张量各自与 `others` 对应项相加。
Tensor4D &operator+=(Tensor4D const &others) {
// TODO: 实现单向广播的加法
// check whether a dimension needs broadcast
return *this;
}
};

// ---- 不要修改以下代码 ----
int main(int argc, char **argv) {
{
unsigned int shape[]{1, 2, 3, 4};
// clang-format off
int data[]{
1, 2, 3, 4,
5, 6, 7, 8,
9, 10, 11, 12,

13, 14, 15, 16,
17, 18, 19, 20,
21, 22, 23, 24};
// clang-format on
auto t0 = Tensor4D(shape, data);
auto t1 = Tensor4D(shape, data);
t0 += t1;
for (auto i = 0u; i < sizeof(data) / sizeof(*data); ++i) {
ASSERT(t0.data[i] == data[i] * 2, "Tensor doubled by plus its self.");
}
}
{
unsigned int s0[]{1, 2, 3, 4};
// clang-format off
float d0[]{
1, 1, 1, 1,
2, 2, 2, 2,
3, 3, 3, 3,

4, 4, 4, 4,
5, 5, 5, 5,
6, 6, 6, 6};
// clang-format on
unsigned int s1[]{1, 2, 3, 1};
// clang-format off
float d1[]{
6,
5,
4,

3,
2,
1};
// clang-format on

auto t0 = Tensor4D(s0, d0);
auto t1 = Tensor4D(s1, d1);
t0 += t1;
for (auto i = 0u; i < sizeof(d0) / sizeof(*d0); ++i) {
ASSERT(t0.data[i] == 7.f, "Every element of t0 should be 7 after adding t1 to it.");
}
}
{
unsigned int s0[]{1, 2, 3, 4};
// clang-format off
double d0[]{
1, 2, 3, 4,
5, 6, 7, 8,
9, 10, 11, 12,

13, 14, 15, 16,
17, 18, 19, 20,
21, 22, 23, 24};
// clang-format on
unsigned int s1[]{1, 1, 1, 1};
double d1[]{1};

auto t0 = Tensor4D(s0, d0);
auto t1 = Tensor4D(s1, d1);
t0 += t1;
for (auto i = 0u; i < sizeof(d0) / sizeof(*d0); ++i) {
ASSERT(t0.data[i] == d0[i] + 1, "Every element of t0 should be incremented by 1 after adding t1 to it.");
}
}
}

+ 19
- 0
programmming/checker.h View File

@@ -0,0 +1,19 @@
#ifndef __EXERCISE_H__
#define __EXERCISE_H__

#include <iostream>

#define ASSERT(COND, MSG) \
if (!(COND)) { \
std::cerr << "\x1b[31mAssertion failed at line #" << __LINE__ << ": \x1b[0m" << std::endl \
<< std::endl \
<< #COND << std::endl \
<< std::endl \
<< "\x1b[34mMessage:\x1b[0m" << std::endl \
<< std::endl \
<< MSG << std::endl \
<< std::endl; \
exit(1); \
}

#endif// __EXERCISE_H__

+ 11
- 0
snippets/lec1/01-const-expr.cc View File

@@ -0,0 +1,11 @@
#include <iostream>

constexpr int fibonacci(const int n) {
return n == 1 || n == 2 ? 1 : fibonacci(n-1)+fibonacci(n-2);
}

int main(){
int fib_5 = fibonacci(5);
std::cout << "fib 5: " << fib_5 << std::endl;
return 0;
}

+ 12
- 0
snippets/lec1/02-structured-binding.cc View File

@@ -0,0 +1,12 @@
#include <iostream>
#include <tuple>

std::tuple<int, double, std::string> get_data() {
return std::make_tuple(1, 2.71828, "hello");
}

int main() {
auto [a, b, c] = get_data();
std::cout << a << " " << b << " " << c << std::endl;
return 0;
}

+ 10
- 0
snippets/lec1/03-type-inference-auto.cc View File

@@ -0,0 +1,10 @@
#include <iostream>
#include <vector>

int main() {
std::vector<int> vec;
std::vector<int>::const_iterator a = vec.cbegin();
// using type inference
auto b = vec.cbegin();
return 0;
}

+ 11
- 0
snippets/lec1/04-type-inference-decltype.cc View File

@@ -0,0 +1,11 @@
#include <iostream>

int main() {
auto x = 1;
auto y = 2.0;
decltype(x+y) z;
if (std::is_same<decltype(x+y), double>::value) {
std::cout << "x+y is double" << std::endl;
}
return 0;
}

+ 13
- 0
snippets/lec1/05-template-add.cc View File

@@ -0,0 +1,13 @@
#include <iostream>

template<typename T>
T add(T a, T b) {
return a + b;
}

int main() {
double a = 1.0;
double b = 2.0;
std::cout << add<double>(a, b) << std::endl;
return 0;
}

+ 16
- 0
snippets/lec1/06-template-with-auto.cc View File

@@ -0,0 +1,16 @@
#include <iostream>

template<typename T, typename U>
auto add(T x, U y){
return x + y;
}

int main() {
int a = 1;
double b = 2.71828;
std::cout << add(a, b) << std::endl;
if (std::is_same<decltype(add(a, b)), double>::value) {
std::cout << "result type of add(a, b) is double!" << std::endl;
}
return 0;
}

+ 14
- 0
snippets/lec1/07-template-args.cc View File

@@ -0,0 +1,14 @@
#include <iostream>

template<typename... Ts>
void magic(Ts... args) {
std::cout << sizeof...(args) << std::endl;
}

int main() {
magic();
magic(1);
magic(1, 2);
magic(1, "hello", "world");
return 0;
}

+ 16
- 0
snippets/lec1/08-template-recursive-args.cc View File

@@ -0,0 +1,16 @@
#include <iostream>
template<typename T>
void my_printf(T value) {
std::cout << value << std::endl;
}

template<typename T, typename... Ts>
void my_printf(T value, Ts... args) {
std::cout << value << std::endl;
my_printf(args...);
}

int main() {
my_printf(1, 2, "San Francisco", 1.1);
return 0;
}

+ 12
- 0
snippets/lec1/09-template-unwrap-args.cc View File

@@ -0,0 +1,12 @@
#include <iostream>

template<typename T, typename... Ts>
void my_printf(T t0, Ts... t) {
std::cout << t0 << std::endl;
if constexpr (sizeof...(t) > 0) my_printf(t...);
}

int main() {
my_printf(1, 2, "San Francisco", 1.1);
return 0;
}

+ 16
- 0
snippets/lec1/10-vec-for-loop.cc View File

@@ -0,0 +1,16 @@
#include <iostream>
#include <vector>

int main() {
std::vector<int> v = {1, 2, 3, 4, 5};
for (auto it: v) {
std::cout << it << std::endl;
}
for (auto &it: v) {
it = it * 2;
}
for (auto it: v) {
std::cout << it << std::endl;
}
return 0;
}

+ 8
- 0
snippets/lec1/11-class-template.cc View File

@@ -0,0 +1,8 @@
template<class T>
struct point {
T x;
T y;
};

point<double> p1{1.0, 2.0};
point<int> p2{1, 2};

+ 19
- 0
snippets/lec1/12-non-class-template.cc View File

@@ -0,0 +1,19 @@
#include <iostream>

// define a template for calculating factorial
template<int N>
struct Factorial {
static const int value = N * Factorial<N - 1>::value;
};

// specialized template to end the factorial recursive
template<>
struct Factorial<0> {
static const int value = 1;
};

int main() {
std::cout << "Factorial of 5 is: " << Factorial<5>::value << std::endl;
std::cout << "Factorial of 10 is: " << Factorial<10>::value << std::endl;
return 0;
}

+ 30
- 0
snippets/lec2/01-comparison.cc View File

@@ -0,0 +1,30 @@
#include <algorithm>
#include <iostream>
#include <vector>

struct CppRecord {
size_t id;
double value;
};

int main() {
std::vector<CppRecord> records = {
{1, 3.5},
{2, 2.0},
{3, 3.5},
{4, 1.0},
{5, 2.0}};

std::sort(records.begin(), records.end(), [](const CppRecord& a, const CppRecord& b) {
if (a.value != b.value) {
return a.value < b.value;
} else {
return a.id < b.id;
}
});

for (const auto& record : records) {
std::cout << record.id << " " << record.value << std::endl;
}
return 0;
}

+ 12
- 0
snippets/lec2/02-pythonic-add.cc View File

@@ -0,0 +1,12 @@
#include <iostream>

int main() {
auto add = [](auto x, auto y) {
return x+y;
};

auto r1 = add(1, 2);
auto r2 = add(1.1, 2.2);
std::cout << r1 << " " << r2 << std::endl;
return 0;
}

+ 33
- 0
snippets/lec2/03-higher-order-functions.cc View File

@@ -0,0 +1,33 @@
#include <iostream>
#include <functional>
#include <vector>

// define a higher order function, composing all functions together
template<typename T>
std::function<T(T)> compose(std::vector<std::function<T(T)>> functions) {
return [functions](T x) {
T result = x;
// apply all these function from the right to the left
for (auto it = functions.rbegin(); it != functions.rend(); ++it) {
result = (*it)(result);
}
return result;
};
}

int main() {
// define a couple of simple functions
auto add_one = [](int x) { return x + 1; };
auto square = [](int x) { return x * x; };
auto double_value = [](int x) { return x * 2; };

// compose the functions
std::vector<std::function<int(int)>> functions = {double_value, square, add_one};
auto pipeline = compose(functions);

// test the composed functions
int result = pipeline(3);
std::cout << result << std::endl; // output: 32

return 0;
}

+ 6
- 0
snippets/lec2/py-01-lambda.py View File

@@ -0,0 +1,6 @@
a = [42, 23, -17, 11, -8, 15, -38, 23, 18, -1]

# sort by absolute value
a.sort(key=lambda x: abs(x))

print(a)

+ 13
- 0
snippets/lec2/py-02-higher-order-functions.py View File

@@ -0,0 +1,13 @@
# define a higher order function
# note: this function receives a function as an argument
def apply_twice(func, x):
# note: this function returns a function
return func(func(x))

# define a simple function
def square(x):
return x * x

# use this higher order function
result = apply_twice(square, 2)
print(result) # output: 16

+ 12
- 0
snippets/lec3/01-std-shared-ptr.cc View File

@@ -0,0 +1,12 @@
#include <memory>
#include <iostream>
void foo(std::shared_ptr<int> p) {
(*p)++;
}

void create() {
std::shared_ptr<int> p = std::make_shared<int>(42);
foo(p);
// p is still valid
std::cout << *p << std::endl;
} // when leaving this scope, p will be destroyed (deleted)

+ 15
- 0
snippets/lec3/py-gc.py View File

@@ -0,0 +1,15 @@
import gc

class FooClass:
def __init__(self):
self.value = 1
def __del__(self):
print(f"FooClass {id(self)} destroyed!")

foo1 = FooClass()
foo2 = foo1
del foo1
print("Called del foo1")
gc.collect()
foo2.value += 1
print("Called foo2.value += 1")

+ 10
- 0
snippets/lec3/py-ref-count.py View File

@@ -0,0 +1,10 @@
import sys
a = [1, 2, 3]
print(f"a's reference count: {sys.getrefcount(a)}")
b = a
print(f"a's reference count: {sys.getrefcount(a)}")
print(f"b's reference count: {sys.getrefcount(b)}")
del b
print(f"a's reference count: {sys.getrefcount(a)}")
del a
print(f"a's reference count: {sys.getrefcount(a)}")

+ 0
- 0
src/.gitkeep View File


Loading…
Cancel
Save