0% found this document useful (0 votes)
28 views50 pages

CC 03 Objects

Uploaded by

Ajay Singh Negi
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
28 views50 pages

CC 03 Objects

Uploaded by

Ajay Singh Negi
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 50

Object Oriented

Patterns
A Historical
Perspective
Dr. Charles R. Severance
www.cc4e.com
code.cc4e.com (sample code)
online.dr-chuck.com
Outline – Object Oriented
• Review from previous courses
• A historical perspective
• Using C to build an OO support
• Building a Python str() class in C
• Building a Python list() class in C
• Building a Python dict() class in C
• Reference: 6.5.1
OO Review – online.dr-chuck.com
• OO Python
• Python for Everybody – Chapter 14
• Django for Everybody
• OO JavaScript
• Django for Everybody
• Web Applications for Everybody

• The goal of this content is to explore how one would implement OO


patterns using C
Definitions (Review)
• Class – a Template – cookie cutter
• Attribute – Some data item that is to be contained in each instance of the
class
• Method – Some code (i.e. like a function) that operates within the context of
an instance of the class
• Object – A particular instance of a class "stamped out" from the class
when a new instance of the class is requested

Image CC-By 2.0: https://www.flickr.com/photos/dinnerseries/23570475099


import math

class Point:
constructor def __init__(self, x, y):
self.x = x attributes
attributes self.y = y

def dump(self):
methods print('Object point@%x x=%f y=%f' % (id(self),self.x,self.y))

def origin(self):
return math.sqrt(self.x*self.x+self.y*self.y)

pt = Point(4.0, 5.0)
Point.dump(pt) constructed
print('Origin',pt.origin())
del(pt)
destructed

Object point@102ad1f10 x=4.000000 y=5.000000


Origin 6.4031242374328485

kr_03_01.py
Object Orientation
Across Time and Programming Languages
Science Calculations

System

System

C uses curly
braces { } for
code blocks.

Scripting/
Interpreted
p://en.wikipedia.org/wiki/History_of_programming_languages
Procedural

Hybrid

Object Oriented

Classes were
added to PHP in
ps://en.wikipedia.org/wiki/Object-oriented_programming 2000
OO Implementations Over Time
• Python (1991)
• C++ (1980)
• Java (1995)
• JavaScript (1995)
• PHP (2000)
• C# (2001)

P.S. The more languages you know the better – Dr. Chuck
import math
Object point@102ad1f10 x=4.000000 y=5.000000
class Point: Origin 6.4031242374328485
def __init__(self, x, y):
self.x = x
self.y = y
Python uses the concept of "self" to refer to
def dump(self): the variables stored in the current instance.
print('Object point@%x x=%f y=%f' % The constructor is by convention "__init__".
(id(self),self.x,self.y))

def origin(self):
return math.sqrt(self.x*self.x+self.y*self.y)

pt = Point(4.0, 5.0)
Point.dump(pt)
print('Origin',pt.origin())
del(pt)

1991 cc_03_01.py
#include <iostream>
#include <math.h>

class Point {
public:
double x, y; Object point x=4.000000 y=5.000000
Origin: 6.40312
Point(double xc, double yc) {
x = xc;
y = yc; C++ was initially implemented as a pre-
};
processing pass that did textual
void dump() { transformations and then passed the code
printf("Object point x=%f y=%f\n", x, y); into the C compiler. There is no concept of
} "self" or "this".
double origin() {
return sqrt(x*x+y*y);
}
};

int main() {
Point pt(4.0, 5.0);
pt.dump();
printf("Origin: %f\n", pt.origin());
}

1980 cc_03_01.cpp
import java.lang.Math;

public class Point {


double x,y;

Point(double x, double y) { Point@7cef4e59 x=4.000000 y=5.000000


this.x = x; Origin 6.403124
this.y = y;
}
The keyword "this" is a reserved word in the
void dump() {
System.out.printf("%s x=%f y=%f\n",
Java language. It is used to refer to the
this, this.x, this.y); current instance of the class. The constructor
} is an un-typed function with the same name
as the class. When you print "this" out, it
double origin() {
return Math.sqrt(this.x*this.x+this.y*this.y); resolves to the name of the class and an
} indication of which instance we are currently
} in. The toString() method produces the string.
------------------------------------------------------
public class cc_03_01 {

public static void main(String[] args)


{
Point pt = new Point(4.0, 5.0);
pt.dump();
System.out.printf("Origin %f\n",pt.origin());
} Point.java
} 1995 cc_03_01.java
function Point(x, y) { Object point x=4 y=5
this.x = x; Origin 6.4031242374328485
this.y = y;
this.party = function () {
this.x = this.x + 1; JavaScript takes the "this" and "new"
console.log("So far "+this.x);
keywords from Java but not much else.
}
There is no "class" keyword. Formatted The
this.dump = function () { way methods are defined take inspiration
console.log("Object point x=%f y=%f", from functional languages like Scheme and
this.x, this.y); use the "first-class function" pattern. Output
} tracks C very closely. The class definition
itself overloads the "function" keyword.
this.origin = function () {
return Math.sqrt(this.x*this.x+this.y*this.y);
}
TypeScript is an "evolved" version of
} JavaScript and adds "class" and "this"
keywords allowing for a more traditional
pt = new Point(4.0, 5.0); Java-like syntax for declaring objects.

pt.dump();
console.log("Origin %f",pt.origin());
1995 cc_03_01.js
class Point { Object point x=4.000000 y=5.000000
private $x, $y; Origin 6.403124

public function __construct($x, $y) {


$this->x = $x; PHP introduced Object Orientation in PHP 4
$this->y = $y;
in 2000 so it could borrow patterns like
}
"this", "class", and "new" from languages like
public function dump() { Java. Because PHP started with Perl 😞 ,
printf("Object point x=%f y=%f\n", variables start with '$'. Also, PHP uses the '.'
$this->x, $this->y); operator for concatenation for the "object
} lookup" operator, PHP had to use "->" which
is inspired by the syntax C uses with a
public function origin() { pointer to a structure.
return sqrt($this->x*$this->x+
$this->y*$this->y);
}
}

$pt = new Point(4.0, 5.0);


$pt->dump();
printf("Origin %f\n",$pt->origin());
2000 cc_03_01.php
using System;
Point object x=4 y=5
public class Point
{
Origin 6.40312423743285
public double x,y;

public Point(double cx, double cy) {


x = cx;
Microsoft's C# was relatively recent and so it
y = cy; could look at the other approaches and pick
} what they saw as the best parts. C# took
most of its inspiration from Java.
public void dump() {
Console.WriteLine("Point object x={0} y={1}", x, y);
}

public double origin() {


return Math.Sqrt(x*x+y*y);
}
}

class TestPoint{
public static void Main(string[] args)
{
Point pt = new Point(4.0, 5.0);
pt.dump();
Console.WriteLine("Origin {0}", pt.origin());
}
} 2001 cc_03_01.cs
Using C to Build OO
Support
How was Python's OO layered on top of C?
import math
Object point@102ad1f10 x=4.000000 y=5.000000
class Point: Origin 6.4031242374328485
def __init__(self, x, y):
self.x = x
self.y = y

def dump(self):
print('Object point@%x x=%f y=%f' %
(id(self),self.x,self.y))

def origin(self):
return math.sqrt(self.x*self.x+self.y*self.y)

pt = Point(4.0, 5.0)
Point.dump(pt)
print('Origin',pt.origin())
del(pt)

1991 cc_03_01.py
#include <stdio.h> struct Point * point_new(double x, double y) {
#include <stdlib.h> struct Point *p = malloc(sizeof(*p));
#include <math.h> p->x = x;
p->y = y;
struct Point { p->dump = &point_dump;
double x; p->origin = &point_origin;
double y; p->del = &point_del;
return p;
void (*del)(const struct Point* self); }
void (*dump)(const struct Point* self);
double (*origin)(const struct Point* self); int main(void)
}; {
struct Point * pt = point_new(4.0,5.0);
void point_dump(const struct Point* self) pt->dump(pt);
{ printf("Origin %f\n", pt->origin(pt));
printf("Object point@%p x=%f y=%f\n", pt->del(pt);
self, self->x, self->y); }
}

void point_del(const struct Point* self) {


free((void *)self);
}

double point_origin(const struct Point* self) { Object point@0x600003e94030 x=4.000000 y=5.000000


return sqrt(self->x*self->x + self->y*self->y); Origin 6.403124
}

1975 cc_03_01.c
Building a Python str()
Class
int main(void)
{
printf("Testing pystr class\n");
struct pystr * x = pystr_new();
pystr_dump(x);
x = str()
x = x + 'H' pystr_append(x, 'H');
print(x) pystr_dump(x);
x = x + 'ello world'
print(x) pystr_appends(x, "ello world");
x = 'A completely new string' pystr_dump(x);
print("String = ", x)
print("Length = ", len(x)) pystr_assign(x, "A completely new string");
printf("String = %s\n", pystr_str(x));
printf("Length = %d\n", pystr_len(x));
pystr_del(x);
}
H
Hello world
String = A completely new string Testing pystr class
Length = 23 Object length=0 alloc=10 data=
Object length=1 alloc=10 data=H
Object length=11 alloc=20 data=Hello world
String = A completely new string
Length = 23

cc_03_02.py
struct pystr
String Structure
{
int length;
int alloc; /* The length of *data */
and Constructor
char *data;
};

/* x = str() */
struct pystr * pystr_new() {
struct pystr *p = malloc(sizeof(*p));
p->length = 0;
p->alloc = 10;
p->data = malloc(10);
p->data[0] = '\0'; length: 0
return p;
}
alloc: 10
data: ∅ ? ? ? ? ? ? ? ? ?
...

int main(void)
{
struct pystr * x = pystr_new();
...
}

cc_03_02.c
struct pystr
{
int length;
char *data;
int alloc; /* The length of *data */
Some Methods
};

/* Constructor – x = str() */
struct pystr * pystr_new() { int pystr_len(const struct pystr* self)
struct pystr *p = malloc(sizeof(*p)); {
p->length = 0; return self->length;
p->alloc = 10; }
p->data = malloc(10);
p->data[0] = '\0'; char *pystr_str(const struct pystr* self)
return p; {
} return self->data;
}
/* Destructor – del(x) */
void pystr_del(const struct pystr* self) {
free((void *)self->data); /* free string first */
free((void *)self);
}

void pystr_dump(const struct pystr* self)


{
printf("Pystr length=%d alloc=%d data=%s\n",
self->length, self->alloc, self->data);
} cc_03_02.c
/* x = x + 'h'; */

Data Methods void pystr_append(struct pystr* self, char ch) {


/* Need about 10 lines of code here  */
}

/* x = x + "hello"; */
• We have three methods to
put data into our structure void pystr_appends(struct pystr* self, char *str) {
/* Need one line of code here  */
}
• You can build pystr_append()
/* x = "hello"; */
and then use it to make the
code in pystr_appends() and void pystr_assign(struct pystr* self, char *str) {
/* Need three lines of code here  */
pystr_assign() very simple. }

int main() {
• Objects like to reuse their struct pystr * x = pystr_new();

own methods because not pystr_append(x, 'H');


pystr_dump(x);
repeating yourself code is pystr_appends(x, "ello world");
pystr_dump(x);
more reliable }
pystr_assign(x, "A completely new string");
struct pystr
{

pystr_append()
int length;
char *data;
int alloc; /* the length of *data */
};

struct pystr * pystr_new() {


• Recall that the constructor struct pystr *p = malloc(sizeof(*p));

allocates a 10 character array p->length = 0;


p->alloc = 10;
and sets alloc to 10 p->data = malloc(10);
p->data[0] = '\0';
return p;
• Length of the actual string is }

zero because there is no data


• We can append 9 characters length: 0
with the data array that is alloc: 10
initially allocated data: ∅ ? ? ? ? ? ? ? ? ?

cc_03_02.c
pystr_append() length: 0
alloc: 10
data: ∅ ? ? ? ? ? ? ? ? ?
struct pystr
{
int length;
char *data;
int alloc; /* the length of *data */ length: 1
};
alloc: 10
int main() {
struct pystr * x = pystr_new(); data: H ∅ ? ? ? ? ? ? ? ?
pystr_append(x, 'H');
pystr_append(x, 'e');
}

length: 2
alloc: 10
data: H e ∅ ? ? ? ? ? ? ?
cc_03_02.c
length: 2 pystr_append()
alloc: 10
data: H e ∅ ? ? ? ? ? ? ? int main() {
struct pystr * x = pystr_new();
pystr_append(x, 'H');
pystr_append(x, 'e');
pystr_append(x, 'l');
pystr_append(x, 'l');
length: 9 pystr_append(x, 'o');
pystr_append(x, ' ');
alloc: 10 pystr_append(x, 'w');
pystr_append(x, 'o');
data: H e l l o w o r ∅ pystr_append(x, 'r');

pystr_append(x, 'l');
pystr_append(x, 'd');

length: 11 realloc() }

alloc: 20
data: H e l l o w o r l d ∅ ? ? ? ? ? ? ? ?
realloc() struct pystr * pystr_new() {
struct pystr *p = malloc(sizeof(*p));
p->length = 0;
p->alloc = 10;
• We can extend the size of a p->data = malloc(10);
p->data[0] = '\0';
dynamically allocated area by return p;

calling realloc() with the }

current pointer to the area void pystr_append(struct pystr* self, char ch) {
/* If we don't have space for 1 character plus
and the needed size termination, allocate 10 more */

• We may get a different if ( self->length >= (self->alloc - 2) ) {


self->alloc = self->alloc + 10;
address from realloc() self->data = (char *)
realloc(self->data, self->alloc);

• The data will be copied and }


...

the old data will be freed }

https://www.w3schools.in/c-programming/dynamic-memory-allocation#realloc-function
int main(void)
{

Using our "class" struct pystr * x = pystr_new();


pystr_dump(x);

pystr_append(x, 'H');
pystr_dump(x);

pystr_appends(x, "ello world");


x = str() pystr_dump(x);
x = x + 'H'
print(x) pystr_assign(x, "A completely new string");
x = x + 'ello world' printf("String = %s\n", pystr_str(x));
print(x) printf("Length = %d\n", pystr_len(x));
x = 'A completely new string' pystr_del(x);
print("String = ", x) }
print("Length = ", len(x))

Testing pystr class


Object length=0 alloc=10 data=
H Object length=1 alloc=10 data=H
Hello world Object length=11 alloc=20 data=Hello world
String = A completely new string String = A completely new string
Length = 23 Length = 23

cc_03_02.c
cc_03_02.py
Building a Python list()
Class
lst = list(); int main(void)
lst.append("Hello world"); {
print(lst) struct pylist * lst = pylist_new();
lst.append("Catch phrase"); pylist_append(lst, "Hello world");
print(lst) pylist_print(lst);
lst.append("Brian"); pylist_append(lst, "Catch phrase");
print(lst) pylist_print(lst);
print("Length =", len(lst)); pylist_append(lst, "Brian");
pylist_print(lst);
print("Brian?", lst.index("Brian")); printf("Length = %d\n", pylist_len(lst));
printf("Brian? %d\n", pylist_index(lst, "Brian"));
if "Bob" in lst: printf("Bob? %d\n", pylist_index(lst, "Bob"));
print("Bob?", lst.index("Bob")); pylist_del(lst);
else: }
print("Bob? 404");

['Hello world'] ['Hello world']


['Hello world', 'Catch phrase'] ['Hello world', 'Catch phrase']
['Hello world', 'Catch phrase', 'Brian'] ['Hello world', 'Catch phrase', 'Brian']
Length = 3 Length = 3
Brian? 2 Brian? 2
Bob? 404 Bob? -1

cc_03_03.c
cc_03_03.py
Basic stuff /* Destructor - del(lst) */
void pylist_del(struct pylist* self) {
struct lnode *cur, *next;
cur = self->head;
while(cur) {
struct lnode {
free(cur->text);
char *text;
next = cur->next;
struct lnode *next;
free(cur);
};
cur = next;
}
struct pylist {
free((void *)self);
struct lnode *head;
}
struct lnode *tail;
int count;
};

/* Constructor - lst = list() */ Important: Free structures from the


struct pylist * pylist_new() { "leaves" inwards – free the actual
struct pylist *p = malloc(sizeof(*p));
p->head = NULL; structure *last*
p->tail = NULL;
p->count = 0;
return p;
}

cc_03_03.c
Freeing Dynamic Memory 1
/* Destructor - del(lst) */ text: C
void pylist_del(struct pylist* self) { 2
struct lnode *cur, *next; next:
cur = self->head;
while(cur) { 4 3
free(cur->text); 1, 3, 5
text: is
next = cur->next;
free(cur); 2, 4, 6 next:
cur = next;
7
}
head: 6 5
free((void *)self); 7
} tail: text: Fun

count: 3 next: ∅

Even the order of next->cur->next and the free(cur)


matters because once free() is called, you should
assume the data is gone or zeroed out

cc_03_03.c
Printing a list
/* print(lst) */
void pylist_print(struct pylist* self)
{
['Hello world']
/* About 10 lines of code ['Hello world', 'Catch phrase']
The output should match Python's ['Hello world', 'Catch phrase', 'Brian']
list output Length = 3
Brian? 2
['Hello world', 'Catch phrase'] Bob? -1

Use printf cleverly, *not* string


concatenation since this is C, not Python.
*/
}

Remember that unlike Python's print() which always includes a newline, C's printf() only
adds a newline (\n) if you include it in the format string. So it is easy to print "long lines"
with no line breaks with for loops in C.
cc_03_03.c
More methods for you to
build
/* len(lst) */
int pylist_len(const struct pylist* self)
{
/* One line of code */
}

/* lst.append("Hello world") */
void pylist_append(struct pylist* self, char *str) {
/* Review: Chapter 6 lectures and assignments */
}

/* lst.index("Hello world") – if not found -1 */


int pylist_index(struct pylist* self, char *str)
{
/* Seven or so lines of code */
}

cc_03_03.c
Using our class int main(void)
{
struct pylist * lst = pylist_new();
pylist_append(lst, "Hello world");
pylist_print(lst);
• This is almost line for line pylist_append(lst, "Catch phrase");

identical to the Python pylist_print(lst);


pylist_append(lst, "Brian");
version of this code pylist_print(lst);
printf("Length = %d\n", pylist_len(lst));
printf("Brian? %d\n", pylist_index(lst, "Brian"));
• The output is also pretty printf("Bob? %d\n", pylist_index(lst, "Bob"));

much identical }
pylist_del(lst);

['Hello world']
['Hello world', 'Catch phrase']
['Hello world', 'Catch phrase', 'Brian']
Length = 3
Brian? 2
Bob? -1

cc_03_03.c
cc_03_03.py
Building a Python dict()
Class
Python Dictionary
{'z': 'Catch phrase'}
dct = dict(); {'z': 'W'}
dct["z"] = "Catch phrase" {'z': 'W', 'y': 'B', 'c': 'C', 'a': 'D'}
print(dct); Length = 4
dct["z"] = "W" z= W
print(dct); x= 404
dct["y"] = "B"
dct["c"] = "C" Dump
dct["a"] = "D" z=W
print(dct); y=B
print("Length =", len(dct)); c=C
print("z=", dct.get("z", 404)) a=D
print("x=", dct.get("x", 404))
print("\nDump")
for key in dct:
print(key+"="+dct[key])

cc_03_04.py
C Dictionary
int main(void)
{
struct pydict * dct = pydict_new(); {'z': 'Catch phrase'}
pydict_put(dct, "z", "Catch phrase"); {'z': 'W'}
pydict_print(dct); {'z': 'W', 'y': 'B', 'c': 'C', 'a': 'D'}
pydict_put(dct, "z", "W"); Length =4
pydict_print(dct); z=W
pydict_put(dct, "y", "B"); x=(null)
pydict_put(dct, "c", "C");
pydict_put(dct, "a", "D"); Dump
pydict_print(dct); z=W
printf("Length =%d\n",pydict_len(dct)); y=B
c=C
printf("z=%s\n", pydict_get(dct, "z")); a=D
printf("x=%s\n", pydict_get(dct, "x"));

printf("\nDump\n");
for(struct dnode * cur = dct->head; cur != NULL ; cur = cur->next ) {
printf("%s=%s\n", cur->key, cur->value);
}

pydict_del(dct);
} cc_03_04.c
/* Destructor - del(dct) */

Basic stuff void pydict_del(struct pydict* self) {


struct dnode *cur, *next;
cur = self->head;
while(cur) {
struct dnode { free(cur->key);
char *key; free(cur->value);
char *value; next = cur->next;
struct dnode *next; free(cur);
}; cur = next;
}
struct pydict { free((void *)self);
struct dnode *head; }
struct dnode *tail;
int count; z
}; key:
/* Constructor – dct = dict() */ value:
struct pydict * pydict_new() { Catch phrase
struct pydict *p = malloc(sizeof(*p)); next: ∅
p->head = NULL;
p->tail = NULL;
p->count = 0; int main(void)
return p; {
} struct pydict * dct = pydict_new();
pydict_put(dct, "z", "Catch phrase");
cc_03_04.c }
Methods for you to build
/* len(dct) */
int pydict_len(const struct pydict* self)
{
/* One line of code */
}

/* print(lst) */
/* {'z': 'W', 'y': 'B', 'c': 'C', 'a': 'D'} */
void pydict_print(struct pydict* self)
{
/* Some code */
}

cc_03_04.c
A Reusable Method
struct dnode* pydict_find(struct pydict* self, char *key)
{
/* Six lines of code */
}

/* x.get(key) - Returns NULL if not found */


char* pydict_get(struct pydict* self, char *key)
{
struct dnode *entry = pydict_find(self, key);
/* Two lines of code */
}

/* x[key] = value; Insert or replace the value associated with a key */


struct pydict* pydict_put(struct pydict* self, char *key, char *value) {
struct dnode *old = pydict_find(self, key);
if ( old != NULL ) {
/* Some code */
} else {
/* Some code */
} cc_03_04.c
}
struct dnode {
char *key;
Building a Dictionary
char *value;
struct dnode *next;
};
head:
struct pydict { ∅
struct dnode *head;
tail:
struct dnode *tail;
int count;
};

int main(void)
{
struct pydict * dct = pydict_new();
pydict_put(dct, "z", "Catch phrase");
pydict_put(dct, "z", "W");
pydict_put(dct, "y", "B");
pydict_put(dct, "c", "C");
pydict_put(dct, "a", "D");
...
}

cc_03_04.c
head:

struct dnode {
tail:
char *key;
char *value; z
struct dnode *next; key:
};
value:
struct pydict { Catch phrase
struct dnode *head;
struct dnode *tail;

int count;
};

int main(void)
{
struct pydict * dct = pydict_new();
pydict_put(dct, "z", "Catch phrase");
pydict_put(dct, "z", "W");
pydict_put(dct, "y", "B");
pydict_put(dct, "c", "C");
pydict_put(dct, "a", "D");
...
}

cc_03_04.c
head:

struct dnode {
tail:
char *key;
char *value; z
struct dnode *next; key:
};
value:
struct pydict { W
struct dnode *head;
struct dnode *tail;

int count;
}; Free Space:
int main(void) Catch phrase
{
struct pydict * dct = pydict_new();
pydict_put(dct, "z", "Catch phrase");
pydict_put(dct, "z", "W");
pydict_put(dct, "y", "B");
pydict_put(dct, "c", "C");
pydict_put(dct, "a", "D"); Make sure to free the data in value that was the
... "Catch phrase" string before allocating the "W"
}
string and setting value to point to the newly
allocated string.
head:

struct dnode {
tail:
char *key;
char *value; z
struct dnode *next; key:
};
value:
struct pydict { W
struct dnode *head;
struct dnode *tail; y
key:
int count;
}; value:
B
int main(void)
{
struct pydict * dct = pydict_new(); ∅
pydict_put(dct, "z", "Catch phrase");
pydict_put(dct, "z", "W");
pydict_put(dct, "y", "B");
pydict_put(dct, "c", "C");
pydict_put(dct, "a", "D");
...
}

cc_03_04.c
head:

struct dnode {
tail:
char *key;
char *value; z
struct dnode *next; key:
};
value:
struct pydict { W
struct dnode *head;
struct dnode *tail; y
key:
int count;
}; value:
B
int main(void)
{ c
struct pydict * dct = pydict_new(); key:
pydict_put(dct, "z", "Catch phrase");
pydict_put(dct, "z", "W"); value:
pydict_put(dct, "y", "B"); C
pydict_put(dct, "c", "C");
pydict_put(dct, "a", "D");
...

}

cc_03_04.c
head:

struct dnode {
tail:
char *key;
char *value; z
struct dnode *next; key:
};
value:
struct pydict { W
struct dnode *head;
struct dnode *tail; y
key:
int count;
}; value:
B
int main(void)
{ c
struct pydict * dct = pydict_new(); key:
pydict_put(dct, "z", "Catch phrase");
pydict_put(dct, "z", "W"); value:
pydict_put(dct, "y", "B"); C
pydict_put(dct, "c", "C");
pydict_put(dct, "a", "D"); a
...
key:
} value:
D
cc_03_04.c

Python OrderedDict() versus dict()
• Before Python 3.7 the dict() class did not remember the order of
items as they were inserted
• The Pre-3.7 Python used internal implementation used hashing to give fast
performance for key lookup and insert
• Since we have implemented dictionary functionality on top of a linked
list, our code behaves more like an OrderedDict()
• Our insert is quick but our key lookup using get() is slow as it might
need to scan the entire list
• We will address this performance issue in an upcoming lecture with
an awesome data structure that combines linked lists and hashing 
Summary
• OO Review from previous courses
• OO – A historical perspective
• Using C to build an OO support
• Building a Python str() class in C
• Building a Python list() class in C
• Building a Python dict() class in C (OrderedDict actually)
Acknowledgements / Contributions
These slides are Copyright 2023- Charles R. Severance (online.dr-chuck.com) Continue new Contributors and Translators here
as part of www.cc4e.com and made available under a Creative Commons
Attribution 4.0 License. Please maintain this last slide in all copies of the
document to comply with the attribution requirements of the license. If you
make a change, feel free to add your name and organization to the list of
contributors on this page as you republish the materials.

Initial Development: Charles Severance, University of Michigan School of


Information

Insert new Contributors and Translators here including names and dates

You might also like