Skip to content

Commit b2c4e00

Browse files
Add C++ exercises (#46)
* Update instructions to add more clarity * Initial import of exercise files * Initial devcontainer config for cmake * Updating container config * Completing exercises * Update main README
1 parent 2cf6be7 commit b2c4e00

33 files changed

+1131
-3
lines changed

.devcontainer/devcontainer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
]
3939
}
4040
},
41-
"postCreateCommand": "cd ./completesolution/node; npm install; cd ../../; dotnet restore ./completesolution/dotnet/MinimalAPI.sln; dotnet restore ./exercisefiles/dotnet/MinimalAPI.sln"
41+
"postCreateCommand": "sudo ./.devcontainer/scripts/install-cmake.sh; cd ./completesolution/node; npm install; cd ../../; dotnet restore ./completesolution/dotnet/MinimalAPI.sln; dotnet restore ./exercisefiles/dotnet/MinimalAPI.sln"
4242
// Features to add to the dev container. More info: https://containers.dev/features.
4343
// "features": {},
4444
// Use 'forwardPorts' to make a list of ports inside the container available locally.
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#!/usr/bin/env bash
2+
#-------------------------------------------------------------------------------------------------------------
3+
# Copyright (c) Microsoft Corporation. All rights reserved.
4+
# Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information.
5+
#-------------------------------------------------------------------------------------------------------------
6+
7+
set -e
8+
9+
echo "Installing apt packages..."
10+
apt-get update
11+
export DEBIAN_FRONTEND=noninteractive
12+
apt-get -y install build-essential cmake cppcheck valgrind clang lldb llvm gdb
13+
apt-get autoremove -y
14+
apt-get clean -y
15+
rm -rf /var/lib/apt/lists/*
16+
17+
echo "Installing vcpkg..."
18+
export VCPKG_ROOT=/usr/local/vcpkg
19+
export VCPKG_DOWNLOADS=/usr/local/vcpkg-downloads
20+
export PATH="${PATH}:${VCPKG_ROOT}"
21+
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
22+
"${DIR}/install-vcpkg.sh" vscode
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
#!/usr/bin/env bash
2+
#-------------------------------------------------------------------------------------------------------------
3+
# Copyright (c) Microsoft Corporation. All rights reserved.
4+
# Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information.
5+
#-------------------------------------------------------------------------------------------------------------
6+
7+
set -e
8+
9+
USERNAME=${1:-"vscode"}
10+
11+
. /etc/os-release
12+
13+
# Add to bashrc/zshrc files for all users.
14+
updaterc() {
15+
echo "Updating /etc/bash.bashrc and /etc/zsh/zshrc..."
16+
if [[ "$(cat /etc/bash.bashrc)" != *"$1"* ]]; then
17+
echo -e "$1" >> /etc/bash.bashrc
18+
fi
19+
if [ -f "/etc/zsh/zshrc" ] && [[ "$(cat /etc/zsh/zshrc)" != *"$1"* ]]; then
20+
echo -e "$1" >> /etc/zsh/zshrc
21+
fi
22+
}
23+
24+
# Run apt-get if needed.
25+
apt_get_update_if_needed() {
26+
if [ ! -d "/var/lib/apt/lists" ] || [ "$(ls /var/lib/apt/lists/ | wc -l)" = "0" ]; then
27+
echo "Running apt-get update..."
28+
apt-get update
29+
else
30+
echo "Skipping apt-get update."
31+
fi
32+
}
33+
34+
# Check if packages are installed and installs them if not.
35+
check_packages() {
36+
if ! dpkg -s "$@" > /dev/null 2>&1; then
37+
apt_get_update_if_needed
38+
apt-get -y install --no-install-recommends "$@"
39+
fi
40+
}
41+
42+
export DEBIAN_FRONTEND=noninteractive
43+
export VCPKG_FORCE_SYSTEM_BINARIES=1
44+
45+
# Install additional packages needed by vcpkg: https://github.com/microsoft/vcpkg/blob/master/README.md#installing-linux-developer-tools
46+
check_packages build-essential tar curl zip unzip pkg-config bash-completion ninja-build
47+
48+
# Setup group and add user
49+
umask 0002
50+
if ! cat /etc/group | grep -e "^vcpkg:" > /dev/null 2>&1; then
51+
groupadd -r "vcpkg"
52+
fi
53+
usermod -a -G "vcpkg" "${USERNAME}"
54+
55+
# Start Installation
56+
# Clone repository with ports and installer
57+
mkdir -p "${VCPKG_ROOT}"
58+
mkdir -p "${VCPKG_DOWNLOADS}"
59+
git clone --depth=1 \
60+
-c core.eol=lf \
61+
-c core.autocrlf=false \
62+
-c fsck.zeroPaddedFilemode=ignore \
63+
-c fetch.fsck.zeroPaddedFilemode=ignore \
64+
-c receive.fsck.zeroPaddedFilemode=ignore \
65+
https://github.com/microsoft/vcpkg "${VCPKG_ROOT}"
66+
67+
## Run installer to get latest stable vcpkg binary
68+
## https://github.com/microsoft/vcpkg/blob/7e7dad5fe20cdc085731343e0e197a7ae655555b/scripts/bootstrap.sh#L126-L144
69+
"${VCPKG_ROOT}"/bootstrap-vcpkg.sh
70+
71+
# Add vcpkg to PATH
72+
updaterc "$(cat << EOF
73+
export VCPKG_ROOT="${VCPKG_ROOT}"
74+
if [[ "\${PATH}" != *"\${VCPKG_ROOT}"* ]]; then export PATH="\${PATH}:\${VCPKG_ROOT}"; fi
75+
EOF
76+
)"
77+
78+
# Give read/write permissions to the user group.
79+
chown -R ":vcpkg" "${VCPKG_ROOT}" "${VCPKG_DOWNLOADS}"
80+
chmod g+r+w+s "${VCPKG_ROOT}" "${VCPKG_DOWNLOADS}"
81+
chmod -R g+r+w "${VCPKG_ROOT}" "${VCPKG_DOWNLOADS}"
82+
83+
# Enable tab completion for bash and zsh
84+
VCPKG_FORCE_SYSTEM_BINARIES=1 su "${USERNAME}" -c "${VCPKG_ROOT}/vcpkg integrate bash"
85+
VCPKG_FORCE_SYSTEM_BINARIES=1 su "${USERNAME}" -c "${VCPKG_ROOT}/vcpkg integrate zsh"

.gitignore

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -530,3 +530,40 @@ FodyWeavers.xsd
530530
*.sln.iml
531531
.idea/
532532

533+
# C++ excludes
534+
535+
# Prerequisites
536+
*.d
537+
538+
# Compiled Object files
539+
*.slo
540+
*.lo
541+
*.o
542+
*.obj
543+
544+
# Precompiled Headers
545+
*.gch
546+
*.pch
547+
548+
# Compiled Dynamic libraries
549+
*.so
550+
*.dylib
551+
*.dll
552+
553+
# Fortran module files
554+
*.mod
555+
*.smod
556+
557+
# Compiled Static libraries
558+
*.lai
559+
*.la
560+
*.a
561+
*.lib
562+
563+
# Executables
564+
*.exe
565+
*.out
566+
*.app
567+
568+
build
569+

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,9 @@ Run:
8282
**For Python**
8383
- [Install Python](https://www.python.org/downloads/)
8484

85+
**For C++**
86+
- [Install cmake](https://cmake.org/download/)
87+
8588
## Labs instructions
8689

8790
- [Node Server](./exercisefiles/node/README.md)
@@ -90,6 +93,7 @@ Run:
9093
- [Java Quarkus](./exercisefiles/quarkus/README.md)
9194
- [Python Data Engineer](./exercisefiles/dataengineer/README.md)
9295
- [Python Data Scientist](./exercisefiles/datascientist/README.md)
96+
- [C++](./exercisefiles/c++/README.md)
9397

9498
## Challenges instructions
9599

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
cmake_minimum_required(VERSION 3.14)
2+
3+
project(OctoConverter
4+
VERSION 1.0.0
5+
LANGUAGES CXX)
6+
7+
set(CMAKE_CXX_STANDARD 20)
8+
set(CMAKE_CXX_STANDARD_REQUIRED ON)
9+
10+
enable_testing()
11+
12+
add_subdirectory(src)
13+
add_subdirectory(test)
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
add_subdirectory(converters)
2+
add_executable(main main.cpp)
3+
target_link_libraries(main PRIVATE converters)
4+
5+
set_target_properties(
6+
main
7+
PROPERTIES
8+
RUNTIME_OUTPUT_DIRECTORY
9+
"${CMAKE_BINARY_DIR}"
10+
)
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
## Build a library "converters" with all included files
2+
add_library(
3+
converters
4+
distance.cpp
5+
distance.h
6+
temperature.cpp
7+
temperature.h
8+
weight.cpp
9+
weight.h
10+
types.h
11+
)
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
#include "distance.h"
2+
#include <iostream>
3+
#include <unordered_map>
4+
5+
namespace /* private */ {
6+
std::string getDistanceUnitSign(DistanceUnit unit)
7+
{
8+
std::unordered_map<DistanceUnit, std::string> unitSigns = {
9+
{DistanceUnit::Meters, "m"},
10+
{DistanceUnit::Feet, "ft"},
11+
{DistanceUnit::Yards, "yd"}
12+
};
13+
14+
return unitSigns.at(unit);
15+
}
16+
} // namespace private
17+
18+
namespace DistanceConversion
19+
{
20+
void startFlow()
21+
{
22+
double sourceValue = getSourceValue();
23+
DistanceUnit from = getDistanceUnit("source");
24+
DistanceUnit to = getDistanceUnit("target");
25+
26+
double targetValue = convertDistance(sourceValue, from, to);
27+
28+
std::cout << sourceValue << getDistanceUnitSign(from) << " is " << targetValue << getDistanceUnitSign(to) << std::endl;
29+
}
30+
31+
double getSourceValue()
32+
{
33+
double value;
34+
std::cout << "Enter the value to be converted: ";
35+
std::cin >> value;
36+
return value;
37+
}
38+
39+
DistanceUnit getDistanceUnit(const std::string_view &sourceOrTarget)
40+
{
41+
int choice;
42+
std::cout << "Select " << sourceOrTarget << " distance unit:\n";
43+
std::cout << "[1] Meters\n";
44+
std::cout << "[2] Feet\n";
45+
std::cout << "[3] Yards\n";
46+
std::cout << "Enter choice: ";
47+
std::cin >> choice;
48+
49+
switch (choice)
50+
{
51+
case 1:
52+
return DistanceUnit::Meters;
53+
case 2:
54+
return DistanceUnit::Feet;
55+
case 3:
56+
return DistanceUnit::Yards;
57+
default:
58+
return DistanceUnit::Meters; // Default to Meters
59+
}
60+
}
61+
62+
double convertDistance(double value, DistanceUnit from, DistanceUnit to)
63+
{
64+
if (from == to)
65+
{
66+
return value;
67+
}
68+
69+
if (from == DistanceUnit::Meters)
70+
{
71+
if (to == DistanceUnit::Feet)
72+
{
73+
return value * 3.28084;
74+
}
75+
else if (to == DistanceUnit::Yards)
76+
{
77+
return value * 1.09361;
78+
}
79+
}
80+
else if (from == DistanceUnit::Feet)
81+
{
82+
if (to == DistanceUnit::Meters)
83+
{
84+
return value / 3.28084;
85+
}
86+
else if (to == DistanceUnit::Yards)
87+
{
88+
return value / 3.0;
89+
}
90+
}
91+
else if (from == DistanceUnit::Yards)
92+
{
93+
if (to == DistanceUnit::Meters)
94+
{
95+
return value / 1.09361;
96+
}
97+
else if (to == DistanceUnit::Feet)
98+
{
99+
return value * 3.0;
100+
}
101+
}
102+
103+
return 0;
104+
}
105+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#ifndef DISTANCE_H
2+
#define DISTANCE_H
3+
4+
#include <string>
5+
6+
enum class DistanceUnit
7+
{
8+
Meters,
9+
Feet,
10+
Yards
11+
};
12+
13+
namespace DistanceConversion
14+
{
15+
void startFlow();
16+
double getSourceValue();
17+
DistanceUnit getDistanceUnit(const std::string_view &sourceOrTarget);
18+
double convertDistance(double value, DistanceUnit from, DistanceUnit to);
19+
}
20+
21+
#endif

0 commit comments

Comments
 (0)