Glider gitbook
GliderRVSS Calculator Ask the Community
  • Glider introduction
  • πŸ„Writing Queries
  • ✍️Glider and Declarative Query Writing
  • πŸŽ“Glider: The Basics
    • Intro to Python
      • Basic Python
      • Advanced Python
    • Intro to Glider
    • Instructions
      • Learning Instructions
      • Exercises
    • Functions
      • Learning Functions
      • Exercises
    • Contracts
      • Learning Contracts
      • Exercises
    • Bonus Challenges
  • πŸ“™API
    • πŸ“ŒMain concepts
    • Iterables
      • APISet
      • APIList
    • Argument
      • Argument.backward_df()
      • Argument.data
      • Argument.df_reaches_from_functions_arguments()
      • Argument.df_reaching_functions_arguments()
      • Argument.forward_df()
      • Argument.get_parent()
      • Argument.index
      • Argument.memory_type
      • Argument.name
      • Argument.procedure_graph_node
      • Argument.source_code()
      • Argument.type
    • Arguments
      • Arguments.list()
      • Arguments.with_memory_type()
      • Arguments.with_name()
      • Arguments.with_type()
      • Arguments.with_type_convertible()
      • Convertor
        • Convertor.add()
        • Convertor.can_convert()
        • Convertor.set_conversions()
    • Contract
      • Contract.address()
      • Contract.base_contracts()
      • Contract.chain_id()
      • Contract.constructor()
      • Contract.derived_contracts()
      • Contract.enums()
      • Contract.errors()
      • Contract.events()
      • Contract.functions()
      • Contract.is_lib()
      • Contract.is_main()
      • Contract.modifiers()
      • Contract.name
      • Contract.parent_contracts()
      • Contract.pragmas()
      • Contract.source_code()
      • Contract.state_variables()
      • Contract.structs()
    • Contracts
      • Contracts.exec()
      • Contracts.functions()
      • Contracts.interface_contracts()
      • Contracts.mains()
      • Contracts.with_name_prefix()
      • Contracts.with_name_regex()
      • Contracts.with_name_suffix()
      • Contracts.non_interface_contracts()
      • Contracts.with_all_function_names()
      • Contracts.with_compiler_range()
      • Contracts.with_compiler_range_not()
      • Contracts.with_error_name()
      • Contracts.with_error_prefix()
      • Contracts.with_error_regex()
      • Contracts.with_error_signature()
      • Contracts.with_error_suffix()
      • Contracts.with_event_name()
      • Contracts.with_event_prefix()
      • Contracts.with_event_regex()
      • Contracts.with_event_signature()
      • Contracts.with_event_suffix()
      • Contracts.with_function_name()
      • Contracts.with_function_name_not()
      • Contracts.with_one_of_the_function_names()
      • Contracts.with_name()
      • Contracts.with_name_not()
      • Contracts.with_struct_field_name()
      • Contracts.with_struct_field_type()
      • Contracts.with_struct_fields_count()
      • Contracts.with_struct_name()
    • Enum
      • Enum.data
      • Enum.max
      • Enum.min
      • Enum.name
      • Enum.values
    • Enums
      • Enums.exec()
    • Error
      • Error.args
      • Error.name
      • Error.signature
    • Errors
      • Errors.exec()
    • Event
      • Event.arg_list()
      • Event.name
      • Event.signature
    • Function
      • Function.caller_functions()
      • Function.extended_caller_functions()
      • Function.has_modifiers()
      • Function.is_constructor()
      • Function.is_external()
      • Function.is_global()
      • Function.is_internal()
      • Function.is_payable()
      • Function.is_private()
      • Function.is_public()
      • Function.is_pure()
      • Function.is_view()
      • Function.modifiers()
      • Function.properties()
      • Function.return_instructions()
      • Function.return_tuple()
    • Functions
      • Functions.constructors()
      • Functions.exec()
      • Functions.extended_caller_functions()
      • Functions.extended_caller_modifiers()
      • Functions.with_all_properties()
      • Functions.with_declarer_contract_name()
      • Functions.with_modifier_name()
      • Functions.without_modifier_name()
      • Functions.with_modifier_name_regex()
      • Functions.with_modifier_signature()
      • Functions.with_one_of_the_modifier_names()
      • Functions.without_modifier_names()
      • Functions.with_one_of_the_modifier_name_regexes()
      • Functions.with_one_property()
      • Functions.without_properties()
      • Functions.with_all_modifier_names()
      • Functions.without_modifiers()
      • Functions.with_declarer_contract_name()
    • Modifier
      • Modifier.functions()
      • Modifier.placer_instructions()
      • Modifier.properties()
    • Modifiers
      • Modifiers.exec()
      • Modifiers.placer_instructions()
    • Callable
      • Callable.address()
      • Callable.arguments()
      • Callable.break_instructions()
      • Callable.callee_functions()
      • Callable.callee_values()
      • Callable.calls_instructions()
      • Callable.catch_instructions()
      • Callable.continue_instructions()
      • Callable.end_asm_instructions()
      • Callable.end_if_instructions()
      • Callable.end_loop_instructions()
      • Callable.entry_point_instructions()
      • Callable.expression_instructions()
      • Callable.extended_callee_functions()
      • Callable.extended_instructions()
      • Callable.get_contract()
      • Callable.get_reachable_instructions()
      • Callable.hashed_signature()
      • Callable.if_instructions()
      • Callable.if_loop_instructions()
      • Callable.instructions()
      • Callable.local_variables()
      • Callable.name
      • Callable.new_contract_instructions()
      • Callable.signature()
      • Callable.source_code()
      • Callable.start_asm_instructions()
      • Callable.start_loop_instructions()
      • Callable.throw_instructions()
      • Callable.try_instructions()
    • Callables
      • Callables.contracts()
      • Callables.extended_callee_functions()
      • Callables.instructions()
      • Callables.with_name_prefix()
      • Callables.with_name_prefixes()
      • Callables.with_name_regex()
      • Callables.with_name_regexes()
      • Callables.with_name_suffix()
      • Callables.with_name_suffixes()
      • Callables.with_arg_count()
      • Callables.with_arg_memory_type()
      • Callables.with_arg_name()
      • Callables.with_arg_type()
      • Callables.with_arg_types()
      • Callables.with_hashed_signature()
      • Callables.with_name()
      • Callables.without_name()
      • Callables.with_one_of_the_names()
      • Callables.without_names()
      • Callables.with_signature()
      • Callables.with_signatures()
      • Callables.with_callee_names()
      • Callables.with_declarer_contract_name()
      • MethodProp
        • MethodProp.EXTERNAL
        • MethodProp.HAS_ARGS
        • MethodProp.HAS_CALLEES
        • MethodProp.HAS_ERRORS
        • MethodProp.HAS_MODIFIERS
        • MethodProp.HAS_STATE_VARIABLES_READ
        • MethodProp.HAS_STATE_VARIABLES_WRITTEN
        • MethodProp.INTERNAL
        • MethodProp.IS_CONSTRUCTOR
        • MethodProp.IS_GLOBAL
        • MethodProp.IS_PAYABLE
        • MethodProp.IS_PURE
        • MethodProp.IS_VIEW
        • MethodProp.PRIVATE
        • MethodProp.PUBLIC
    • Instruction
      • Instruction.backward_df()
      • Instruction.callee_names()
      • Instruction.extended_previous_instructions()
      • Instruction.forward_df()
      • Instruction.get_callees()
      • Instruction.get_component()
      • Instruction.get_components()
      • Instruction.get_dest()
      • Instruction.get_parent()
      • Instruction.get_value()
      • Instruction.is_break()
      • Instruction.is_call()
      • Instruction.is_catch()
      • Instruction.is_cmp()
      • Instruction.is_continue()
      • Instruction.is_end_assembly()
      • Instruction.is_end_if()
      • Instruction.is_end_loop()
      • Instruction.is_entry_point()
      • Instruction.is_expression()
      • Instruction.is_from_assembly()
      • Instruction.is_if()
      • Instruction.is_if_loop()
      • Instruction.is_new_contract()
      • Instruction.is_placer()
      • Instruction.is_return()
      • Instruction.is_start_assembly()
      • Instruction.is_start_loop()
      • Instruction.is_storage_read()
      • Instruction.is_storage_write()
      • Instruction.is_throw()
      • Instruction.is_try()
      • Instruction.next_block()
      • Instruction.next_instruction()
      • Instruction.next_instructions()
      • Instruction.extended_next_instructions()
      • Instruction.previous_instruction()
      • Instruction.previous_instructions()
      • Instruction.extended_previous_instructions()
      • Instruction.solidity_callee_names()
      • Instruction.source_code()
      • BreakInstruction
      • CatchInstruction
        • CatchInstruction.get_block_instructions()
      • ContinueInstruction
      • EndAssemblyInstruction
      • EndIfInstruction
      • EndLoopInstruction
      • EntryPointInstruction
      • ExpressionInstruction
      • IfInstruction
        • IfInstruction.first_false_instruction()
        • IfInstruction.first_true_instruction()
        • IfInstruction.get_condition()
        • Condition
          • Condition.is_eq()
          • Condition.is_geq()
          • Condition.is_gr()
          • Condition.is_le()
          • Condition.is_leq()
      • IfLoopInstruction
      • NewVariableInstruction
      • PlaceholderInstruction
      • ReturnInstruction
      • StartAssemblyInstruction
        • StartAssemblyInstruction.get_block_instructions()
      • StartLoopInstruction
      • ThrowInstruction
      • TryInstruction
        • TryInstruction.get_block_instructions()
      • CatchInstruction
        • CatchInstruction.get_block_instructions()
    • Instructions
      • Instructions.asm_block_instructions()
      • Instructions.break_instructions()
      • Instructions.calls()
      • Instruction.catch_instructions()
      • Instructions.continue_instructions()
      • Instructions.delegate_calls()
      • Instructions.delegate_calls_from_assembly()
      • Instructions.delegate_calls_non_assembly()
      • Instructions.end_asm_instructions()
      • Instructions.end_if_instructions()
      • Instructions.end_loop_instructions()
      • Instructions.entry_point_instructions()
      • Instructions.exec()
      • Instructions.expression_instructions()
      • Instructions.external_calls()
      • Instructions.functions()
      • Instructions.high_level_static_calls()
      • Instructions.if_instructions()
      • Instructions.if_loop_instructions()
      • Instructions.internal_calls()
      • Instructions.library_calls()
      • Instructions.low_level_function_calls()
      • Instructions.low_level_static_calls()
      • Instructions.modifiers()
      • Instructions.new_contract_instructions()
      • Instructions.new_variable_instructions()
      • Instructions.placeholder_instructions()
      • Instructions.return_instructions()
      • Instructions.start_asm_instructions()
      • Instructions.start_loop_instructions()
      • Instructions.throw_instructions()
      • Instructions.try_instructions()
      • Instructions.with_all_callee_function_names()
      • Instructions.with_callee_function_name()
      • Instructions.with_callee_function_name_prefix()
      • Instructions.with_callee_function_name_suffix()
      • Instructions.with_callee_function_signature()
      • Instructions.with_one_of_callee_function_names()
      • Instructions.without_callee_function_name()
      • Instructions.without_callee_function_names()
    • Value
      • Value
        • Value.expression
        • Value.is_main_value()
        • Value.parent_value
        • Value.get_callee_values()
        • Value.get_state_vars()
        • Value.get_local_vars()
        • Value.get_global_vars()
        • Value.get_arg_vars()
        • Value.get_vars()
      • ValueExpression
        • ValueExpression.get_dest()
        • ValueExpression.get_component()
        • ValueExpression.get_components()
      • Var
        • Var.backward_df()
        • Var.forward_df()
        • Var.get_object_of_var()
        • Var.get_parent()
        • Var.procedure_graph_node
        • Var.type
      • Literal
        • Literal.get_type()
        • Literal.get_value()
      • Call
        • Call.signature
        • Call.name
        • Call.get_contract_name()
        • Call.get_args()
        • Call.get_arg()
        • Call.get_call_gas()
        • Call.get_call_qualifier()
        • Call.get_call_salt()
        • Call.get_call_type()
        • Call.get_call_value()
        • Call.get_function()
        • Call.get_special_params()
        • Call.kv_parameters()
        • CallType
          • CallType.EVENT
          • CallType.EXTERNAL
          • CallType.INTERNAL
          • CallType.LIBRARY
          • CallType.LOW_LEVEL
          • CallType.NEW_ARR
          • CallType.NEW_ELEMENTARY_TYPE:
          • CallType.NEW_STRUCT
          • CallType.PRIVATE
          • CallType.PUBLIC
          • CallType.SOLIDITY
          • CallType.TYPE_CONVERSION
    • Point
      • Point
        • Point.backward_df()
        • Point.forward_df()
        • Point.extended_backward_df()
        • Point.extended_forward_df()
        • Point.has_global_df()
        • Point.has_extended_global_df()
        • Point.get_parent()
        • Point.get_all_tainted_paths_affecting_point()
        • Point.get_tainted_path_affecting_point()
        • Point.get_tainted_sources_affecting_point()
        • Point.df_reaching_functions_arguments()
        • Point.df_reaches_from_functions_arguments()
      • ArgumentPoint
        • ArgumentPoint.get_variable()
      • ArgumentPoints
        • ArgumentsPoints.with_memory_type()
        • ArgumentPoints.with_name()
        • ArgumentPoints.with_type()
        • ArgumentPoints.list()
      • ExternalPoint
        • ExternalPoint.get_variable()
        • ExternalPoint.source_code()
      • GlobalPoint
        • GlobalPoint.get_variable()
      • StatePoint
        • StatePoint.get_variable()
      • VarValue
        • VarValue.backward_df()
        • VarValue.extended_backward_df()
        • VarValue.extended_forward_df()
        • VarValue.forward_df()
        • VarValue.get_defining_points()
        • VarValue.get_object_of_var()
        • VarValue.get_parent()
        • VarValue.type
    • Variables
      • Variable
        • Variable.canonical_name
        • Variable.data
        • Variable.name
        • Variable.source_code()
        • Variable.type
      • StateVariables
        • StateVariables
          • StateVariables.exec()
          • StateVariables.with_all_properties()
          • StateVariables.with_one_property()
          • StateVariables.with_type()
          • StateVariable.with_name()
        • StateVariableProp
        • StateVariable
          • StateVariable.contract()
          • StateVariable.is_accessible()
          • StateVariable.is_constant()
          • StateVariable.is_immutable()
          • StateVariable.is_internal()
          • StateVariable.is_private()
          • StateVariable.is_public()
          • StateVariable.properties()
          • StateVariable.source_code()
      • LocalVariables
        • LocalVariables
          • LocalVariables.with_memory_type()
          • LocalVariables.with_type()
        • LocalVariable
          • LocalVariable.get_parent()
          • LocalVariable.property
          • LocalVariable.source_code()
      • GlobalVariables
      • ArgumentVariable
        • ArgumentVariable.index
        • ArgumentVariable.data
        • ArgumentVariable.memory_type
        • ArgumentVariable.source_code()
    • Struct
      • Struct.data
      • Struct.fields
      • Struct.name
    • StructField
      • StructField.name
      • StructField.type
    • Structs
      • Structs.exec()
    • Internal
      • CallGraph
        • CallGraph.all_nodes()
        • CallGraph.get_corresponding_node_for_function()
        • CallGraph.nodes()
        • CallGraph.with_name()
        • CallGraph.with_name_not()
        • CallGraph.with_name_prefix()
        • CallGraph.with_name_suffix()
      • CallNode
        • CallNode.callable()
        • CallNode.callable_name()
        • CallNode.callee_functions()
        • CallNode.callee_modifiers()
        • CallNode.callees()
        • CallNode.caller_functions()
        • CallNode.caller_modifiers()
        • CallNode.callers()
        • CallNode.get_extended_callees()
        • CallNode.get_extended_callers()
        • CallNode.is_function
        • CallNode.is_modifier
      • Queryable
        • Queryable.query_aggregator
      • NoneObject
        • NoneObject.dump_into_json()
        • NoneObject.instructions()
        • NoneObject.name()
  • Changelog
  • 🚧Limitations
  • πŸ”§Glider Usage
  • πŸ—ΊοΈRoadmap
  • πŸ‘₯Comparison with other tools
  • βš–οΈLegal Notices
    • Privacy Notice
    • Terms and Conditions
Powered by GitBook
On this page
  • The Foundational Query
  • Variables
  • Naming Variables
  • Variable Exercise
  • Strings, Integers, and Booleans
  • Strings
  • Integers
  • Booleans
  • Functions
  • Why Use Functions
  • Function Name
  • Returning Data from Functions
  • Function Arguments
  • How to Create Functions
  • Calling Functions
  • Chaining Function Calls
  • Using print() in Glider queries for debugging
  • Printing Function Properties Exercise
  • Conclusion
  • What’s Next?
  1. Glider: The Basics
  2. Intro to Python

Basic Python

The Foundational Query

Glider queries are powered by Python, a high-level programming language known for its simplicity and readability. If you’re new to Python, this section will introduce you to core concepts such as variables and functions. Along the way we will show you Python is used to write Glider queries.

In the following topics below, we’ll analyze our foundational query, discovering essential Python functionalities used throughout the query. If you’re unfamiliar with Python, you can refer to this query as a guide to understanding how different aspects of the language work.

The first foundational query we will review can be found below:

from glider import *

def query():
    swap_functions = Functions().with_name("swap").exec(10)

    swap_functions.filter(lambda function: print(function.address()))

    return swap_functions

Variables

In Python, variables allow you to store and manage data, such as strings, integers, and more. They act as placeholders for values that you can reference later in your code.

For example, consider the following code:

swap_functions = Functions().with_name("swap").exec(10)

Here, we are creating a variable called swap_functions. The variable name is on the left side of the equals = operator, while the right side contains the data the variable stores.

In this case, the data consists of the query results for the first 10 "swap" functions.

Functions().with_name("swap").exec(10)

Naming Variables

You can name variables however you like, but it’s best to choose a name that clearly describes what the variable stores. In this case, since the variable holds queried functions, we name the variable swap_functions to keep the code clear and readable.

Once created, a variable can be reused throughout the query, making the code more elegant and easy to read.

Variable Exercise

Exercise: Create a variable that stores the number of functions found in the swap_functions variable.

Hint: You can use Python’s built-in len() function to count the number of items in a variable.

from glider import *

def query():
    swap_functions = Functions().with_name("swap").exec(10)

    # CHALLENGE: Create a variable and assign it to len(swap_functions)

    swap_functions.filter(lambda function : print(function.address()))

    return swap_functions

Strings, Integers, and Booleans

Strings

In Python, text is often enclosed in double quotes " " like this:

"This is a string"

This is called a string - a data type used to store text. Strings have many uses, but in Glider queries, they play a key role in specifying how a query should be executed.

For example, when searching for functions by name, we use a string to specify the function name we want to find:

Functions().with_name("swap")

In the code above, we have the "swap" string which tells Glider we want to find functions named "swap."

Integers

In programming, we often work with numbers. In Python, these are called integers.

Glider queries use integers to specify how many records Glider should search for. If we look back at our foundational query, we can see an integer written in the exec() call:

Functions().with_name("swap").exec(10)

Here, the integer 10 tells Glider to fetch 10 matching functions.

Booleans

In Python, a boolean (bool) is a data type that represents either a True or False value. Certain Python code can return booleans. Booleans are useful for making decisions in code, such as filtering results in a Glider query.

Let’s look at some examples. In the code below, the statement returns True because both strings are identical:

"onERC721Received" == "onERC721Received" # Returns True

If the strings were different, the expression would return False.

"onERC721Received" == "receivedERCToken" # Returns False

Tip: An expression is code that returns a value. A value is a piece of data that can be a string, integer, boolean, etc.

"onERC721Received" == "receivedERCToken"

The code shown above is an expression since it returns return True or False. An expression can return more than just True or False; it can return strings, integers, etc.

Functions

In Python, we often find ourselves writing the same code multiple times. This can make our programs long, repetitive, and difficult to understand. A great way to solve this is by using functions.

A function is a reusable block of code that helps keep our programs organized and clean. Python and Glider provide many built-in functions, but we can also create our own!

Let’s look at the following function:

def contains_state_variables(contract):
    return len(contract.state_variables().exec()) > 0

This function contains a single line of code that checks whether a contract contains any state variables.

Once we create a function, we can then run the function (aka execute the function code). With a function, our code becomes smaller and simpler to understand. To use (or call) this function, we write:

creates_local_variables(function)

In this section, we will go over various aspects of functions, how to create them, and conclude with an challenge exercise.

Tip: In Python, functions are sometimes called methods. While there’s a difference between the two, for this series, we’ll use "functions" to refer to both.

Why Use Functions

When we write code, we often reuse the same logic multiple times or find ourselves grouping chunks of code together. Let’s consider the following Glider query:

Functions()
    .exec(1000)
    .filter(lambda function : function.get_contract().name not in {"UniswapV3Pool"})
    .filter(
        lambda function : 
        len(
            function
            .instructions_recursive()
            .filter(lambda instruction: instruction.is_if() or instruction.is_if_loop() or instruction.is_start_loop())
        ) > 30
    )

Even without understanding exactly how this code works, it’s clear that a lot is happening. Can we improve the readability of this query? Yes! By using functions, we can simplify the query as follows:

(
    Functions()
    .exec(1000)
    .filter(not_uniswap_pools)
    .filter(has_too_much_control_flow)
)

def not_uniswap_pools(function):
    return function.get_contract().name not in ["UniswapV3Pool"]
 
def has_too_much_control_flow(function):
    return len(
        function
        .instructions_recursive()
        .filter(is_control_flow)
    ) > 30

def is_control_flow(instruction):
    return instruction.is_if() or instruction.is_if_loop() or instruction.is_start_loop()

In this updated version, we’ve extracted parts of the query into separate functions. This makes the code more readable by clearly defining what each section of code does. Now, if we look at the main portion of the query:

(
    Functions()
    .exec(1000)
    .filter(not_uniswap_pools)
    .filter(has_too_much_control_flow)
)

We can easily understand it at a glance. Roughly translated, it means:

Find 1000 functions that are not part of a Uniswap pool and has too much control flow.

By creating functions, we’ve written cleaner, more readable code that is easier to maintain and understand.

Function Name

A function name describes what the function does. Choosing a clear and meaningful name makes your code easier to read and understand.

For example, if we create a function to find contracts named IERC20, we might call the function get_erc20_interface_contracts as seen below:

def get_erc20_interface_contracts():

Each function name must be unique, and we use the name to call (run) the function later. We can identify the function name by looking at the text that comes after the def keyword:

def defines_variables():

This function name gives us an idea of what the function does and hints at what it might return (more on that soon!).

Returning Data from Functions

Functions don’t just execute code - they can also return data. This is useful when we want a function to perform a task and then provide a result we can use elsewhere.

Tip: Functions are not required to return data.

In fact, every Glider query relies on return values! For example, the query() function below returns the Glider query results:

def query():
    swap_functions = Functions().with_name("swap").exec(10)
    
    # Return the Glider results
    return swap_functions

By returning values, functions become powerful tools for organizing and reusing code efficiently. This allows us to break down complex logic into smaller, more manageable pieces.

Function Arguments

When writing functions, we often need to use data from outside the function inside of the function. This is where function arguments come in.

A function argument allows us to pass additional data into a function so it knows exactly what to do.

What do function arguments look like?

Function arguments are placed inside parentheses () when defining a function. For example, the function below accepts a single argument named contract:

def contains_state_variables(contract):
    return len(contract.state_variables().exec()) > 0

Inside the function, we can use the function argument just like any other variable.

Functions can also accept multiple arguments like so:

def contains_state_variables(contract, state_variables_count):
    return len(contract.state_variables().exec()) > state_variables_count

In this example, we introduced a second argument, state_variables_count, which we then use to gauge how many state variables the contract has.

Using function arguments makes our functions more flexible and reusable, allowing us to work with different data each time we call the function.

How to Create Functions

Now that we’ve covered the basics of functions, let’s learn how to create one. In Python, we use specific keywords and syntax to define a function.

Here’s a simple function template:

def name_of_function(argument_1, argument_2):
    # ADD CODE HERE

Breaking it Down

In the function above we:

  • Defined a function using the def keyword.

  • Named the function name_of_function.

  • Added two arguments inside the parentheses (argument_1, argument_2).

  • Add code inside of the function. Be sure to indent the code inside the function, otherwise the code won't execute.

This template can be used whenever you want to create a function. Now, let’s explore how to call and use our functions!

Calling Functions

Once we define a function, we need to call it to execute its code.

To call a function, simply write the function name followed by parentheses ():

if_instructions()

This calls a function named if_instructions.

Calling Functions with Arguments

If a function requires arguments, we need to add the arguments inside the parentheses.

For example, the with_name() function accepts a single argument:

with_name("swap")

Here, we pass the string "swap" into the with_name() function. This tells with_name() we want to find functions named swap.

Calling functions allows us to run reusable code and pass in custom values when needed.

Chaining Function Calls

A useful feature in Python is chaining function calls, which allows us to call multiple functions back to back. But what does this actually do, and why use it?

How It Works

When we chain function calls, each function returns data that the next function uses. This makes our code more concise and readable.

For example, consider this Glider query:

Functions().with_name("swap").exec(10)

Breaking It Down

Let's now break down the code snippet into sections:

  • .with_name("swap") β†’ Calls the with_name() function on the Functions object to query for functions named "swap", returning a Functions object.

  • .exec(10) β†’ Calls the exec() function on the Functions object to execute the query and return 10 results.

By chaining these function calls together, we can apply multiple operations in a single statement. This makes the code cleaner, more readable, and more efficient.

You can wrap chained function calls in parentheses () to make the code easier to read:

(
    Functions()
    .with_name("swap")
    .exec(10)
)

Using print() in Glider queries for debugging

One of the most useful functions in Glider queries is print(). It can take any number or type of arguments. When called, print() prints the arguments to the Output Panel in the Glider IDE.

For example running the following code below:

print("Check out this cool info!")

Will display in following content in the Glider IDE Output panel:

Check out this cool info!

Why Use print()?

The print() function is great for:

  • View what a variable stores.

  • Check if a section is executed (if it's printed, you know the code is executed)

Printing Function Properties Exercise

Challenge: Modify the query below by adding the print() function to display the function properties of the swap_function variable in the Glider IDE output panel.

Hint: To determine the function properties, we can call:

function.properties()
from glider import *

def query():
    swap_functions = Functions().with_name("swap").exec(10)

    swap_function = swap_functions[0]
    
    # CHALLENGE: Print the swap_function properties below

    return swap_functions

Conclusion

Great job! πŸŽ‰

You’ve now learned some of the fundamental building blocks of Python, including:

  • Variables - How to store and reuse data.

  • Strings, Integers, and Booleans - The different types of data you can work with.

  • Functions - How to create reusable blocks of code and run functions.

  • Chaining function calls - How to streamline your Glider queries by calling multiple functions back-to-back.

  • The print() function - A useful function for debugging and checking values inside your queries.

What’s Next?

  • Classes - Understanding how to create class instances.

  • Glider API Functions - Exploring built-in functions provided by Glider.

  • Lists - Understanding and efficiently managing Glider query results.

Keep going as you’re on your way to mastering Python for Glider queries!

PreviousIntro to PythonNextAdvanced Python

Last updated 22 days ago

Click here for the solution

Stuck or want to confirm your answer? Visit the link below where you can view and run the solution inside of Glider IDE:

Functions() β†’ Creates a Functions class instance. Note: We'll discuss class instances more in the .

Click here for the solution

Stuck or want to confirm your answer? Visit the link below where you can view and run the solution inside of Glider IDE:

In the , we’ll dive into more complex concepts including:

πŸŽ“
πŸ’‘
πŸ’‘
https://glide.r.xyz/query/BOTP5BqCh
https://glide.r.xyz/query/aGtCqO1E
next section
Advanced Python section
Printing Output to the Glider IDE