code: def backbone_bond_angles(self):
          
          bond_angles = dict(
              n_ca_c=[angle_between_vectors(r['N'] - r['CA'], r['C'] - r['CA'])
                      for r in self.get_monomers(ligands=False)],
              ca_c_o=[angle_between_vectors(r['CA'] - r['C'], r['O'] - r['C'])
                      for r in self.get_monomers(ligands=False)],
              ca_c_n=[angle_between_vectors(r1['CA'] - r1['C'], r2['N'] - r1['C'])
                      for r1, r2 in [(self[i], self[i + 1]) for i in range(len(self) - 1)]],
              c_n_ca=[angle_between_vectors(r1['C'] - r2['N'], r2['CA'] - r2['N'])
                      for r1, r2 in [(self[i], self[i + 1]) for i in range(len(self) - 1)]],
          )
          return bond_angles
docs: Dictionary containing backbone bond angles as lists of floats.
  
          Returns
          -------
          bond_angles : dict
              Keys are `n_ca_c`, `ca_c_o`, `ca_c_n` and `c_n_ca`, referring
              to the N-CA-C, CA-C=O, CA-C-N and C-N-CA angles respectively.
              Values are lists of floats : the bond angles in degrees.
              The lists of n_ca_c, ca_c_o are of length k for a `Polypeptide`
              containing k `Residues`. The list of ca_c_n and c_n_ca are of
              length k-1 for a `Polypeptide` containing k `Residues` (These
              angles are across the peptide bond, and are therefore formed
              between successive `Residue` pairs).