diff --git a/agents.py b/agents.py index 742cd6c40..b7f1d50ef 100644 --- a/agents.py +++ b/agents.py @@ -45,8 +45,7 @@ # ______________________________________________________________________________ -class Thing(object): - +class Thing: """This represents any physical object that can appear in an Environment. You subclass Thing to get the things you want. Each thing can have a .__name__ slot (used for output only).""" @@ -69,7 +68,6 @@ def display(self, canvas, x, y, width, height): class Agent(Thing): - """An Agent is a subclass of Thing with one required slot, .program, which should hold a function that takes one argument, the percept, and returns an action. (What counts as a percept or action @@ -222,8 +220,7 @@ def program(percept): # ______________________________________________________________________________ -class Environment(object): - +class Environment: """Abstract class representing an Environment. 'Real' Environment classes inherit from this. Your Environment will typically need to implement: percept: Define the percept that an agent sees. @@ -319,7 +316,8 @@ def delete_thing(self, thing): if thing in self.agents: self.agents.remove(thing) -class Direction(): + +class Direction: """A direction class for agents that want to move in a 2D plane Usage: d = Direction("down") @@ -371,7 +369,6 @@ def move_forward(self, from_location): class XYEnvironment(Environment): - """This class is for environments on a 2D plane, with locations labelled by (x, y) points, either discrete or continuous. @@ -507,7 +504,6 @@ def turn_heading(self, heading, inc): class Obstacle(Thing): - """Something that can cause a bump, preventing an agent from moving into the same square it's in.""" pass @@ -724,7 +720,8 @@ def get_world(self, show_walls=True): return result def percepts_from(self, agent, location, tclass=Thing): - """Returns percepts from a given location, and replaces some items with percepts from chapter 7.""" + """Returns percepts from a given location, + and replaces some items with percepts from chapter 7.""" thing_percepts = { Gold: Glitter(), Wall: Bump(), diff --git a/csp.py b/csp.py index 207576928..1e97d7780 100644 --- a/csp.py +++ b/csp.py @@ -12,7 +12,6 @@ class CSP(search.Problem): - """This class describes finite-domain Constraint Satisfaction Problems. A CSP is specified by the following inputs: variables A list of variables; each is atomic (e.g. int or string). @@ -49,7 +48,7 @@ class CSP(search.Problem): """ def __init__(self, variables, domains, neighbors, constraints): - "Construct a CSP problem. If variables is empty, it becomes domains.keys()." + """Construct a CSP problem. If variables is empty, it becomes domains.keys().""" variables = variables or list(domains.keys()) self.variables = variables @@ -61,7 +60,7 @@ def __init__(self, variables, domains, neighbors, constraints): self.nassigns = 0 def assign(self, var, val, assignment): - "Add {var: val} to assignment; Discard the old value if any." + """Add {var: val} to assignment; Discard the old value if any.""" assignment[var] = val self.nassigns += 1 @@ -73,7 +72,7 @@ def unassign(self, var, assignment): del assignment[var] def nconflicts(self, var, val, assignment): - "Return the number of conflicts var=val has with other variables." + """Return the number of conflicts var=val has with other variables.""" # Subclasses may implement this more efficiently def conflict(var2): return (var2 in assignment and @@ -81,7 +80,7 @@ def conflict(var2): return count(conflict(v) for v in self.neighbors[var]) def display(self, assignment): - "Show a human-readable representation of the CSP." + """Show a human-readable representation of the CSP.""" # Subclasses can print in a prettier way, or display with a GUI print('CSP:', self, 'with assignment:', assignment) @@ -99,12 +98,12 @@ def actions(self, state): if self.nconflicts(var, val, assignment) == 0] def result(self, state, action): - "Perform an action and return the new state." + """Perform an action and return the new state.""" (var, val) = action return state + ((var, val),) def goal_test(self, state): - "The goal is to assign all variables, with all constraints satisfied." + """The goal is to assign all variables, with all constraints satisfied.""" assignment = dict(state) return (len(assignment) == len(self.variables) and all(self.nconflicts(variables, assignment[variables], assignment) == 0 @@ -119,37 +118,37 @@ def support_pruning(self): self.curr_domains = {v: list(self.domains[v]) for v in self.variables} def suppose(self, var, value): - "Start accumulating inferences from assuming var=value." + """Start accumulating inferences from assuming var=value.""" self.support_pruning() removals = [(var, a) for a in self.curr_domains[var] if a != value] self.curr_domains[var] = [value] return removals def prune(self, var, value, removals): - "Rule out var=value." + """Rule out var=value.""" self.curr_domains[var].remove(value) if removals is not None: removals.append((var, value)) def choices(self, var): - "Return all values for var that aren't currently ruled out." + """Return all values for var that aren't currently ruled out.""" return (self.curr_domains or self.domains)[var] def infer_assignment(self): - "Return the partial assignment implied by the current inferences." + """Return the partial assignment implied by the current inferences.""" self.support_pruning() return {v: self.curr_domains[v][0] for v in self.variables if 1 == len(self.curr_domains[v])} def restore(self, removals): - "Undo a supposition and all inferences from it." + """Undo a supposition and all inferences from it.""" for B, b in removals: self.curr_domains[B].append(b) # This is for min_conflicts search def conflicted_vars(self, current): - "Return a list of variables in current assignment that are in conflict" + """Return a list of variables in current assignment that are in conflict""" return [var for var in self.variables if self.nconflicts(var, current[var], current) > 0] @@ -174,7 +173,7 @@ def AC3(csp, queue=None, removals=None): def revise(csp, Xi, Xj, removals): - "Return true if we remove a value." + """Return true if we remove a value.""" revised = False for x in csp.curr_domains[Xi][:]: # If Xi=x conflicts with Xj=y for every possible y, eliminate Xi=x @@ -190,12 +189,12 @@ def revise(csp, Xi, Xj, removals): def first_unassigned_variable(assignment, csp): - "The default variable order." + """The default variable order.""" return first([var for var in csp.variables if var not in assignment]) def mrv(assignment, csp): - "Minimum-remaining-values heuristic." + """Minimum-remaining-values heuristic.""" return argmin_random_tie( [v for v in csp.variables if v not in assignment], key=lambda var: num_legal_values(csp, var, assignment)) @@ -212,12 +211,12 @@ def num_legal_values(csp, var, assignment): def unordered_domain_values(var, assignment, csp): - "The default value order." + """The default value order.""" return csp.choices(var) def lcv(var, assignment, csp): - "Least-constraining-values heuristic." + """Least-constraining-values heuristic.""" return sorted(csp.choices(var), key=lambda val: csp.nconflicts(var, val, assignment)) @@ -229,7 +228,7 @@ def no_inference(csp, var, value, assignment, removals): def forward_checking(csp, var, value, assignment, removals): - "Prune neighbor values inconsistent with var=value." + """Prune neighbor values inconsistent with var=value.""" for B in csp.neighbors[var]: if B not in assignment: for b in csp.curr_domains[B][:]: @@ -241,7 +240,7 @@ def forward_checking(csp, var, value, assignment, removals): def mac(csp, var, value, assignment, removals): - "Maintain arc consistency." + """Maintain arc consistency.""" return AC3(csp, [(X, var) for X in csp.neighbors[var]], removals) # The search, proper @@ -251,8 +250,7 @@ def backtracking_search(csp, select_unassigned_variable=first_unassigned_variable, order_domain_values=unordered_domain_values, inference=no_inference): - """[Figure 6.5] - """ + """[Figure 6.5]""" def backtrack(assignment): if len(assignment) == len(csp.variables): @@ -306,7 +304,7 @@ def min_conflicts_value(csp, var, current): def tree_csp_solver(csp): - "[Figure 6.11]" + """[Figure 6.11]""" assignment = {} root = csp.variables[0] X, parent = topological_sort(csp.variables, root) @@ -332,7 +330,6 @@ def make_arc_consistent(Xj, Xk, csp): class UniversalDict: - """A universal dict maps any key to the same value. We use it here as the domains dict for CSPs in which all variables have the same domain. >>> d = UniversalDict(42) @@ -348,7 +345,7 @@ def __repr__(self): return '{{Any: {0!r}}}'.format(self.value) def different_values_constraint(A, a, B, b): - "A constraint saying two neighboring variables must differ in value." + """A constraint saying two neighboring variables must differ in value.""" return a != b @@ -413,7 +410,6 @@ def queen_constraint(A, a, B, b): class NQueensCSP(CSP): - """Make a CSP for the nQueens problem for search with min_conflicts. Suitable for large n, it uses only data structures of size O(n). Think of placing queens one per column, from left to right. @@ -453,7 +449,7 @@ def nconflicts(self, var, val, assignment): return c def assign(self, var, val, assignment): - "Assign var, and keep track of conflicts." + """Assign var, and keep track of conflicts.""" oldval = assignment.get(var, None) if val != oldval: if oldval is not None: # Remove old val if there was one @@ -462,20 +458,20 @@ def assign(self, var, val, assignment): CSP.assign(self, var, val, assignment) def unassign(self, var, assignment): - "Remove var from assignment (if it is there) and track conflicts." + """Remove var from assignment (if it is there) and track conflicts.""" if var in assignment: self.record_conflict(assignment, var, assignment[var], -1) CSP.unassign(self, var, assignment) def record_conflict(self, assignment, var, val, delta): - "Record conflicts caused by addition or deletion of a Queen." + """Record conflicts caused by addition or deletion of a Queen.""" n = len(self.variables) self.rows[val] += delta self.downs[var + val] += delta self.ups[var - val + n - 1] += delta def display(self, assignment): - "Print the queens and the nconflicts values (for debugging)." + """Print the queens and the nconflicts values (for debugging).""" n = len(self.variables) for val in range(n): for var in range(n): @@ -514,11 +510,10 @@ def flatten(seqs): return sum(seqs, []) _NEIGHBORS = {v: set() for v in flatten(_ROWS)} for unit in map(set, _BOXES + _ROWS + _COLS): for v in unit: - _NEIGHBORS[v].update(unit - set([v])) + _NEIGHBORS[v].update(unit - {v}) class Sudoku(CSP): - """A Sudoku problem. The box grid is a 3x3 array of boxes, each a 3x3 array of cells. Each cell holds a digit in 1..9. In each box, all digits are @@ -587,7 +582,7 @@ def abut(lines1, lines2): return list( def Zebra(): - "Return an instance of the Zebra Puzzle." + """Return an instance of the Zebra Puzzle.""" Colors = 'Red Yellow Blue Green Ivory'.split() Pets = 'Dog Fox Snails Horse Zebra'.split() Drinks = 'OJ Tea Coffee Milk Water'.split() diff --git a/games.py b/games.py index 9b98c5638..f5061f4c8 100644 --- a/games.py +++ b/games.py @@ -135,7 +135,7 @@ def min_value(state, alpha, beta, depth): def query_player(game, state): - "Make a move by querying standard input." + """Make a move by querying standard input.""" move_string = input('Your move? ') try: move = eval(move_string) @@ -145,7 +145,7 @@ def query_player(game, state): def random_player(game, state): - "A player that chooses a legal move at random." + """A player that chooses a legal move at random.""" return random.choice(game.actions(state)) @@ -179,27 +179,27 @@ class Game: be done in the constructor.""" def actions(self, state): - "Return a list of the allowable moves at this point." + """Return a list of the allowable moves at this point.""" raise NotImplementedError def result(self, state, move): - "Return the state that results from making a move from a state." + """Return the state that results from making a move from a state.""" raise NotImplementedError def utility(self, state, player): - "Return the value of this final state to player." + """Return the value of this final state to player.""" raise NotImplementedError def terminal_test(self, state): - "Return True if this is a final state for the game." + """Return True if this is a final state for the game.""" return not self.actions(state) def to_move(self, state): - "Return the player whose move it is in this state." + """Return the player whose move it is in this state.""" return state.to_move def display(self, state): - "Print or otherwise display the state." + """Print or otherwise display the state.""" print(state) def __repr__(self): @@ -250,7 +250,7 @@ def __init__(self, h=3, v=3, k=3): self.initial = GameState(to_move='X', utility=0, board={}, moves=moves) def actions(self, state): - "Legal moves are any square not yet taken." + """Legal moves are any square not yet taken.""" return state.moves def result(self, state, move): @@ -265,11 +265,11 @@ def result(self, state, move): board=board, moves=moves) def utility(self, state, player): - "Return the value to player; 1 for win, -1 for loss, 0 otherwise." + """Return the value to player; 1 for win, -1 for loss, 0 otherwise.""" return state.utility if player == 'X' else -state.utility def terminal_test(self, state): - "A state is terminal if it is won or there are no empty squares." + """A state is terminal if it is won or there are no empty squares.""" return state.utility != 0 or len(state.moves) == 0 def display(self, state): @@ -280,7 +280,7 @@ def display(self, state): print() def compute_utility(self, board, move, player): - "If 'X' wins with this move, return 1; if 'O' wins return -1; else return 0." + """If 'X' wins with this move, return 1; if 'O' wins return -1; else return 0.""" if (self.k_in_row(board, move, player, (0, 1)) or self.k_in_row(board, move, player, (1, 0)) or self.k_in_row(board, move, player, (1, -1)) or @@ -290,7 +290,7 @@ def compute_utility(self, board, move, player): return 0 def k_in_row(self, board, move, player, delta_x_y): - "Return true if there is a line through move on board for player." + """Return true if there is a line through move on board for player.""" (delta_x, delta_y) = delta_x_y x, y = move n = 0 # n is number of moves in row diff --git a/ipyviews.py b/ipyviews.py index 7cb28850b..4c3776fbc 100644 --- a/ipyviews.py +++ b/ipyviews.py @@ -27,7 +27,7 @@ class ContinuousWorldView: - ''' View for continuousworld Implementation in agents.py ''' + """ View for continuousworld Implementation in agents.py """ def __init__(self, world, fill="#AAA"): self.time = time.time() diff --git a/learning.py b/learning.py index 3e7f4690c..db25c42f3 100644 --- a/learning.py +++ b/learning.py @@ -39,7 +39,6 @@ def mean_boolean_error(predictions, targets): class DataSet: - """A data set for a machine learning problem. It has the following fields: d.examples A list of examples. Each one is a list of attribute values. @@ -173,7 +172,6 @@ def parse_csv(input, delim=','): class CountingProbDist: - """A probability distribution formed by observing and counting examples. If p is an instance of this class and o is an observed value, then there are 3 main operations: @@ -285,7 +283,6 @@ def predict(example): class DecisionFork: - """A fork of a decision tree holds an attribute to test, and a dict of branches, one for each of the attribute's values.""" @@ -317,7 +314,6 @@ def __repr__(self): class DecisionLeaf: - """A leaf of a decision tree holds just a result.""" def __init__(self, result): @@ -413,7 +409,7 @@ def decision_list_learning(examples): return [(True, False)] t, o, examples_t = find_examples(examples) if not t: - raise Failure + raise Exception return [(t, o)] + decision_list_learning(examples - examples_t) def find_examples(examples): @@ -439,8 +435,7 @@ def predict(example): def NeuralNetLearner(dataset, hidden_layer_sizes=[3], learning_rate=0.01, epoches=100): - """ - Layered feed-forward network. + """Layered feed-forward network. hidden_layer_sizes: List of number of hidden units per hidden layer learning_rate: Learning rate of gradient descent epoches: Number of passes over the dataset @@ -479,8 +474,7 @@ def predict(example): class NNUnit: - """ - Single Unit of Multiple Layer Neural Network + """Single Unit of Multiple Layer Neural Network inputs: Incoming connections weights: Weights to incoming connections """ @@ -493,8 +487,7 @@ def __init__(self, weights=None, inputs=None): def network(input_units, hidden_layer_sizes, output_units): - """ - Create Directed Acyclic Network of given number layers. + """Create Directed Acyclic Network of given number layers. hidden_layers_sizes : List number of neuron units in each hidden layer excluding input and output layers """ @@ -632,11 +625,11 @@ def LinearLearner(dataset, learning_rate=0.01, epochs=100): X_col = [dataset.values[i] for i in idx_i] # vertical columns of X # Add dummy - ones = [1 for i in range(len(examples))] + ones = [1 for _ in range(len(examples))] X_col = ones + X_col # Initialize random weigts - w = [random(-0.5, 0.5) for i in range(len(idx_i) + 1)] + w = [random.randrange(-0.5, 0.5) for _ in range(len(idx_i) + 1)] for epoch in range(epochs): err = [] @@ -820,8 +813,7 @@ def cross_validation(learner, size, dataset, k=10, trials=1): def cross_validation_wrapper(learner, dataset, k=10, trials=1): - """ - [Fig 18.8] + """[Fig 18.8] Return the optimal value of size having minimum error on validataion set. err_train: A training error array, indexed by size diff --git a/logic.py b/logic.py index 75c461e8f..9054cdfc7 100644 --- a/logic.py +++ b/logic.py @@ -60,7 +60,7 @@ def __init__(self, sentence=None): raise NotImplementedError def tell(self, sentence): - "Add the sentence to the KB." + """Add the sentence to the KB.""" raise NotImplementedError def ask(self, query): @@ -68,17 +68,16 @@ def ask(self, query): return first(self.ask_generator(query), default=False) def ask_generator(self, query): - "Yield all the substitutions that make query true." + """Yield all the substitutions that make query true.""" raise NotImplementedError def retract(self, sentence): - "Remove sentence from the KB." + """Remove sentence from the KB.""" raise NotImplementedError class PropKB(KB): - - "A KB for propositional logic. Inefficient, with no indexing." + """A KB for propositional logic. Inefficient, with no indexing.""" def __init__(self, sentence=None): self.clauses = [] @@ -86,22 +85,22 @@ def __init__(self, sentence=None): self.tell(sentence) def tell(self, sentence): - "Add the sentence's clauses to the KB." + """Add the sentence's clauses to the KB.""" self.clauses.extend(conjuncts(to_cnf(sentence))) def ask_generator(self, query): - "Yield the empty substitution {} if KB entails query; else no results." + """Yield the empty substitution {} if KB entails query; else no results.""" if tt_entails(Expr('&', *self.clauses), query): yield {} def ask_if_true(self, query): - "Return True if the KB entails query, else return False." + """Return True if the KB entails query, else return False.""" for _ in self.ask_generator(query): return True return False def retract(self, sentence): - "Remove the sentence's clauses from the KB." + """Remove the sentence's clauses from the KB.""" for c in conjuncts(to_cnf(sentence)): if c in self.clauses: self.clauses.remove(c) @@ -120,25 +119,25 @@ def program(percept): KB.tell(make_action_sentence(action, t)) return action - def make_percept_sentence(self, percept, t): + def make_percept_sentence(percept, t): return Expr("Percept")(percept, t) - def make_action_query(self, t): + def make_action_query(t): return expr("ShouldDo(action, {})".format(t)) - def make_action_sentence(self, action, t): + def make_action_sentence(action, t): return Expr("Did")(action[expr('action')], t) return program def is_symbol(s): - "A string s is a symbol if it starts with an alphabetic char." + """A string s is a symbol if it starts with an alphabetic char.""" return isinstance(s, str) and s[:1].isalpha() def is_var_symbol(s): - "A logic variable symbol is an initial-lowercase string." + """A logic variable symbol is an initial-lowercase string.""" return is_symbol(s) and s[0].islower() @@ -156,7 +155,7 @@ def variables(s): def is_definite_clause(s): - """returns True for exprs s of the form A & B & ... & C ==> D, + """Returns True for exprs s of the form A & B & ... & C ==> D, where all literals are positive. In clause form, this is ~A | ~B | ... | ~C | D, where exactly one clause is positive. >>> is_definite_clause(expr('Farmer(Mac)')) @@ -173,7 +172,7 @@ def is_definite_clause(s): def parse_definite_clause(s): - "Return the antecedents and the consequent of a definite clause." + """Return the antecedents and the consequent of a definite clause.""" assert is_definite_clause(s) if is_symbol(s.op): return [], s @@ -200,7 +199,7 @@ def tt_entails(kb, alpha): def tt_check_all(kb, alpha, symbols, model): - "Auxiliary routine to implement tt_entails." + """Auxiliary routine to implement tt_entails.""" if not symbols: if pl_true(kb, model): result = pl_true(alpha, model) @@ -215,7 +214,7 @@ def tt_check_all(kb, alpha, symbols, model): def prop_symbols(x): - "Return a list of all propositional symbols in x." + """Return a list of all propositional symbols in x.""" if not isinstance(x, Expr): return [] elif is_prop_symbol(x.op): @@ -305,7 +304,7 @@ def to_cnf(s): def eliminate_implications(s): - "Change implications into equivalent form with only &, |, and ~ as logical operators." + """Change implications into equivalent form with only &, |, and ~ as logical operators.""" s = expr(s) if not s.args or is_symbol(s.op): return s # Atoms are unchanged. @@ -433,7 +432,7 @@ def disjuncts(s): def pl_resolution(KB, alpha): - "Propositional-logic resolution: say if alpha follows from KB. [Figure 7.12]" + """Propositional-logic resolution: say if alpha follows from KB. [Figure 7.12]""" clauses = KB.clauses + conjuncts(to_cnf(~alpha)) new = set() while True: @@ -467,16 +466,15 @@ def pl_resolve(ci, cj): class PropDefiniteKB(PropKB): - - "A KB of propositional definite clauses." + """A KB of propositional definite clauses.""" def tell(self, sentence): - "Add a definite clause to this KB." + """Add a definite clause to this KB.""" assert is_definite_clause(sentence), "Must be definite clause" self.clauses.append(sentence) def ask_generator(self, query): - "Yield the empty substitution if KB implies query; else nothing." + """Yield the empty substitution if KB implies query; else nothing.""" if pl_fc_entails(self.clauses, query): yield {} @@ -542,7 +540,7 @@ def dpll_satisfiable(s): def dpll(clauses, symbols, model): - "See if the clauses are true in a partial model." + """See if the clauses are true in a partial model.""" unknown_clauses = [] # clauses with an unknown truth value for c in clauses: val = pl_true(c, model) @@ -669,7 +667,6 @@ def sat_count(sym): class HybridWumpusAgent(agents.Agent): - """An agent for the wumpus world that does logical inference. [Figure 7.20]""" def __init__(self): @@ -871,7 +868,6 @@ def standardize_variables(sentence, dic=None): class FolKB(KB): - """A knowledge base consisting of first-order definite clauses. >>> kb0 = FolKB([expr('Farmer(Mac)'), expr('Rabbit(Pete)'), ... expr('(Rabbit(r) & Farmer(f)) ==> Hates(f, r)')]) diff --git a/probability.py b/probability.py index d28a8a38b..fa856c330 100644 --- a/probability.py +++ b/probability.py @@ -16,7 +16,7 @@ def DTAgentProgram(belief_state): - "A decision-theoretic agent. [Figure 13.1]" + """A decision-theoretic agent. [Figure 13.1]""" def program(percept): belief_state.observe(program.action, percept) program.action = argmax(belief_state.actions(), @@ -29,8 +29,7 @@ def program(percept): class ProbDist: - - """A discrete probability distribution. You name the random variable + """A discrete probability distribution. You name the random variable in the constructor, then assign and query probability of values. >>> P = ProbDist('Flip'); P['H'], P['T'] = 0.25, 0.75; P['H'] 0.25 @@ -40,8 +39,8 @@ class ProbDist: """ def __init__(self, varname='?', freqs=None): - """If freqs is given, it is a dictionary of value: frequency pairs, - and the ProbDist then is normalized.""" + """If freqs is given, it is a dictionary of values - frequency pairs, + then ProbDist is normalized.""" self.prob = {} self.varname = varname self.values = [] @@ -51,14 +50,14 @@ def __init__(self, varname='?', freqs=None): self.normalize() def __getitem__(self, val): - "Given a value, return P(value)." + """Given a value, return P(value).""" try: return self.prob[val] except KeyError: return 0 def __setitem__(self, val, p): - "Set P(val) = p." + """Set P(val) = p.""" if val not in self.values: self.values.append(val) self.prob[val] = p @@ -98,7 +97,7 @@ def __init__(self, variables): self.vals = defaultdict(list) def __getitem__(self, values): - "Given a tuple or dict of values, return P(values)." + """Given a tuple or dict of values, return P(values).""" values = event_values(values, self.variables) return ProbDist.__getitem__(self, values) @@ -113,7 +112,7 @@ def __setitem__(self, values, p): self.vals[var].append(val) def values(self, var): - "Return the set of possible values for a variable." + """Return the set of possible values for a variable.""" return self.vals[var] def __repr__(self): @@ -164,11 +163,10 @@ def enumerate_joint(variables, e, P): class BayesNet: - - "Bayesian network containing only boolean-variable nodes." + """Bayesian network containing only boolean-variable nodes.""" def __init__(self, node_specs=[]): - "nodes must be ordered with parents before children." + """Nodes must be ordered with parents before children.""" self.nodes = [] self.variables = [] for node_spec in node_specs: @@ -195,7 +193,7 @@ def variable_node(self, var): raise Exception("No such variable: {}".format(var)) def variable_values(self, var): - "Return the domain of var." + """Return the domain of var.""" return [True, False] def __repr__(self): @@ -203,7 +201,6 @@ def __repr__(self): class BayesNode: - """A conditional probability distribution for a boolean variable, P(X | parents). Part of a BayesNet.""" @@ -337,7 +334,7 @@ def elimination_ask(X, e, bn): def is_hidden(var, X, e): - "Is var a hidden variable when querying P(X|e)?" + """Is var a hidden variable when querying P(X|e)?""" return var != X and var not in e @@ -366,7 +363,6 @@ def sum_out(var, factors, bn): class Factor: - """A factor in a joint distribution.""" def __init__(self, variables, cpt): @@ -526,7 +522,6 @@ def markov_blanket_sample(X, e, bn): class HiddenMarkovModel: - """A Hidden markov model which takes Transition model and Sensor model as inputs""" def __init__(self, transition_model, sensor_model, prior=[0.5, 0.5]): @@ -605,7 +600,7 @@ def fixed_lag_smoothing(e_t, HMM, d, ev, t): B = matrix_multiplication(inverse_matrix(O_tmd), inverse_matrix(T_model), B, T_model, O_t) else: B = matrix_multiplication(B, T_model, O_t) - t = t + 1 + t += 1 if t > d: # always returns a 1x2 matrix @@ -618,18 +613,15 @@ def fixed_lag_smoothing(e_t, HMM, d, ev, t): def particle_filtering(e, N, HMM): """Particle filtering considering two states variables.""" - s = [] dist = [0.5, 0.5] - # State Initialization - s = ['A' if probability(dist[0]) else 'B' for i in range(N)] # Weight Initialization - w = [0 for i in range(N)] + w = [0 for _ in range(N)] # STEP 1 # Propagate one step using transition model given prior state dist = vector_add(scalar_vector_product(dist[0], HMM.transition_model[0]), scalar_vector_product(dist[1], HMM.transition_model[1])) # Assign state according to probability - s = ['A' if probability(dist[0]) else 'B' for i in range(N)] + s = ['A' if probability(dist[0]) else 'B' for _ in range(N)] w_tot = 0 # Calculate importance weight given evidence e for i in range(N):