markusvoelter / programmingbasics Goto Github PK
View Code? Open in Web Editor NEWHow to think like a programmer.
License: MIT License
How to think like a programmer.
License: MIT License
"If you wanted to store several data items, for example,..." - I suggest to add the two examples explained in the paragraph so the user can contrast the two options - two maps or a map with record values. Remember, this is the first time they might have met maps, so they cannot visualize the options themselves.
Vaclav says: Section Evaluation Order - in the last but one paragraph you state “So, based on our dependency graph above, changing A1 will result in the reevaluation of B1 and B0 only.” I think A1 should also be re-evaluated - to update the cached value, or, in case A1 holds a formula, to re-compute it.
The section compares record instantiation to method invocation with positional parameters. A question arises, whether name parameters are also possible for record instantiation, just like for method invocation. I guess the same readability argument is valid for record instantiation.
The constNum block in the composite blocks has not been explained. It uses some unfamiliar syntax with a ":=" operator, which so far has not been defined.
Excercise05_01 (Show solution)
ext fun endDateGreaterThanStartDate(c: Course) : boolean {
if c.endDate.year - c.startDate.year > 0 then true
else if c.endDate.year - c.startDate.year < 0 then false
else if c.endDate.month - c.startDate.month > 0 then true
else if c.endDate.month - c.startDate.month > 0 then true
else if c.endDate.month - c.startDate.month < 0 then false
else if c.endDate.day - c.startDate.day >= 0 then true else false
}
the line "else if c.endDate.month - c.startDate.month > 0 then true" is duplicated.
Should month be replaced with day?
ext fun endDateGreaterThanStartDate(c: Course) : boolean {
if c.endDate.year - c.startDate.year > 0 then true
else if c.endDate.year - c.startDate.year < 0 then false
else if c.endDate.month - c.startDate.month > 0 then true
else if c.endDate.month - c.startDate.month < 0 then false
else if c.endDate.day - c.startDate.day >= 0 then true else false
}
The Sets section:
assert listHalved.toSet.toList.head(3) equals list(0, 1, 2)
Isn't this implementation specific? What guarantees that a list converted to a set and converted back to a list preserves the original order? How about:
listHalved.toSet.with(...).without(...).toList also preserve order?
assert listHalved.toList.at(3) equals 2 - here the "toList" conversion is not necessary, right?
fun vacationDays
Hier haben wir den perfekten Arbeitnehmer:
jünger als 18 und schon 30 Jahre Berufserfahrung ;-)
In der Tabelle stimmt der Wert links unten wohl nicht. In der EU dürfte auch der Wert darüber fragwürdig sein.
Wie geht man mit solchen Daten um? Eigentlich müßte die Funktion zurückliefern:
Lieber Anwender, Du hast definitiv falsche Werte erfaßt, dafür gibt es einen Fehler statt eines Wertes.
. The plusMinus block takes two numbers, and returs two results:
. The plusMinus block takes two numbers, and returNs two results:
A beginner will need more guidance to fully understand the example. The notYetBorn() function should be covered by tests. The explanation of the "precision" expression should help the reader locate in the code.
In the Map section:
fun getPopSize(cityName: string) = cityData.findFirst(it.name == cityName).pop
If I'm not mistaken this is the first occurrence of a function reaching out to the outer context for the value of "cityName". Maybe this deserves a mention.
Additionally, maybe a little note on the purpose of the findFirst() function could be included.
Some languages use the term Dictionary for Maps. This could be mentioned.
"the record instances defines specific rows" -> "the record instances define(s) specific rows"
the second example does not show any calculated values in the IDE, the C, D and E columns are grey and empty in my MPS project.
"As a software architect, we use a principle..." -> "As software architects, we use a principle..."
"you are now asked to "become a programmer" so you can use this DSL..." -> "you are now asked to "become a programmer" so THAT you can use this DSL..."
"As the tax expert we mentioned before, ..." -> "Us being tax experts, as we mentioned before, ...", or "As tax experts, ..."
"...that are the tax law for the particular period." -> "as specified by the tax law for the particular period."
Vaclav says: Section BasicOperators - == and != are probably new to many readers, they may be confusing = with ==. This perhaps deserves more explanation, especially if you later plan to add an assignment operator. I always wonder why languages re-invent an operator for equality when there is one known in math for centuries (=). Instead, it is the assignment operator that should be changed (e.g. := or <- or something else), in my opinion.
@farcasia : One more thing about chapter 4, and more precisely, about the figure with contexts and box. You have a square of a lighter grey colour that probably represents a return value for the box, but you never mentions why this lighter grey square is more special, and why there is an arrow pointing out
from the box for this square.
Also 'P' in the function name should be upper case
(as shWOn in the thisIs15 example)
(as shown in the thisIs15 example)
anonyNously,
anonymously
If a user is doing the test and writes
"number[3|3]"
because he learned that {0} is the default, the unittest failes. The user maybe astonished ;-)
The riskFactor() function declares its type as number[0|∞]{inf} but is calculated as number[-∞|∞]{inf}
"Two two results are"
Also, I find the fact that the plusMinus block takes two arguments and returns two results confusing for some potential readers. They may see correlation between the number of parameters and the number of results, which there obviously isn't. An example, which breaks that false perception could help.
While you're making an excellent point here, it is important to correct one thing. The "bind" operation does not do currying, but partial application. These two, although somewhat related, terms mean different things. - http://2ality.com/2011/09/currying-vs-part-eval.html
"that allows us to work us with " double "us"
type TrainType: string [where it.startsWith("ICE") || it.startsWith("RE")]
I guess this is the first time the ability to constraint types with code is mentioned. Perhaps more highlight to the feature could be used and its possible usages and limitations mentioned.
A curious question - can we have similar constraints on, let say, the "number" type? Perhaps to define a type for "all even numbers"? Why not?
Solution [X]show
template sheet NameAge
Please have a look in the inspector of cell $B1
the constraint shows
constraint: type: int
where it >= 0 && it <= 130
shouldn't it be it <= 30 ?
there’s no explanation about how to evaluate a test case in my IDE. So I cannot play with the tests myself. Maybe the intention that evaluates a test-case should be mentioned.
Many of the "src" links lead no non-existant nodes
"I the previous chapter we" should be "In the previous chapter we"
It should be mentioned that age() is an "extension" function and so it becomes available on Person. People might have forgotten the semantics of "extension functions".
assert olderThan35.head(4) equals all.head(4)
Although understandable for programmers, I thing this is a puzzling simplification for beginners, as it only works thanks to the coincidence that the last element is filtered out. I'd rather utilize some combination of "contains" or "containsAll".
From the design point of view I'm not sure a Citizen should have taxId. This certainly is questionable, but perhaps calling it something socialSecurityId or citizenId would be better. Kids are citizens and do not pay taxes, for example. Why do they need a taxId? This may cause some confusion for the reader, since they may thing that the taxId field has some relationship with TaxCitizen.
"we multiple the sum and the difference." -> multiply
Section "The problem of coverage" - I’d suggest to guide the reader to play with the two erroneous cases in the code snippet. How exactly should the test case warn them about a failure to divide by zero? What should they expect? It may not be clear to the reader what should happen when a value in B is set to 0, for example - nothing visually noticeable happens currently. It is not even a test case, so no green/red coloring is performed.
assert all.first.name equals "Smith"
assert all.at(1).first equals "Mary"
The "first" identifier is used twice for two completely different purposes, I suggest using a different name for the "first" field of the Person record.
"This is an important distinction:" - I have a mental association that colons precede some more formal definition or structured explanation or a list of options. Here it is neither - the following paragraphs go on explaining the composition and references. Thus I recommend using a full stop or an exclamation mark to finish the sentence. Possibly a title "Composition vs. referencing" could be used to separate the following paragraphs.
"will neer explicitly deal with " should be "will never explicitly deal with "
I did not figure out how to have something calculated in value inspectors, nor how to invoke computation trace. Detailed guidelines would be helpful.
Why not tell the readers that it is the Inspector window that can show them the constraints applied to the B0/B1 cells?
"these new kind of function" - use "this new kind of functions"
Also, perhaps a title "Passing code to functions" could be used to for the section.
chapter07_MathNotation: im frame midnight3_tests wird 3 mal midnight aufgerufen. Der dritte Aufruf geht aber (wie der erste) auf den frame:midnight1. Auch wenn's MPS anhand des AST kann die richtige Funktion aufzurufen (wenn man die richtige auswählt :zwinkern:, würde ich dem Leser zuliebe die Funktionen umbenennen. Frame midnight1: fun midnight1 / Frame midnight2: fun midnight2.
bmi: number[0|50]{1}
decision table:
bmi < 18 | bmi>=18 && bmi < 25 | bmi >= 25 && bmi < 30 | bmi > 30
Should the solver find the missing "bmi == 30" ? It is not mentioned as another bug...
"we now allow for a BMW less than 10 or" -> "we now allow for a "bmi" less than 10 or"
We can see the values which a particular expression (here: the call to add) evaluates to. If our expecation i
We can see the values which (?) a particular expression (here: the call to add) evaluates to. If our expecTation i
imho wouldn't that be easier to understand?
add(3,3)
=> add(3,2)
=> add(3,1)
=> add(3,0)
{ b == 0 so return a (=3)
{ return 3.plus1()} -> 4
{ return 4.plus1() } -> 5
{ return 5.plus1() } -> 6
In "Path Expressions" I suggest to add something like:
assert markusData.person.deref.first equals "Markus" to show that "deref" can be in the middle of a path.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.