<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def create_csr(key, dn, csrfilename=None, attributes=None):
 """ Generates a Certificate Signing Request for a given key. :param Crypto.PublicKey.RSA._RSAobj key: a key :param dn: a distinguished name as dictionary or string with key=value pairs separated by slashes like ``/CN=test.example.org/C=DE/O=Test organisation/`` :param str csrfilename: name of a file to write the CSR to :param tuple attributes: a tuple describing attributes to be included in the CSR :return: a certificate signing request """

    certreqInfo = rfc2314.CertificationRequestInfo()
    certreqInfo.setComponentByName('version', rfc2314.Version(0))
    certreqInfo.setComponentByName('subject', _build_dn(dn))
    certreqInfo.setComponentByName('subjectPublicKeyInfo',
                                   _build_subject_publickey_info(key))
    attrpos = certreqInfo.componentType.getPositionByName('attributes')
    attrtype = certreqInfo.componentType.getTypeByPosition(attrpos)
    certreqInfo.setComponentByName('attributes', _build_attributes(
        attributes, attrtype))

    certreq = rfc2314.CertificationRequest()
    certreq.setComponentByName('certificationRequestInfo', certreqInfo)

    sigAlgIdentifier = rfc2314.SignatureAlgorithmIdentifier()
    sigAlgIdentifier.setComponentByName(
        'algorithm', univ.ObjectIdentifier('1.2.840.113549.1.1.11'))
    certreq.setComponentByName(
        'signatureAlgorithm',
        sigAlgIdentifier)
    certreq.setComponentByName(
        'signature', _build_signature(key, certreqInfo))

    output = _der_to_pem(encoder.encode(certreq), 'CERTIFICATE REQUEST')

    if csrfilename:
        with open(csrfilename, 'w') as csrfile:
            csrfile.write(output)
    log.info("generated certification request:\n\n%s", output)
    return output