77 Matching Annotations
  1. Feb 2021
    1. The .zip file can not contain libraries written in C or C++. If your .zip file contains C-extension libraries, such as the Pillow (PIL) or numpy libraries, we recommend using the AWS SAM CLI to build a deployment package. For more information, see Using other AWS services to build a deployment package.

      No scientific applications possible with the .zip upload method.

  2. Jan 2021
    1. Note: You can only use variables in serverless.yml property values, not property keys. So you can't use variables to generate dynamic logical IDs in the custom resources section for example.

      WARNING

    2. Note: By supplying your resources at resources.Resources you may accidentally override resources as generated by the framework.

      WARNING: Should be aware that you are NOT prevented by default from overriding serverless create resources.

    3. Although Dead Letter Queues support both SNS topics and SQS queues, the onError config currently only supports SNS topic arns due to a race condition when using SQS queue arns and updating the IAM role.

      WARNING: No support using serverless and SQS backed DLQs

    1. Note: If your DNS does not allow you to add “@” as the hostname, please try leaving this field blank when you enter the ProtonMail verification information.

      If you're using AWS Route53, the console will silently accept the @ for the host, but WILL BE INVALID. You will need to follow this guidance to complete DNS configuration for ProtonMail.

    1. Please note that the AWS Go SDK, the underlying authentication handler used by the Terraform AWS Provider, does not support all AWS CLI features, such as Single Sign On (SSO) configuration or credentials.

      What exactly does this mean? When using the default Remote planning behaviour with terraform plan, I encounter the following error (despite my AWS creds being shared with this directive):

      Waiting for the plan to start...
      
      Terraform v0.14.4
      Configuring remote state backend...
      Initializing Terraform configuration...
      
      Error: No valid credential sources found for AWS Provider.
              Please see https://terraform.io/docs/providers/aws/index.html for more information on
              providing credentials for the AWS Provider
      
        on example.tf line 16, in provider "aws":
        16: provider "aws" {
      

      Switching to Local seems to fix the issue, but kind of defeats the purpose of using Terraform Cloud.

  3. Nov 2020
    1. The syntax .. will expand to as many values as it needs to be.

      i.e. is variadic

    2. Ignoring an Entire Value with _

      Also explains why prefixing a variable with the _ will allow it to be ignored when it is not used.

    1. Thinking about the relationships another way, a parent node should own its children: if a parent node is dropped, its child nodes should be dropped as well. However, a child should not own its parent: if we drop a child node, the parent should still exist. This is a case for weak references!

      A directed acyclic graphic relationship.

    1. Interior mutability is a design pattern in Rust that allows you to mutate data even when there are immutable references to that data; normally, this action is disallowed by the borrowing rules. To mutate data, the pattern uses unsafe code inside a data structure to bend Rust’s usual rules that govern mutation and borrowing.

      By definition interior mutability is an unsafe operation.

    1. Note that Rc<T> is only for use in single-threaded scenarios.

      An important caveat of using Rc<T>.

    1. Be careful when publishing a crate because a publish is permanent. The version can never be overwritten, and the code cannot be deleted.

      Care must be taken with published crates as they are permanent.

    2. Documentation comments use three slashes, ///, instead of two and support Markdown notation for formatting the text.

      Important to note that Markdown is supported within the documentation commments.

    1. let add_one_v4 = |x| x + 1 ;

      In IntelliJ, I see the following error when attempting to compile these statements:

      ^ consider giving this closure parameter a type

      This suggests that at least in rustc 1.47.0 (18bf6b4f0 2020-10-07), type inference of these closure datatypes must be explicit.

    1. Doing so improves performance without having to give up the flexibility of generics.

      Generics vs. dynamic typing (DT) where the convenience of DT is pushed back into the compiler. Neat!

    2. Using Trait Bounds to Conditionally Implement Methods

      This allows for the functional decomposition of interfaces which are orthogonal to one another without the use class inheritance ... kind of like interface mixins.

    3. The impl Trait syntax works for straightforward cases but is actually syntax sugar for a longer form, which is called a trait bound

      Suggests an explicit generic type constraint instead on a type being inferred.

    4. Note that it isn’t possible to call the default implementation from an overriding implementation of that same method.

      This suggests that the default implementation is shadowed.

    5. Sometimes it’s useful to have default behavior for some or all of the methods in a trait instead of requiring implementations for all methods on every type. Then, as we implement the trait on a particular type, we can keep or override each method’s default behavior.

      A Trait can behave like an abstract class which implements an interface (which are inherently abstract) to provide a default implementation.

      Perhaps injection by the compiler into the implementation by treating the default implementation as a partial?

    6. But we can’t implement external traits on external types. For example, we can’t implement the Display trait on Vec<T> within our aggregator crate, because Display and Vec<T> are defined in the standard library and aren’t local to our aggregator crate. This restriction is part of a property of programs called coherence, and more specifically the orphan rule, so named because the parent type is not present. This rule ensures that other people’s code can’t break your code and vice versa. Without the rule, two crates could implement the same trait for the same type, and Rust wouldn’t know which implementation to use.

      Coherence implies scoped Traits.

    7. After the method signature, instead of providing an implementation within curly brackets, we use a semicolon. Each type implementing this trait must provide its own custom behavior for the body of the method. The compiler will enforce that any type that has the Summary trait will have the method summarize defined with this signature exactly.

      Traits are abstract meaning that the type MUST provide the implementation of the Trait's function signatures.

    1. The main function is special, and there are restrictions on what its return type must be. One valid return type for main is (), and conveniently, another valid return type is Result<T, E>, as shown here:

      The main function is exceptional with regards to it's return types.

    1. The type annotation HashMap<_, _> is needed here because it’s possible to collect into many different data structures and Rust doesn’t know which you want unless you specify. For the parameters for the key and value types, however, we use underscores, and Rust can infer the types that the hash map contains based on the types of the data in the vectors.

      Rust uses monomorphization as opposed to type erasure (Java) or reification (C#).

    1. The Option type is used in many places because it encodes the very common scenario in which a value could be something or it could be nothing.

      The Option type is the implementation of the Null Object pattern.

    2. enums are useful and more appropriate than structs

      Enums are like typed struct constants that can be initialized with values.

    1. Each struct is allowed to have multiple impl blocks.

      Mulitple impl blocks seems reminiscent of C# partial classes.

    2. Another useful feature of impl blocks is that we’re allowed to define functions within impl blocks that don’t take self as a parameter. These are called associated functions because they’re associated with the struct. They’re still functions, not methods, because they don’t have an instance of the struct to work with. You’ve already used the String::from associated function.

      Associated Functions seem to behave like class methods (not associated with an object instance).

    1. Derived Traits

      Derived Traits seem to function like Ruby mixins. No need to specify overridden implementations of an abstract interface.

    1. A struct, or structure, is a custom data type that lets you name and package together multiple related values that make up a meaningful group. If you’re familiar with an object-oriented language, a struct is like an object’s data attributes.

      A Rust struct is similar to an OOP class.

    1. The benefit of having this restriction is that Rust can prevent data races at compile time. A data race is similar to a race condition and happens when these three behaviors occur: Two or more pointers access the same data at the same time. At least one of the pointers is being used to write to the data. There’s no mechanism being used to synchronize access to the data.

      Rust's enforcement of single mutable borrows using pointers/references prevents data race conditions.

    2. First, we had to change s to be mut. Then we had to create a mutable reference with &mut s and accept a mutable reference with some_string: &mut String.

      Again, Rust makes mutability (even with pointers) explicit.

    1. To ensure memory safety, there’s one more detail to what happens in this situation in Rust. Instead of trying to copy the allocated memory, Rust considers s1 to no longer be valid and, therefore, Rust doesn’t need to free anything when s1 goes out of scope.

      This behaviour sounds like shadowing except with variables and their pointer values.

    2. This kind of string can be mutated

      Emphasis on the can be mutated which suggests that explicit variable annotation (nut) is still required for a heap allocated complex type.

    1. (1..4)

      This presumably is a range tuple with shorthand specification. Tuples are iterable.

    2. As a more concise alternative, you can use a for loop and execute some code for each item in a collection.

      Rust's for expression works on iterable collections like arrays.

    3. To do this, you can add the value you want returned after the break expression you use to stop the loop; that value will be returned out of the loop so you can use it

      You can break and provide an expression. In addition, loop is an expression (can be used on the left of the assignment operator).

    4. This means the values that have the potential to be results from each arm of the if must be the same type; in Listing 3-2, the results of both the if arm and the else arm were i32 integers. If the types are mismatched, as in the following example, we’ll get an error

      Conditional expressions MUST return the same type.

    5. That’s because Rust only executes the block for the first true condition, and once it finds one, it doesn’t even check the rest.

      Rust short-circuits any additional conditions like C.

    6. the condition in this code must be a bool. If the condition isn’t a bool, we’ll get an error.

      Rust if/else expressions must be a bool.

    1. x + 1;

      A statement implicitly returns a tuple.

    2. Expressions do not include ending semicolons. If you add a semicolon to the end of an expression, you turn it into a statement, which will then not return a value. Keep this in mind as you explore function return values and expressions next.

      Expressions DO NOT end with semicolons. This is a very important (and somewhat subtle) distinction to make when reading Rust code.

    3. The let y = 6 statement does not return a value, so there isn’t anything for x to bind to. This is different from what happens in other languages, such as C and Ruby, where the assignment returns the value of the assignment. In those languages, you can write x = y = 6 and have both x and y have the value 6; that is not the case in Rust.

      Unlike C/Ruby, statements DO NOT return a value. There is a clear distinction between 1statements and expressions in Rust.

    4. In function signatures, you must declare the type of each parameter. This is a deliberate decision in Rust’s design: requiring type annotations in function definitions means the compiler almost never needs you to use them elsewhere in the code to figure out what you mean.

      Explicit types in function signatures are part of the Rust design.

    1. The compilation didn’t produce any errors, but the program resulted in a runtime error and didn’t exit successfully.

      Index out of bounds errors are runtime errors.

    2. Rust’s char type is four bytes in size and represents a Unicode Scalar Value, which means it can represent a lot more than just ASCII.

      The char type represents Unicode characters, not just ASCII.

    3. Let’s say you have a variable of type u8 that can hold values between 0 and 255. If you try to change the variable to a value outside of that range, such as 256, integer overflow will occur. Rust has some interesting rules involving this behavior. When you’re compiling in debug mode, Rust includes checks for integer overflow that cause your program to panic at runtime if this behavior occurs. Rust uses the term panicking when a program exits with an error; we’ll discuss panics in more depth in the “Unrecoverable Errors with panic!” section in Chapter 9. When you’re compiling in release mode with the --release flag, Rust does not include checks for integer overflow that cause panics. Instead, if overflow occurs, Rust performs two’s complement wrapping. In short, values greater than the maximum value the type can hold “wrap around” to the minimum of the values the type can hold. In the case of a u8, 256 becomes 0, 257 becomes 1, and so on. The program won’t panic, but the variable will have a value that probably isn’t what you were expecting it to have. Relying on integer overflow’s wrapping behavior is considered an error. If you want to wrap explicitly, you can use the standard library type Wrapping.

      Integer Overflow behaviour depends on whether the application is being compiled with debug vs. release.

    1. However, if we try to use mut for this, as shown here, we’ll get a compile-time error:

      Can mutable variables be shadowed? This section suggests that they cannot be (or maybe it is limited to variables of the same type).

    2. First, you aren’t allowed to use mut with constants. Constants aren’t just immutable by default—they’re always immutable. You declare constants using the const keyword instead of the let keyword, and the type of the value must be annotated. We’re about to cover types and type annotations in the next section, “Data Types,” so don’t worry about the details right now. Just know that you must always annotate the type. Constants can be declared in any scope, including the global scope, which makes them useful for values that many parts of code need to know about. The last difference is that constants may be set only to a constant expression, not the result of a function call or any other value that could only be computed at runtime.

      Constants cannot be made mutable with mut. In addition, they must be set to a constant expression (not a value can can only be resolved at runtime).

    1. The colon (:) after guess tells Rust we’ll annotate the variable’s type

      You can provide type hints with variable annotations instead of relying on type inference.

    2. Rust allows us to shadow the previous value of guess with a new one. This feature is often used in situations in which you want to convert a value from one type to another type. Shadowing lets us reuse the guess variable name rather than forcing us to create two unique variables, such as guess_str and guess for example.

      Shadowing must implicitly rely on variable declaration ordering? It seems that shadowing does not inherit mutability semantics from previous variable declarations and defines the shadow variable within a more focused scope. How do you rollback a variable that's been shadowed?

    3. The Rng trait defines methods that random number generators implement, and this trait must be in scope for us to use those methods.

      The Rust equivalent of interfaces is traits.

    4. When you do want to update a crate, Cargo provides another command, update, which will ignore the Cargo.lock file and figure out all the latest versions that fit your specifications in Cargo.toml.

      The cargo update only works with release semver updates. Major/minor semver updates require updating the Cargo.toml file manually to the new version.

    5. Cargo has a mechanism that ensures you can rebuild the same artifact every time you or anyone else builds your code: Cargo will use only the versions of the dependencies you specified until you indicate otherwise.

      By default, dependency versions are pinned. This ensures that builds are reproducible.

    6. Rust warns that you haven’t used the Result value returned from read_line, indicating that the program hasn’t handled a possible error.

      The compiler enforces exception handling; unhandled exceptions are identified with compiler warnings.

    7. For now, all you need to know is that like variables, references are immutable by default.

      The default policy of immutability by default extends to references. This greatly simplifies managing program state during concurrency.

    8. let mut guess = String::new();

      Mutability must be declared explicitly.

    9. associated function of the String type. An associated function is implemented on a type, in this case String, rather than on a particular instance of a String. Some languages call this a static method.

      The Rust terminology for static functions is associated functions

    1. Does your API cross organizational and national boundaries the same way that HTTP needs to? Then building a RESTful API with a predictable, uniform interface might be the right approach. If not, it’s good to remember that Fielding favored having form follow function. Maybe something like GraphQL or even just JSON-RPC would be a better fit for what you are trying to accomplish.

      Architectural considerations of how the API is to be accessed and distributed (and also the consumers).

  4. Oct 2020
    1. The Security Rule requires the risk analysis to be documented but does not require a specific format. (See 45 C.F.R. § 164.316(b)(1).) The risk analysis documentation is a direct input to the risk management process.

      Documentation of the Risk Analysis is REQUIRED.

    2. Organizations must identify and document reasonably anticipated threats to e-PHI. (See 45 C.F.R. §§ 164.306(a)(2) and 164.316(b)(1)(ii).) Organizations may identify different threats that are unique to the circumstances of their environment. Organizations must also identify and document vulnerabilities which, if triggered or exploited by a threat, would create a risk of inappropriate access to or disclosure of e-PHI. (See 45 C.F.R. §§ 164.308(a)(1)(ii)(A) and 164.316(b)(1)(ii).)

      By definition, Security Rule Risk Analysis is a Threat Surface Model for the various ways in which electronic protected health information (ePHI) can be accessed/disclosed in an unauthorized manner or compromised/tampered with.

    3. The scope of risk analysis that the Security Rule encompasses includes the potential risks and vulnerabilities to the confidentiality, availability and integrity of all e-PHI that an organization creates, receives, maintains, or transmits. (45 C.F.R. § 164.306(a).) This includes e-PHI in all forms of electronic media, such as hard drives, floppy disks, CDs, DVDs, smart cards or other storage devices, personal digital assistants, transmission media, or portable electronic media. Electronic media includes a single workstation as well as complex networks connected between multiple locations. Thus, an organization’s risk analysis should take into account all of its e-PHI, regardless of the particular electronic medium in which it is created, received, maintained or transmitted or the source or location of its e-PHI.

      The HIPAA Security Rule's scope of Risk Analysis.

    4. An adapted definition of risk, from NIST SP 800-30, is: “The net mission impact considering (1) the probability that a particular [threat] will exercise (accidentally trigger or intentionally exploit) a particular [vulnerability] and (2) the resulting impact if this should occur . . . . [R]isks arise from legal liability or mission loss due to— 1. Unauthorized (malicious or accidental) disclosure, modification, or destruction of information 2. Unintentional errors and omissions 3. IT disruptions due to natural or man- made disasters 4. Failure to exercise due care and diligence in the implementation and operation of the IT system.”

      The NIST definition of Risk.

    5. An adapted definition of threat, from NIST SP 800-30, is “[t]he potential for a person or thing to exercise (accidentally trigger or intentionally exploit) a specific vulnerability.”

      The NIST definition of a Threat.

    6. Vulnerability is defined in NIST Special Publication (SP) 800-30 as “[a] flaw or weakness in system security procedures, design, implementation, or internal controls that could be exercised (accidentally triggered or intentionally exploited) and result in a security breach or a violation of the system’s security policy.”

      The NIST definition of a Vulnerability.

    7. Decide whether and how to use encryption. (45 C.F.R. §§ 164.312(a)(2)(iv) and (e)(2)(ii).) • Address what data must be authenticated in particular situations to protect data integrity. (45 C.F.R. § 164.312(c)(2).) • Determine the appropriate manner of protecting health information transmissions. (45 C.F.R. § 164.312(e)(1).)

      Encryption/data integrity/secure authentication specifications as defined by NIST.

    8. An addressable implementation specification is not optional; rather, if an organization determines that the implementation specification is not reasonable and appropriate, the organization must document why it is not reasonable and appropriate and adopt an equivalent measure if it is reasonable and appropriate to do so.

      Specifies that "Addressabhle" implementations must have documented exclusions and whether equivalent measures are adopted.

    9. Section 164.308(a)(1)(ii)(A) states: RISK ANALYSIS (Required). Conduct an accurate and thorough assessment of the potential risks and vulnerabilities to the confidentiality, integrity, and availability of electronic protected health information held by the [organization].

      HIPAA section which specifically mentions that Risk Analysis is REQUIRED.

    10. The Security Rule requires entities to evaluate risks and vulnerabilities in their environments and to implement reasonable and appropriate security measures to protect against reasonably anticipated threats or hazards to the security or integrity of e-PHI. Risk analysis is the first step in that process.

      Note the inclusion of "reasonably anticipated threats or hazards".

    11. Conducting a risk analysis is the first step in identifying and implementing safeguards that comply with and carry out the standards and implementation specifications in the Security Rule.  Therefore, a risk analysis is foundational, and must be understood in detail before OCR can issue meaningful guidance that specifically addresses safeguards and technologies that will best protect electronic health information

      All HIPAA compliance organizations should have completed a REQUIRED risk analysis.

    1. The “Omnibus HIPAA Final Rule”)

      This is the most current version of the HIPAA Rules with the attendant clarifications. In practice, this should be used to determine applicability/conformance to HIPAA by organizations.

    1. Policies and Procedures and Documentation Requirements A covered entity must adopt reasonable and appropriate policies and procedures to comply with the provisions of the Security Rule. A covered entity must maintain, until six years after the later of the date of their creation or last effective date, written security policies and procedures and written records of required actions, activities or assessments.30 Updates. A covered entity must periodically review and update its documentation in response to environmental or organizational changes that affect the security of electronic protected health information (e-PHI).31

      There is a burden of responsibility regarding documentation for compliance/implementation details for covered entities with regards to the safeguards implemented.

    2. Required and Addressable Implementation Specifications Covered entities are required to comply with every Security Rule "Standard." However, the Security Rule categorizes certain implementation specifications within those standards as "addressable," while others are "required." The "required" implementation specifications must be implemented. The "addressable" designation does not mean that an implementation specification is optional. However, it permits covered entities to determine whether the addressable implementation specification is reasonable and appropriate for that covered entity. If it is not, the Security Rule allows the covered entity to adopt an alternative measure that achieves the purpose of the standard, if the alternative measure is reasonable and appropriate.28

      Definition of "Required" vs. "Addressable" Implementation specifications.

    3. The Administrative Safeguards provisions in the Security Rule require covered entities to perform risk analysis as part of their security management processes. The risk analysis and management provisions of the Security Rule are addressed separately here because, by helping to determine which security measures are reasonable and appropriate for a particular covered entity, risk analysis affects the implementation of all of the safeguards contained in the Security Rule.  A risk analysis process includes, but is not limited to, the following activities: Evaluate the likelihood and impact of potential risks to e-PHI;8 Implement appropriate security measures to address the risks identified in the risk analysis;9 Document the chosen security measures and, where required, the rationale for adopting those measures;10 and Maintain continuous, reasonable, and appropriate security protections.11  Risk analysis should be an ongoing process, in which a covered entity regularly reviews its records to track access to e-PHI and detect security incidents,12 periodically evaluates the effectiveness of security measures put in place,13 and regularly reevaluates potential risks to e-PHI.14

      A Risk Analysis and Risk Management practice is REQUIRED.

      The following sections outline the safeguards the MUST be implemented. Failing to do so exposes the covered entity or business associate to LIABILITY.

    4. The Security Rule applies to health plans, health care clearinghouses, and to any health care provider who transmits health information in electronic form in connection with a transaction for which the Secretary of HHS has adopted standards under HIPAA (the “covered entities”) and to their business associates.

      Scope of who must comply by the HIPAA Security Rules.

    5. The Health Insurance Portability and Accountability Act of 1996 (HIPAA) required the Secretary of the U.S. Department of Health and Human Services (HHS) to develop regulations protecting the privacy and security of certain health information.1 To fulfill this requirement, HHS published what are commonly known as the HIPAA Privacy Rule and the HIPAA Security Rule. The Privacy Rule, or Standards for Privacy of Individually Identifiable Health Information, establishes national standards for the protection of certain health information. The Security Standards for the Protection of Electronic Protected Health Information (the Security Rule) establish a national set of security standards for protecting certain health information that is held or transferred in electronic form. The Security Rule operationalizes the protections contained in the Privacy Rule by addressing the technical and non-technical safeguards that organizations called “covered entities” must put in place to secure individuals’ “electronic protected health information” (e-PHI). Within HHS, the Office for Civil Rights (OCR) has responsibility for enforcing the Privacy and Security Rules with voluntary compliance activities and civil money penalties.

      Definition of the Privacy Rule and the operationalized Security Rule guidance for HIPAA.

    1. The doctest module provides a tool for scanning a module and validating tests embedded in a program’s docstrings. Test construction is as simple as cutting-and-pasting a typical call along with its results into the docstring. This improves the documentation by providing the user with an example and it allows the doctest module to make sure the code remains true to the documentation:

      This idea of using documentation as self-verifying code/tests looks promising for other languages.

    1. In fact, nothing in Python makes it possible to enforce data hiding — it is all based upon convention

      WTF!