Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Sage beginners guide - Finch Kraigh copy.pdf
Скачиваний:
13
Добавлен:
10.02.2015
Размер:
5.86 Mб
Скачать

Getting Started with Sage

The first line declares the name of the function and the argument list. Don't forget the colon after the argument list! It's also valid to define a function without any arguments, in which case the parenthesis must be empty.

The body of the function is a block of code that is uniformly indented. A unique feature of the Python language is that indentation is used to delimit blocks of code, rather than using symbols like curly braces. That is why it is so important to indent each line in the body of the function by the same amount. The first item within the function body is called the docstring. While this is optional, it's good to get in the habit of including it. Sage displays the docstring when the user asks for help on the function. The docstring is triple-quoted, which means that Sage will display its contents exactly as you format them. Next, the function can have any number of statements. Note that our function has its own local variable, tau. You can also define functions within functions. The final line of the function definition is the return keyword, followed by one or more variables whose values will be returned. If the function doesn't return anything, the return keyword can be used without any variable names, or return can be omitted.

If you find a block of code occurring more than once in your program, stop and move that block of code to a function. Duplicate blocks of code will make your programs harder to read and more prone to bugs.

Functions with keyword arguments

There are two good reasons to use keyword arguments when defining a function. One reason is to allow the user to omit arguments that are seldom changed from their default value. The other is to reduce confusion when calling the function. In the example above, it might be easy to accidentally interchange the resistance and capacitance values when calling the function, resulting in a bug that's hard to track down.

Timeforaction–definingafunctionwithkeywordarguments

Let's re-define our function with keyword arguments:

def RC_voltage(t, v0=100, R=1000, C=1e-9):

"""

 

 

 

Calculate

the voltage at time t for an R-C circuit

with initial voltage v0.

"""

 

 

 

tau = R *

C

return v0

* exp(-t / tau)

res = 250e3

# Ohms

cap = 4e-6

# Farads

 

 

 

 

 

 

[ 72 ]

 

 

 

 

Chapter 3

v0 = 100.0

# Volts

 

t

=

1.0

# seconds

 

v

=

RC_voltage(t, v0=v0, R=res, C=cap)

print('Voltage at t=' +

str(n(t, digits=4)) + 's is ' +

 

 

str(n(v, digits=4))

+ 'V')

The output is the same as the previous example.

What just happened?

Declaring keyword arguments is very similar to declaring positional arguments. If there are keyword arguments, they must be defined after the positional arguments. The default value of each keyword argument must be given. The following is the general form of a function definition with positional and keyword arguments:

def function_name(argument_1, argument_2, … , argument_n, keyword_arg_1=default_value,… , keyword_arg_n=default_value ):

"""

Documentation string here

"""

statement one statement two

...

return some_value

In our function definition, we used keyword arguments for the initial voltage, resistance, and capacitance. We had to move the time argument t so that it came before the keyword arguments. When we called the function, we used the keywords v0, R, and C to specify the initial voltage, resistance, and capacitance. In this case, it doesn't really make sense to use a keyword argument for t, since it's the only positional argument and there is no chance of confusing it with the keyword arguments.

Objects

Over the past three decades, object-oriented programming (OOP) has created a fundamental shift in the way that programmers approach problems. In the early days of OOP, people involved in scientific computing could largely ignore object-oriented principles. Today, that is no longer the case. While the algorithms of scientific computing are still fundamentally procedural, the software packages are increasingly constructed in an object-oriented fashion. OOP allows scientific software to be more organized, easier to use, and more maintainable. In this section, you will learn how to use pre-defined objects in Sage. In Chapter 9, you will learn how to create custom objects.

[ 73 ]

Getting Started with Sage

Timeforaction–workingwithobjects

If you are already familiar with objects from another programming language (such as Java or C++), then you will immediately be familiar with objects in Sage. If not, this example should help you understand the concept:

real_number = RR(10/3) print(type(real_number)) print('Value: ' + real_number.str()) print(real_number.n(digits=5))

print('Precision: ' + str(real_number.precision())) print(real_number.ceil())

The result should look like this:

What just happened?

We've already been using objects without knowing it—every number in Sage is actually an object! An object is a construct that consists of data (called attributes) and behaviours (called methods). An object's attributes and methods are defined by a class. We say that an object is an instance of a particular class. In our example, the object called real_number is an instance of a class called RR. We create an object using syntax that is just like a function call:

new_object = Class_Name(arg1, arg2, …)

The number and type of arguments (positional vs. keyword) will depend upon the class definition.

The object called real_number has an attribute that stores a representation of the floatingpoint number 1.4372. It has another attribute that stores the precision of the floating-point number. Objects can have other objects as attributes, leading to very complicated structures. An object's attributes can be interrogated and manipulated using methods. Methods are functions that are associated with an object. For example, the precision method returns the number of bits of precision for the real number:

real_number.precision()

We can use the str method to obtain a string representation of a real number:

real_number.str()

[ 74 ]

Chapter 3

Methods are called with the syntax:

result = object_name.method_name(argument_1, argument_2, … , argument_n)

One of the strengths of object-oriented programming is that the design of the object limits the ways that we can manipulate its data. For example, it wouldn't make any sense if we were allowed to change the value of a floating-point number without updating the number of bits of precision.

As you start using objects, you may be frustrated by the lack of direct access to the data. You may find yourself tempted to avoid using the methods, and directly manipulate the data in an object. This defeats the purpose of using objects! If the methods seem to be hindering your use of the object, you probably aren't using them right. Take another look at the documentation and examples, and re-think your approach.

Gettinghelpwithobjects

If you know an object's class, you can use the help function to see its architecture. In the previous example, we used the type function to determine that a real number's class is sage.rings.real_mpfr.RealNumber. We can use the help function to learn more about it. In the interactive shell, the class documentation looks like this:

sage: help(sage.rings.real_mpfr.RealLiteral)

Help on class RealNumber in module sage.rings.real_mpfr:

class RealNumber(sage.structure.element.RingElement)

|

File: sage/rings/real_mpfr.pyx (starting at line 1034)

|

 

 

 

|

A floating point approximation to a real number using any specified

|

precision. Answers derived from calculations with such

|

approximations may differ from what they would be if those

|

calculations were performed with true real numbers. This is due to

|

the rounding errors inherent to finite precision calculations.

|

 

 

 

|

The approximation is printed to slightly fewer digits than its

|

internal precision, in order to avoid confusing roundoff issues

|

that occur because numbers are stored internally in binary.

|

 

 

 

 

 

 

 

 

 

[ 75 ]

 

 

 

 

Getting Started with Sage

|

Method resolution order:

|

RealNumber

|

sage.structure.element.RingElement

|

sage.structure.element.ModuleElement

|

sage.structure.element.Element

|

sage.structure.sage_object.SageObject

|

__builtin__.object

|

 

 

...

The same information is available from the notebook interface, but the formatting will differ.

You can view the source code for a class by typing its name, followed by two question marks:

RR??

You can quickly access a list of methods by typing the name of an object followed by a period

and pressing Tab. If the object has many methods and you are using the interactive shell,

Sage will give you fair warning:

sage: real_number.

Display all 105 possibilities? (y or n)

If you are using the notebook interface, a table of methods will appear:

To find out more about a particular method, type the name of the object, a period, and the method name, followed by a question mark. Here is an example of how this looks in the interactive shell (it will also work in the notebook interface):

sage: real_number.cos?

Type: builtin_function_or_method

Base Class: <type 'builtin_function_or_method'>

[ 76 ]

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]