General Remarks
Hello Cédric, Mitchell, Farros, Gedewon, Kenneth and Steven, first of all, your group submitted
this on time, so well done.
General remarks
What I like a lot was that you thought to add tests for your calculate power and charging logic.
These are the core of the system.
What worries me are:
● The submitted merge conflicts - meaning, your code does not compile at this moment.
● The building is not integrated with the chargers.
The above two points are critical and potentially project-breaking for you, please give those your
top priority.
Reading guide
I’ve split my comments in 2 big sections:
● Submission: the files you submitted beside the code
● Code: the actual code
I know it looks like a lot of comments, but the reason is because I’ve written down all remarks
that crossed my mind, even the nitpicking ones, so that you can be aware of these things.
For ease of reading, I’ve color coded the comments:
● Red: Obvious/potential bugs.
● Blue: Between must and should have; will improve the code a lot for me.
● Green: Compliment.
● Black: Nice to have.
Please prioritize the right comments to process at this stage, as I understand we don’t have
much time left.
Submission
First of all, it was delivered on time, well done.
1. README file
Thank you for delivering a README file. I appreciate your efforts to make my review go
smoother. Every reviewer has limited time and concentration to spend, so it’s always good
practice to think of them and make their work easier. That way, you maximize your learning.
Below are a few comments on how to further improve on your current files. Feel free to take this
along in your student experience:
“What to look at” section
●
●
Current situation: You mentioned to look at the source files and their headers, but there
are many, many of them.
Desired situation: If you can point me to the highlights of your code (in your case, the
building, the main system, the charging logic, calculate power, etc.), it would help me
know right away which files have my priority. If I spend less time searching, I spend more
time reviewing.
Consider such a table format like below for this section:
Class
Files
Building
Responsibility: abcxyz
Building.cpp
“Known issues” section
● Current situation: You mentioned issues with integration and multi-threading
● Desired situation: Consider adding more details to this, so the reader is aware of what
problems they can expect with the system:
○ Integration: What is not integrated (e.g. the main system with the charging logic)?
What does this mean (e.g. charging mode cannot be changed from the building)?
○ Multi-threading: Same comment as above. It was a bit unclear what is going
wrong with multi-threading.
2. Additional documents
Thank you for providing them. I take the 2 class diagrams provided next to the README as
reference for design.
Code
Building system
Main [source]
Line
Type of comment
Description
1
Clutter
@brief
Please give a brief description. Otherwise this section of the
comments add no extra value.
@author farros (you@domain.com)
Minor: please also update your email
12
Clutter
//NOTE - This main file only initiate the
building and looping the building tasks.
I would remove these. Maybe the school wants you to
comment more, so I understand why these are here.
Code should be expressive and explains itself. Comments
are more often than not clutter. The only useful comments
are those explaining why you’re doing something, not what
or how you’re doing it (as I can read that from the code).
For more info: see Chapter 4 of Clean Code by Robert C
Martin.
Many files have the same issues where their @brief tells me nothing, and/or the comments are
unnecessary. I remarked on it here, so I will not do that for other files.
Building [header]
Design mismatched with code. The Building class diagram does not show the actual state.
Line
Type of comment
Description
14
Strange code
#include
"../include/communication/com_manager.h"
I assume you had to include with relative path to compile for
Arduino, otherwise I expect a makefile.
I think ../include/ can be removed: your header is
already in the include/ folder.
19
Readability
Better to put public things first, and private later. The
reader wants to first see what they can use from your API.
23 + 26
Consistency
void begin();
int GetCurrentMode();
Minor: inconsistency in style, please pick either
lowerCamelCase or UpperCamelCase.
31
Undescriptive name
UiManager interface;
Interface is a very generic term. What is it an interface to?
Consider: uiManager or uiInterface
46
Strange code
static void MessageReceived(uint32_t from,
String &msg)
Is there a reason why these two cannot be normal function
members?
Hesitate to make static functions. They’re often a sign that
you’re not doing OOP (as static functions don’t use the state
of the object).
Building [source]
Line
Type of comment
Description
35
Strange code
Potential bug
currentMode = Mode::DIRECTOR;
// Default
mode
I thought DIRECTOR was the special case and not the
default one?
49
Strange code
ProcessSerial(this);
An extra sign that ProcessSerial is just a normal
function - why is a static function interested in this object?
81
Undescriptive
name
serialInput = ProcessCommand(command);
“Process” can mean many things. Why not
convertToInputcommand(command)?
83
Magic numbers
These magic numbers in switch cases: please make an
InputCommand enum for them.
95
Strange code
I know you set the currentProfile in another function,
but imagine at first glance how
ChangeProfile(currentProfile) looks wrong.
Why not instead:
newProfile =
convertToProfile(profileInput);
ChangeProfile(newProfile)
105
Compliment
You thought to add the default case, I like.
141+172
Strange code
Why not return a Profile enum or a Mode enum?
257+252
Refactor point
Extract the switch case to NotifyProfileChanged
and NotifyModeChanged function.
197+207
Unused code
Getters unused. They also should return the enum they’re
getting, not an int.
319
Consistency
String profile_to_send;
Same as with functions, decide if you want
lowerCamelCase or snake_case.
322
Hardcoded strings
This switch case with “FIFO” “QUEUE” “STATIC” is
really just an enum to string.
We can use a map in C++ to do that, for example:
std::map<Command, std::string>
commandToString = {
{ Command::NONE, "NONE" },
{ Command::SEND, "SEND" },
};
String profileToSend =
commandToString[Command::NONE]
335
Hardcoded strings
See comment on line 322.
350
Unremoved
TODO?
// TODO - Adding logic algorithm for power
supply!
Is this still not done? If so, why were these not mentioned
in known issues?
ComManager [source]
Mismatched the provided design.
Line
Type of comment
Description
39
Strange code
Here you have all these local callbacks, except for
MessageReceived - which is injected in by the Building.
Any reason for not putting MessageReceived inside
ComManager?
Main
●
●
Many merge conflicts in this one. Please resolve them ASAP.
Please remove fully commented out files as well: seen in includemanager.
Main [source]
Line
Type of comment
Description
1
Broken code
<<<<<<< HEAD
Please fix these, and give that your priority. These
conflicts mean your code is currently broken and you
have no product.
18+21
Strange code
Why not just delay for 7 seconds either at start or end,
instead of 5 initially, and then 2 at the end?
20
Strange code
meshNetwork.send("Hello");
We now send a “Hello” every few seconds. Is this
intended as a heartbeat keep-alive thing, or should this
have been removed?
MainSystem [header]
Mismatched with provided design as it’s incomplete. I expected this to be mentioned in the
Known Issues.
Line
Type of comment
Description
16
Strange code
main() implemented in a header file, please move to
cpp and also don’t call it main() - that’s misleading as
this is not the entry point of your program.
Consider: update() to be consistent with other files.
19
Bug
The while true loop is very strange here. This means
that if I call mainSystem from main.cpp I will no longer
return to do other tasks in main.cpp as I’m stuck in this
state machine.
Enums [header]
Line
Type of comment
Description
6
Undescriptive
name
enum userType {EMPTY = 0, ND = 1, D = 2};
In line 4 we were using DIRECTOR and
NON-DIRECTOR, why not use it here?
CalculatePower [header]
Mismatched with provided design.
Line
Type of comment
Description
20
Strange code
CalculateShare modifies a float pointer and returns a
success indication. This is C style code.
Why not: float CalculateShare to return the power
share, and throw an exception if things go wrong. Same
for other functions below.
CalculatePower [source]
Line
Type of comment
Description
3
Function too big
CalculateShare is at least 6 functions in a trench coat.
See Appendix A for a proposal to improve.
3 to 115
Magic numbers
All these 1.5, 4, etc numbers don’t mean anything to me.
Please put them in variables and give a descriptive name.
137
Readability
Just return calculatedTotal <=
(powerInfo.totalBudget powerInfo.powerMargin) also works.
CalculatePowerTest [source]
Line
Type of comment
Description
1
Compliment
Tests, you have them!
20
Undescriptive
name
CalculateShareTest1 tells me nothing. Test names
often tells what the input and expected results are e.g.
WhenDirectorAndFifo_CalculateShareReturns2
5Percent
Overall
Readability
The tests are hard to read for me. I don’t understand what
the magic numbers are, and I don’t know what exactly the
tests are testing.
ChargingLogic [header]
Mismatched with provided design.
Line
Type of comment
Description
17
Strange code
C style function, see CalculateShare comment.
22
Undescriptive
name
Usually a function returning boolean is named like a
question. In your case, consider: isAllowedToCharge
ChargingLogic [source]
Line
Type of comment
Description
4
Strange code
Here you want to clamp values so it doesn’t go past max
charge of 100%.
Consider replacing the if/else with:
myInfo.batteryLevel += calculatedAddedPower;
myInfo.batteryLevel =
std::min(myInfo.batteryLevel, MAX_CHARGE);
18
Readability
return myInfo.batteryLevel >=
upperBatteryLimit also works.
ChargingLogicTest [source]
Line
Type of comment
Description
1
Compliment
Again, tests, you have them!
21
Compliment
Names are more descriptive than the other test I read, so
good job!
UI_ESP
Main [source]
Line
Type of comment
Description
1
Question
This looks like example code from PainlessMesh, and I
remember seeing similar code in the Main folder.
What is the responsibility of this folder UI_ESP?
20
Dead code
Please remove unused comments.
Appendix A. CalculatePower changes
Currently, you have all this “switch based on mode and profile” behavior in CalculateShare that’s usually a sign that a few tortured objects are trying to get out.
Consider these changes, where the calculation will be encapsulated fully in objects:
1. Make an abstract PowerCalculator with a virtual calculate()
2. Make for each type of calculation, an object, e.g. FifoPowerCalculator,
DirectorFifoPowerCalculator
3. In these objects, implement the calculate() method according to the type.
4. Make a PowerCalculatorFactory - this factory will create the right calculator based
on a profile and mode (see Factory Design Pattern)
5. The entirety of your CalculateShare function now becomes:
return PowerCalculatorFactory::create(profile,
mode)->calculate(connectedUsers)
I prepared snippet below to show you what I mean. That code has issues with memory and is
not directly usable - something for you to solve if you’d like to use it.
0
You can add this document to your study collection(s)
Sign in Available only to authorized usersYou can add this document to your saved list
Sign in Available only to authorized users(For complaints, use another form )