πŸ•ΆοΈ
VICEINTELPRO
GitHub: HorrorClause
  • In Tenebris Videmus
  • 🚩CTFs
    • πŸ’ΎHack the Box
      • 🏫Academy
        • Command Injection Assessment
        • XSS Assessment
        • Web Attacks Assessment
    • Try Hack Me
      • In Progress
  • πŸ“–Documents
  • πŸ‘¨β€πŸ«HOW-TOs
    • Obisidian How-To
    • Setup Mandiant FLARE VM
  • πŸ“‘Security Fundamentals
    • Security Controls
      • Physical Security
      • Endpoint Security
      • Email Security
      • Network Security
      • AAA Controls
    • Networking 101
      • OSI Model
      • Network Fundamentals
      • Network Devices
      • Network Tools
      • Protocols and Ports
    • πŸ‘¨β€πŸ’ΌManagement Principles
      • Risk
      • Policies and Procedures
      • Compliance and Frameworks
      • Change and Patch Management
  • πŸ›‘οΈSecurity Concepts
    • ⚠️Risk Assessment Models
      • DREAD Risk Assessment Model
      • STRIDE Threat Model
      • Common Vulnerability Scoring System (CVSS)
    • Pentesting
      • Common Terms
      • AV Identification-Evasion
      • Introduction to Payloads
      • Automating Payloads & Delivery with Metasploit
      • Shells Jack Us In, Payloads Deliver Us Shells
      • Web Shells
      • Pentesting Overview
      • Penetration Testing Process
    • πŸ›Vulnerability Assessment
      • Common Vulnerabilities and Exposures (CVE)
      • Common Vulnerability Scoring System (CVSS)
      • Assessment Standards
      • Vulnerability Assessment
      • Vulnerability Scanning
      • Reporting
      • 🎯Nessus
        • Getting Started with Nessus
        • Nessus Scan
        • Working with Nessus Scan Output
        • Advanced Settings
        • Scanning Issues
      • 🦴OpenVAS (Greenbone)
        • Getting Started with OpenVAS
        • OpenVAS
        • Exporting Results
    • Passwords
      • Password Managers
      • Password Policies
      • Password Security Fundamentals
    • Frameworks
    • GRC
    • Logon Types
    • What is Dev-Null ?
  • βš”οΈOffensive Security
    • OSINT
      • OSINT - Websites
      • Google Dorks
    • πŸ”«Attacking Common Services
      • The Concept of Attacks
      • Interacting with Common Services
      • Finding Sensitive Information
      • Attacking DNS
      • Attacking Email Services
      • Attacking FTP
      • Attacking RDP
      • Attacking SMB
      • Attacking SQL Databases
      • Cheat Sheet - Attacking Common Services
      • Service Misconfigurations
    • πŸ”ͺAttacking Web Apps with Ffuf
      • Web Fuzzing
      • Directory Fuzzing
      • Page Fuzzing
      • Recursive Fuzzing
      • DNS Records
      • Sub-domain Fuzzing
      • Vhost Fuzzing
      • Filtering Results
      • Parameter Fuzzing - GET
      • Parameter Fuzzing - POST
      • Value Fuzzing
    • ☁️Cloud
      • AWS
        • AWS S3 Buckets
    • πŸ’‰Command Injection
      • Command Injection Cheat Sheet
      • Intro to Command Injections
      • Detection
      • Injecting Commands
      • Other Injection Operators
      • Identifying Filters
      • Bypassing Space Filters
      • Bypassing Other Blacklisted Characters
      • Bypassing Blacklisted Commands
      • Advanced Command Obfuscation
      • Evasion Tools
      • Command Injection Prevention
    • Containers
      • Docker
    • ❌Cross-Site Scripting (XSS)
      • Introduction to XSS
      • Stored XSS
      • Reflected XSS
      • DOM XSS
      • XSS Discovery
      • Defacing
      • Phishing
      • Session Hijacking
      • XSS Prevention
    • Directory Busting
      • DirB
      • DirBuster
      • Ffuf
      • Gobuster
    • πŸ…°οΈDNS
      • DNSRecon
      • Fierce
    • File Inclusion
      • Local File Inclusion Cheatsheet
      • Intro to File Inclusion
      • Local File Inclusion (LFI)
      • Basic Bypass
      • PHP Filters
      • PHP Wrappers
      • Remote File Inclusion (RFI)
      • LFI and File Uploads
      • Log Poisoning
      • Automated Scanning
      • File Inclusion Prevention
    • File Transfers
      • Transferring Files
      • File Transfer - Quick Commands
      • Living off the Land
      • Windows File Transfer Methods
      • Linux File Transfer Methods
      • Catching Files over HTTP(S)
      • Transferring Files with Code
      • Miscellaneous File Transfer Methods
      • Protected File Transfers
      • Mounting Encrypted VHD Drives
      • Mounting VHD in Kali
      • File Transfer Detection
    • File Upload Attacks
      • File Upload Cheatsheet
      • Absent Validation
      • Upload Exploitation
      • Client-Side Validation
      • Blacklist Filters
      • Whitelist Filters
      • Type Filters
      • Limited File Uploads
      • Other Upload Attacks
      • Preventing File Upload Vulnerabilities
    • πŸ‘£Footprinting
      • Linux Remote Management Protocols
      • Windows Remote Management Protocols
      • Enumeration
        • Enumeration Methodology
        • πŸ–₯️Host Based
          • Quick Commands
          • DNS
          • FTP
          • IMAP-POP3
          • IPMI
          • MSSQL
          • MySQL
          • NFS
          • Oracle TNS
          • SMB
  • Powershell
    • Powershell CheatSheet
  • Python
    • Map
    • Anonymous Functions
    • Recursion
      • ZipMap
      • Nested Sum
      • Recursion on a Tree
      • Count Nested Levels
      • Longest Word
    • Function Transformations
      • More Transformations
      • Why Transform?
    • Closures
    • Currying
    • Decorators
    • Sum Types
    • Enums
    • Match
    • Regex
  • Kusto (KQL)
    • SQL and KQL Comparison
    • Using the Where and Sort Operators
    • KQL Queries
  • HTML
  • Insecure File Uploads
Powered by GitBook
On this page
  • Assignment
  • Solution
  • Why Curry?
  1. Python

Currying

PreviousClosuresNextDecorators

Last updated 2 months ago

Function is a specific kind of function transformation where we translate a single function that accepts multiple arguments into multiple functions that each accept a single argument.

This is a "normal" 3-argument function:

box_volume(3, 4, 5)

This is a "curried" series of functions that does the same thing:

box_volume(3)(4)(5)

Here's another example that includes the implementations:

def sum(a, b):
  return a + b

print(sum(1, 2))
# prints 3

And the same thing curried:

def sum(a):
  def inner_sum(b):
    return a + b
  return inner_sum

print(sum(1)(2))
# prints 3

The sum function only takes a single input, a. It returns a new function that takes a single input, b. This new function when called with a value for b will return the sum of a and b. We'll talk later about why this is useful.

Assignment

In Doc2Doc, depending on the type of text file we're working with, we sometimes need to transform the font size of the text when it comes time to render it on the screen.

Fix the converted_font_size function. We are using a 3rd party code library that expects our function to be a curried series of functions that each take a single argument.

  • converted_font_size should just take a single argument, font_size and return a function that takes a single argument, doc_type. That function should return the font_size multiplied by the appropriate value for the given doc_type.

def converted_font_size(font_size, doc_type):
    if doc_type == "txt":
        return font_size
    if doc_type == "md":
        return font_size * 2
    if doc_type == "docx":
        return font_size * 3
    raise ValueError("invalid doc type")

Solution

def converted_font_size(font_size):
    def doc(doc_type):
        if doc_type == "txt":
            return font_size
        if doc_type == "md":
            return font_size * 2
        if doc_type == "docx":
            return font_size * 3
        raise ValueError("invalid doc type")
    return doc

Your solution works because it implements function currying, which means it transforms a function that conceptually takes two arguments into a function that takes one argument and returns another function to accept the second argument. Here’s a breakdown:

  • Curried Function Structure:

    • converted_font_size(font_size) takes a single argument (font_size) and returns a new function.

    • The inner function doc(doc_type) takes a single argument (doc_type).

  • Processing the Input:

    • When you call converted_font_size(12), for example, it returns the doc function with font_size set to 12.

    • Then, calling doc("md") (i.e., converted_font_size(12)("md")) checks the doc_type:

      • If doc_type is "txt", it returns font_size (12).

      • If "md", it returns font_size * 2 (24).

      • If "docx", it returns font_size * 3 (36).

    • If the doc_type is invalid, it raises a ValueError.

  • Why It Meets the Assignment:

    • It adheres to the requirement that each function in the chain accepts a single argument.

    • The design lets you specify the font size first and then, depending on the document type, adjust that size with a multiplier.

This approach is useful in scenarios where you need to configure part of a process (in this case, setting a base font size) and then apply different transformations based on additional input (the document type).

Why Curry?

It's fairly obvious that:

def sum(a, b):
  return a + b

is simpler than:

def sum(a):
  def inner_sum(b):
    return a + b
  return inner_sum

So why would we ever want to do the more complicated thing? Well, currying is often used to change a function's signature to make it conform to a specific shape. For example:

def colorize(converter, doc):
  # ...
  converter(doc)
  # ...

The colorize function accepts a function called converter as input, and at some point during its execution, it calls converter with a single argument. That means that it expects converter to accept exactly one argument. So, if I have a conversion function like this:

def markdown_to_html(doc, asterisk_style):
  # ...

I can't pass markdown_to_html to colorize because markdown_to_html wants two arguments. To solve this problem, I can curry markdown_to_html into a function that takes a single argument:

def markdown_to_html(asterisk_style):
  def asterisk_md_to_html(doc):
    # do stuff with doc and asterisk_style...

  return asterisk_md_to_html

markdown_to_html_italic = markdown_to_html('italic')
colorize(markdown_to_html_italic, doc)
currying