<commit_before>from Module import Module
from Location import Location
import datetime

class Project():
    def __init__(self, name, method, budget, revenue_tier):
        self.name = name
        self.development_method = method
        self.delivery_date = None
        self.budget = budget
        self.cash = budget
        self.expected_yearly_revenue = revenue_tier.expected_yearly_profits()
        self.modules = list()
        self.locations = list()
        self.start_time = datetime.datetime(2014,1,1,0,0,0)
        self.current_time = datetime.datetime(2014,1,1,0,0,0)

    def home_site(self, site):
        self.home_site = site

    def calc_nominal_schedule(self, dev_effort_val):
        if self.development_method == 'Agile':
            max_team_cost = 0
            for location in self.locations:
                for team in location.teams:
                    team_cost = 0
                    for module in team.modules:
                        team_cost += module.expected_cost/team.size
                    if team_cost > max_team_cost:
                        max_team_cost = team_cost
            nominal_schedule = max_team_cost / dev_effort_val
            self.delivery_date = self.start_time + datetime.timedelta(days=nominal_schedule/8)

    def months_behind_schedule(self):
        # Returns a number of days late, divide by 30 to get number of months late
        delta = self.delivery_date - self.start_time
        days_late = delta.days
        num_months_late = days_late/30
        return num_months_late

    def game_score(self):
        num_months_late = self.months_behind_schedule()
        score = self.cash + ((6 - num_months_late) * (self.expected_yearly_revenue / 12))
        return score

    # From email:
    # expected_budget =
    #  [sum(module estimated effort) /  (avg_developer_effort_day * num_developers)] * 1.24
    # NOTE: IMPORTANT - This calculation doesn't take into account developer wages
    # An adjustment was made below to account for this, rounding up a day.
    def expected_budget(self, developer_effort_day):
        total_module_effort = 0
        total_daily_cost = 0  # in $CURRENCY
        for module in self.modules:
            total_module_effort += module.expected_cost
        num_developers = 0
        for location in self.locations:
            num_developers += location.current_size
            total_daily_cost += (location.salary * 8 * location.current_size)
        total_effort_hours = ((float(total_module_effort) / (float(developer_effort_day) * float(num_developers)) * 1.24))
        total_effort_days = (total_effort_hours/8) + 1
        return (float(total_effort_days) * float(total_daily_cost))

    def actual_budget(self):
        return self.budget

    # From e-mail:
    # expected_revenue = expected_early_revenue / 2
    def expected_revenue(self):
        return self.expected_yearly_revenue / 2

    def actual_revenue(self):
        num_months_late = self.months_behind_schedule()
        actual_revenue = (6 - num_months_late) * (self.expected_yearly_revenue / 12)
        return actual_revenue
<commit_msg>Made budget calculation more accurate with productive developer hours<commit_after>from Module import Module
from Location import Location
import datetime

class Project():
    def __init__(self, name, method, budget, revenue_tier):
        self.name = name
        self.development_method = method
        self.delivery_date = None
        self.budget = budget
        self.cash = budget
        self.expected_yearly_revenue = revenue_tier.expected_yearly_profits()
        self.modules = list()
        self.locations = list()
        self.start_time = datetime.datetime(2014,1,1,0,0,0)
        self.current_time = datetime.datetime(2014,1,1,0,0,0)

    def home_site(self, site):
        self.home_site = site

    def calc_nominal_schedule(self, dev_effort_val):
        if self.development_method == 'Agile':
            max_team_cost = 0
            for location in self.locations:
                for team in location.teams:
                    team_cost = 0
                    for module in team.modules:
                        team_cost += module.expected_cost/team.size
                    if team_cost > max_team_cost:
                        max_team_cost = team_cost
            nominal_schedule = max_team_cost / dev_effort_val
            self.delivery_date = self.start_time + datetime.timedelta(days=nominal_schedule/8)

    def months_behind_schedule(self):
        # Returns a number of days late, divide by 30 to get number of months late
        delta = self.delivery_date - self.start_time
        days_late = delta.days
        num_months_late = days_late/30
        return num_months_late

    def game_score(self):
        num_months_late = self.months_behind_schedule()
        score = self.cash + ((6 - num_months_late) * (self.expected_yearly_revenue / 12))
        return score

    # From email:
    # expected_budget =
    #  [sum(module estimated effort) /  (avg_developer_effort_day * num_developers)] * 1.24
    # NOTE: IMPORTANT - This calculation doesn't take into account developer wages
    # An adjustment was made below to account for this, rounding up a day.
    def expected_budget(self, developer_effort_day):
        total_module_effort = 0
        total_daily_cost = 0  # in $CURRENCY
        for module in self.modules:
            total_module_effort += module.expected_cost
        num_developers = 0
        for location in self.locations:
            num_developers += location.current_size
            total_daily_cost += (location.salary * developer_effort_day * location.current_size)
        total_effort_hours = ((float(total_module_effort) / (float(developer_effort_day) * float(num_developers)) * 1.24))
        total_effort_days = (total_effort_hours/8) + 1
        return (float(total_effort_days) * float(total_daily_cost))

    def actual_budget(self):
        return self.budget

    # From e-mail:
    # expected_revenue = expected_early_revenue / 2
    def expected_revenue(self):
        return self.expected_yearly_revenue / 2

    def actual_revenue(self):
        num_months_late = self.months_behind_schedule()
        actual_revenue = (6 - num_months_late) * (self.expected_yearly_revenue / 12)
        return actual_revenue
<|endoftext|>


<commit_before>import numpy as np
import time

import easyexplot as eep

def my_experiment(x, f='sin', shift=False, seed=None):
    """
    A simple example for an experiment function with seed.
    """

    # initialize RNG with given seed
    print 'got seed:', seed
    np.random.seed(seed)

    # simulate heavy computation
    time.sleep(1)

    # invent some results
    if f == 'sin':
        result_value = np.sin(x)
    elif f == 'cos':
        result_value = np.cos(x)
    else:
        result_value = 0
    if shift:
        result_value += .3
    result_value += .5 * np.random.randn()
    return result_value

def main():
    """
    Calls a computationally expensive experiment and caches the results. If you
    call it a second time, you should see the plot instantly.
    """
    seed = 0
    repetitions = 3
    cachedir = '/tmp'

    # plot varying 'x' and cache the results
    eep.plot(my_experiment,
             x=range(10),
             seed=seed,
             repetitions=repetitions,
             cachedir=cachedir)
    return

if __name__ == '__main__':
    main()
<commit_msg>simplified example<commit_after>import numpy as np
import time

import easyexplot as eep

def my_experiment(x, seed=None):
    """
    A simple example for an experiment function with seed.
    """

    # initialize RNG with given seed
    print 'got seed:', seed
    np.random.seed(seed)

    # simulate heavy computation
    time.sleep(1)

    # invent some results
    return np.sin(x) + .5 * np.random.randn()

def main():
    """
    Calls a computationally expensive experiment and caches the results. If you
    call it a second time, you should see the plot instantly.
    """
    seed = 0
    repetitions = 3
    cachedir = '/tmp'

    # plot varying 'x' and cache the results
    eep.plot(my_experiment,
             x=range(10),
             seed=seed,
             repetitions=repetitions,
             cachedir=cachedir)
    return

if __name__ == '__main__':
    main()
<|endoftext|>


<commit_before>from ConfigParser import ConfigParser
import os

from pymachine.utils import MachineGraph
def ensure_dir(path):
    if not os.path.exists(path):
        os.mkdir(path)

def batches(l, n):
    """ Yield successive n-sized chunks from l.
    (source: http://stackoverflow.com/questions/312443/
    how-do-you-split-a-list-into-evenly-sized-chunks-in-python
    """
    for i in xrange(0, len(l), n):
        yield l[i:i+n]

def print_4lang_graphs(words_to_machines, graph_dir):
    for word, machine in words_to_machines.iteritems():
        print_4lang_graph(word, machine, graph_dir)

def print_4lang_graph(word, machine, graph_dir):
    graph = MachineGraph.create_from_machines([machine])
    fn = os.path.join(graph_dir, u"{0}.dot".format(word))
    with open(fn, 'w') as dot_obj:
        dot_obj.write(graph.to_dot().encode('utf-8'))

def get_cfg(cfg_file=None):
    cfg_files = ['conf/default.cfg']
    if cfg_file is not None:
        cfg_files.append(cfg_file)
    cfg = ConfigParser()
    cfg.read(cfg_files)
    return cfg
<commit_msg>utils.ensure_dir now uses os.makedirs and will create directories recursively 	modified:   src/fourlang/utils.py<commit_after>from ConfigParser import ConfigParser
import os

from pymachine.utils import MachineGraph
def ensure_dir(path):
    if not os.path.exists(path):
        os.makedirs(path)

def batches(l, n):
    """ Yield successive n-sized chunks from l.
    (source: http://stackoverflow.com/questions/312443/
    how-do-you-split-a-list-into-evenly-sized-chunks-in-python
    """
    for i in xrange(0, len(l), n):
        yield l[i:i+n]

def print_4lang_graphs(words_to_machines, graph_dir):
    for word, machine in words_to_machines.iteritems():
        print_4lang_graph(word, machine, graph_dir)

def print_4lang_graph(word, machine, graph_dir):
    graph = MachineGraph.create_from_machines([machine])
    fn = os.path.join(graph_dir, u"{0}.dot".format(word))
    with open(fn, 'w') as dot_obj:
        dot_obj.write(graph.to_dot().encode('utf-8'))

def get_cfg(cfg_file=None):
    cfg_files = ['conf/default.cfg']
    if cfg_file is not None:
        cfg_files.append(cfg_file)
    cfg = ConfigParser()
    cfg.read(cfg_files)
    return cfg
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-

import numpy as np
from matplotlib import pyplot as plt

COLORS = plt.cm.YlGn(np.arange(5)/5.)

def heatmap(values, xlabels, ylabels, size=(12, 1.35)):
    fig, ax = plt.subplots()
    plt.axis('equal')
    ax.pcolormesh(values, cmap=plt.cm.YlGn)
    fig.set_size_inches(*size)

    ax.set_frame_on(False)

    ax.set_xticks(np.arange(values.shape[1])+0.5, minor=False)
    ax.set_yticks(np.arange(values.shape[0])+0.5, minor=False)

    ax.invert_yaxis()
    ax.xaxis.tick_top()
    ax.yaxis.tick_left()
    ax.grid(False)

    ax.set_xticklabels(xlabels, minor=False, size=8)
    ax.set_yticklabels(ylabels, minor=False, size=8)
    for i, label in enumerate(ax.xaxis.get_ticklabels()):
        if i % 5 == 0:
            label.set_visible(True)
        else:
            label.set_visible(False)

def pie(labels, values, title=None):
    plt.axis("equal")

    if title is not None:
        plt.title(title)

    plt.pie(values, labels=labels, colors=COLORS, autopct='%1.1f%%', labeldistance=1.1)

def changebars(labels, inserts, deletes):
    plt.axis("tight")
    plt.figure()
    ax = plt.subplot(111)
    ticks = range(len(labels))
    ax.bar(ticks, deletes, width=1, color='crimson')
    ax.bar(ticks, inserts, width=1, color='darkblue')
    plt.xticks([t+0.5 for t in ticks], labels)
<commit_msg>Colorbar for the activity heatmap<commit_after># -*- coding: utf-8 -*-

import numpy as np
from matplotlib import pyplot as plt

COLORS = plt.cm.YlGn(np.arange(5)/5.)

def heatmap(values, xlabels, ylabels, size=(12, 1.35)):
    fig, ax = plt.subplots()
    plt.axis('equal')
    heatmap = ax.pcolormesh(values, cmap=plt.cm.YlGn)
    plt.colorbar(heatmap, ticks=range(int(values.max().round())+1))
    fig.set_size_inches(*size)

    ax.set_frame_on(False)

    ax.set_xticks(np.arange(values.shape[1])+0.5, minor=False)
    ax.set_yticks(np.arange(values.shape[0])+0.5, minor=False)

    ax.invert_yaxis()
    ax.xaxis.tick_top()
    ax.yaxis.tick_left()
    ax.grid(False)

    ax.set_xticklabels(xlabels, minor=False, size=8)
    ax.set_yticklabels(ylabels, minor=False, size=8)
    for i, label in enumerate(ax.xaxis.get_ticklabels()):
        if i % 5 == 0:
            label.set_visible(True)
        else:
            label.set_visible(False)

def pie(labels, values, title=None):
    plt.axis("equal")

    if title is not None:
        plt.title(title)

    plt.pie(values, labels=labels, colors=COLORS, autopct='%1.1f%%', labeldistance=1.1)

def changebars(labels, inserts, deletes):
    plt.axis("tight")
    plt.figure()
    ax = plt.subplot(111)
    ticks = range(len(labels))
    ax.bar(ticks, deletes, width=1, color='crimson')
    ax.bar(ticks, inserts, width=1, color='darkblue')
    plt.xticks([t+0.5 for t in ticks], labels)
<|endoftext|>


<commit_before>'''
Created on Oct 2, 2010
ULB Gehol to CSV calendar converter
@author: epd
'''
import argparse
import urllib
from BeautifulSoup import BeautifulSoup
import re
import csv, codecs, cStringIO
from datetime import datetime, timedelta

def get_html(host,mnemo):
    '''get the html page from the web'''
    try:
        params = urllib.urlencode({'template': 'cours', 'weeks': '1-31', 'days': '1-6', 'periods':'5-29', 'width':0,'height':0})
        url = '%s/Reporting/Individual;Courses;name;%s?%s'%(host,mnemo,params)
        f = urllib.urlopen(url)
        return f.read()
    except:
        raise ValueError('Could not get html')

def split_weeks(weeks):
    '''split string containing weeks info into separated fields
    e.g. "1,5-7"  ---> [1,5,6,7]'''
    s = weeks.split(',')
    w = []
    for f in s:
        sf = f.split('-')
        if len(sf)>1:
            w.extend(range(int(sf[0]),int(sf[1])+1))
        else:
            w.append(int(f))
    return w

def parse_header(html):
    '''parse html page to find global informations'''
    try:
        soup = BeautifulSoup(html)
        #process names ...
        bTag = soup.find('td',text=re.compile('Horaire'))
        head = {}
        head['mnemo'] = bTag.split(':')[1].split('-')[0].lstrip()
        head['title'] = bTag.split(':')[1].split('-')[1].lstrip()
        bTag = soup.find('td',text=re.compile('Titulaire'))
        head['tutor'] = bTag.split(':')[1].lstrip()
        return head
    except:
        raise ValueError('Could not parse html')

def convert_time(s):
    '''convert string time into datetime struct'''
    d = datetime.strptime(s,"%H:%M")
    return d

def parse_table(html):
    '''parse html page and process the calendar table
    intermediate python structure (event list) is returned'''
    soup = BeautifulSoup(html)
    tables = soup.html.body.findAll(name='table',recursive=False)
    #jump to the calendar table
    cal = tables[1]
    lines = cal.findAll(name='tr',recursive=False)
    #isolate first tab line with hours
    hours_line = lines[0].findAll(name='td',recursive=False)
    hours = []
    for h in hours_line[1:]:
        hours.append(convert_time(h.string))
    #process all lines
    #search the number of row for that day
    n_rows = []
    for (no_line,line) in enumerate(lines[1:]):
        slots = line.findAll(name='td',recursive=False)
        #search the number of row for that day
        if slots[0].has_key('rowspan'):
            n_rows.append(int(slots[0]['rowspan']))
        else:
            n_rows.append(0)
    event_list = []
    day = -1
    n = 0
    for (no_line,line) in enumerate(lines[1:]):
        if n==0:
            n = n_rows[no_line]
            day = day + 1
            current_time = -1
        else:
            current_time = 0
        n = n-1
        slots = line.findAll(name='td',recursive=False)
        for s in slots:
            cell = s.findAll(name='table',recursive=False)
            # event found
            if len(cell)>1:
                event = {}
                event['no_line'] = no_line
                event['day'] = day
                event['start'] = hours[current_time]
                #duration in hours is extract from the colspan
                event['duration'] = int(s['colspan'])
                #compute end time (1 colspan=1/2 hour)
                delta = timedelta(hours=event['duration']/2)
                event['end'] = hours[current_time]+delta
                td = cell[0].tr.findAll(name='td',recursive=False)
                # Gehol weeks when the event occurs
                event['weeks'] = split_weeks(td[0].contents[0].string)
                # location
                event['location'] = td[1].contents[0].string
                if event['location'] is None:
                    event['location'] = ''
                # activity
                event['type'] = cell[1].tr.td.contents[0].string
                current_time = current_time + event['duration']
                event_list.append(event)
            else:
                current_time = current_time + 1
    #now event are ready for export
    return event_list

class UnicodeWriter:
    """
    A CSV writer which will write rows to CSV file "f",
    which is encoded in the given encoding.
    """

    def __init__(self, f, dialect=csv.excel, encoding="utf-8", **kwds):
        # Redirect output to a queue
        self.queue = cStringIO.StringIO()
        self.writer = csv.writer(self.queue, dialect=dialect, **kwds)
        self.stream = f
        self.encoder = codecs.getincrementalencoder(encoding)()

    def writerow(self, row):
        self.writer.writerow([s.encode("utf-8") for s in row])
        # Fetch UTF-8 output from the queue ...
        data = self.queue.getvalue()
        data = data.decode("utf-8")
        # ... and reencode it into the target encoding
        data = self.encoder.encode(data)
        # write to the target stream
        self.stream.write(data)
        # empty queue
        self.queue.truncate(0)

    def writerows(self, rows):
        for row in rows:
            self.writerow(row)

def export_csv(head,events,filename,first_monday):
    '''export events into csv format
    the file is saved under filename .csv extension must be provided
    Google calendar import format:
    Subject,Start Date,Start Time,End Date,End Time,All Day Event,Description,Location,Private
    Final Exam,05/12/08,07:10:00 PM,05/12/08,10:00:00 PM,False,Two essay questions that will cover topics covered throughout the semester,"Columbia, Schermerhorn 614",True
    first_monday corresponds to the monday date of week 1 in Gehol
    '''
    date_init = datetime.strptime(first_monday,'%d/%m/%Y')
    writer = UnicodeWriter(open(filename, 'w'), delimiter=',',quotechar='"', quoting=csv.QUOTE_NONNUMERIC)
    #write header line see google help http://www.google.com/support/calendar/bin/answer.py?answer=45656
    writer.writerow(['Subject','Start Date','Start Time','End Date','End Time','All Day Event','Description','Location','Private'])
    for event in events:
        n = len(event['weeks'])
        for (i,sub) in enumerate(event['weeks']):
            subject = '%s%s (%d/%d)'%(head['mnemo'],event['type'],i+1,n)
            #add offset corresponding to week numbers for each event repetition
            delta = timedelta(days=(sub-1)*7+(event['day']))
            start_date = (date_init+delta).strftime("%d/%m/%y")
            start_time = event['start'].strftime("%I:%M:%S %p")
            end_date = start_date
            end_time = event['end'].strftime("%I:%M:%S %p")
            all_day_event = 'False'
            description = head['title']+' titulaire : '+ head['tutor']
            location = event['location']
            private = 'False'
            writer.writerow([subject,start_date,start_time,end_date,end_time,
                         all_day_event,description,location,private])

def test():
    '''test import function for a mnemonic list'''
    print 'import calendar test --> csv files'
    mnemo = ['INFOH500','BIMEH404','STATH400']
    host = 'http://164.15.72.157:8080'
    first_monday = '20/09/2010'

    for m in mnemo:
        dest_filename = 'agenda_%s.csv'%m
        process(m, host, first_monday, dest_filename)
        print dest_filename

def process(mnemo,host,first_monday,dest_filename):
    html = get_html(host,mnemo)
    head = parse_header(html)
    events = parse_table(html)
    export_csv(head, events, dest_filename,first_monday)

if __name__ == '__main__':
    '''Import calendar directly from the ULB webserver and convert the calendar
    into a CVS file compatible with google calendar
    this version is used only with the "by course" calendars
    '''
    parser = argparse.ArgumentParser(description='Fetch Gehol calendar from the ULB web page and generate a csv file compatible with google calendar.',
                                     epilog="THIS PROGRAM IS GIVEN AS THIS WITHOUT ANY GARANTEE")
    #positional argument
    parser.add_argument('mnemo', nargs='?', default=None)
    #optional arguments
    parser.add_argument('-s','--server', required=False, help='server address [http://164.15.72.157:8080]',default = 'http://164.15.72.157:8080')
    parser.add_argument('-d', required=False, help='Monday date of the week 1 [20/09/2010]',default = '20/09/2010')
    parser.add_argument('-t','--test', required=False, action='store_true',help='test the program on some courses',default = False)

    args = parser.parse_args()
    if args.test:
        test()
    else:
        if args.mnemo is None:
            parser.print_help()
        else:
            dest_filename = 'agenda_%s.csv'%args.mnemo
            try:
                process(args.mnemo, args.server, args.d, dest_filename)
            except Exception as inst:
                print 'problem encountered with \n%s\nNothing saved.\n'%args
                print type(inst)     # the exception instance
                print inst.args      # arguments stored in .args
                print inst           # __str__ allows args to printed directly
            else:
                print '%s saved\n'%dest_filename            <commit_msg>parse html for student version by setting default values<commit_after>'''
Created on Oct 2, 2010
ULB Gehol to CSV calendar converter
@author: epd
'''
import argparse
import urllib
from BeautifulSoup import BeautifulSoup
import re
import csv, codecs, cStringIO
from datetime import datetime, timedelta

def get_html(host,mnemo):
    '''get the html page from the web'''
    try:
        params = urllib.urlencode({'template': 'cours', 'weeks': '1-31', 'days': '1-6', 'periods':'5-29', 'width':0,'height':0})
        url = '%s/Reporting/Individual;Courses;name;%s?%s'%(host,mnemo,params)
        f = urllib.urlopen(url)
        return f.read()
    except:
        raise ValueError('Could not get html')

def get_html_by_url(url):
    '''get the html page from the web for a specific student'''
    try:
        f = urllib.urlopen(url)
        return f.read()
    except:
        raise ValueError('Could not get html')

def split_weeks(weeks):
    '''split string containing weeks info into separated fields
    e.g. "1,5-7"  ---> [1,5,6,7]'''
    s = weeks.split(',')
    w = []
    for f in s:
        sf = f.split('-')
        if len(sf)>1:
            w.extend(range(int(sf[0]),int(sf[1])+1))
        else:
            w.append(int(f))
    return w

def parse_header(html):
    '''parse html page to find global informations'''
    #try individual course
    try:
        soup = BeautifulSoup(html)
        #process names ...
        bTag = soup.find('td',text=re.compile('Horaire'))
        head = {}
        head['mnemo'] = bTag.split(':')[1].split('-')[0].lstrip()
        head['title'] = bTag.split(':')[1].split('-')[1].lstrip()
        bTag = soup.find('td',text=re.compile('Titulaire'))
        head['tutor'] = bTag.split(':')[1].lstrip()
        head['type'] = 'course'
        return head
    except:
        #try idividual student
        head = {}
        head['mnemo'] = ''
        head['title'] = ''
        head['tutor'] = ''
        head['type'] = 'student'
        return head

def convert_time(s):
    '''convert string time into datetime struct'''
    d = datetime.strptime(s,"%H:%M")
    return d

def parse_table(html):
    '''parse html page and process the calendar table
    intermediate python structure (event list) is returned'''
    soup = BeautifulSoup(html)
    tables = soup.html.body.findAll(name='table',recursive=False)
    #jump to the calendar table
    cal = tables[1]
    lines = cal.findAll(name='tr',recursive=False)
    #isolate first tab line with hours
    hours_line = lines[0].findAll(name='td',recursive=False)
    hours = []
    for h in hours_line[1:]:
        hours.append(convert_time(h.string))
    #process all lines
    #search the number of row for that day
    n_rows = []
    for (no_line,line) in enumerate(lines[1:]):
        slots = line.findAll(name='td',recursive=False)
        #search the number of row for that day
        if slots[0].has_key('rowspan'):
            n_rows.append(int(slots[0]['rowspan']))
        else:
            n_rows.append(0)
    event_list = []
    day = -1
    n = 0
    for (no_line,line) in enumerate(lines[1:]):
        if n==0:
            n = n_rows[no_line]
            day = day + 1
            current_time = -1
        else:
            current_time = 0
        n = n-1
        slots = line.findAll(name='td',recursive=False)
        for s in slots:
            cell = s.findAll(name='table',recursive=False)
            # event found
            if len(cell)>1:
                event = {}
                event['no_line'] = no_line
                event['day'] = day
                event['start'] = hours[current_time]
                #duration in hours is extract from the colspan
                event['duration'] = int(s['colspan'])
                #compute end time (1 colspan=1/2 hour)
                delta = timedelta(hours=event['duration']/2)
                event['end'] = hours[current_time]+delta
                td = cell[0].tr.findAll(name='td',recursive=False)
                # Gehol weeks when the event occurs
                event['weeks'] = split_weeks(td[0].contents[0].string)
                # location
                event['location'] = td[1].contents[0].string
                if event['location'] is None:
                    event['location'] = ''
                # activity
                event['type'] = cell[1].tr.td.contents[0].string
                current_time = current_time + event['duration']
                event_list.append(event)
            else:
                current_time = current_time + 1
    #now event are ready for export
    return event_list

class UnicodeWriter:
    """
    A CSV writer which will write rows to CSV file "f",
    which is encoded in the given encoding.
    """

    def __init__(self, f, dialect=csv.excel, encoding="utf-8", **kwds):
        # Redirect output to a queue
        self.queue = cStringIO.StringIO()
        self.writer = csv.writer(self.queue, dialect=dialect, **kwds)
        self.stream = f
        self.encoder = codecs.getincrementalencoder(encoding)()

    def writerow(self, row):
        self.writer.writerow([s.encode("utf-8") for s in row])
        # Fetch UTF-8 output from the queue ...
        data = self.queue.getvalue()
        data = data.decode("utf-8")
        # ... and reencode it into the target encoding
        data = self.encoder.encode(data)
        # write to the target stream
        self.stream.write(data)
        # empty queue
        self.queue.truncate(0)

    def writerows(self, rows):
        for row in rows:
            self.writerow(row)

def export_csv(head,events,filename,first_monday):
    '''export events into csv format
    the file is saved under filename .csv extension must be provided
    Google calendar import format:
    Subject,Start Date,Start Time,End Date,End Time,All Day Event,Description,Location,Private
    Final Exam,05/12/08,07:10:00 PM,05/12/08,10:00:00 PM,False,Two essay questions that will cover topics covered throughout the semester,"Columbia, Schermerhorn 614",True
    first_monday corresponds to the monday date of week 1 in Gehol
    '''
    date_init = datetime.strptime(first_monday,'%d/%m/%Y')
    writer = UnicodeWriter(open(filename, 'w'), delimiter=',',quotechar='"', quoting=csv.QUOTE_NONNUMERIC)
    #write header line see google help http://www.google.com/support/calendar/bin/answer.py?answer=45656
    writer.writerow(['Subject','Start Date','Start Time','End Date','End Time','All Day Event','Description','Location','Private'])
    for event in events:
        n = len(event['weeks'])
        for (i,sub) in enumerate(event['weeks']):
            subject = '%s%s (%d/%d)'%(head['mnemo'],event['type'],i+1,n)
            #add offset corresponding to week numbers for each event repetition
            delta = timedelta(days=(sub-1)*7+(event['day']))
            start_date = (date_init+delta).strftime("%d/%m/%y")
            start_time = event['start'].strftime("%I:%M:%S %p")
            end_date = start_date
            end_time = event['end'].strftime("%I:%M:%S %p")
            all_day_event = 'False'
            description = head['title']+' titulaire : '+ head['tutor']
            location = event['location']
            private = 'False'
            writer.writerow([subject,start_date,start_time,end_date,end_time,
                         all_day_event,description,location,private])

def test():
    '''test import function for a mnemonic list'''
    print 'import calendar test --> csv files'
    mnemo = ['INFOH500','BIMEH404','STATH400']
    host = 'http://164.15.72.157:8080'
    first_monday = '20/09/2010'

    for m in mnemo:
        dest_filename = 'agenda_%s.csv'%m
        process(m, host, first_monday, dest_filename)
        print dest_filename

    #test by url
    url = 'http://164.15.72.157:8080/Reporting/Individual;Student%20Set%20Groups;id;%23SPLUSA629A0?&template=Ann%E9e%20d%27%E9tude&weeks=1-14&days=1-6&periods=5-33&width=0&height=0'
    dest_filename = 'import_by_url.csv'
    process_by_url(url, first_monday, dest_filename)

def process(mnemo,host,first_monday,dest_filename):
    html = get_html(host,mnemo)
    head = parse_header(html)
    events = parse_table(html)
    export_csv(head, events, dest_filename,first_monday)

def process_by_url(url,first_monday,dest_filename):
    html = get_html_by_url(url)
    head = parse_header(html)
    events = parse_table(html)
    export_csv(head, events, dest_filename,first_monday)

if __name__ == '__main__':
    '''Import calendar directly from the ULB webserver and convert the calendar
    into a CVS file compatible with google calendar
    this version is used only with the "by course" calendars
    '''
    parser = argparse.ArgumentParser(description='Fetch Gehol calendar from the ULB web page and generate a csv file compatible with google calendar.',
                                     epilog="THIS PROGRAM IS GIVEN AS THIS WITHOUT ANY GARANTEE")
    #positional argument
    parser.add_argument('mnemo', nargs='?', default=None)
    #optional arguments
    parser.add_argument('-s','--server', required=False, help='server address [http://164.15.72.157:8080]',default = 'http://164.15.72.157:8080')
    parser.add_argument('-d', required=False, help='Monday date of the week 1 [20/09/2010]',default = '20/09/2010')
    parser.add_argument('-t','--test', required=False, action='store_true',help='test the program on some courses',default = False)

    args = parser.parse_args()
    if args.test:
        test()
    else:
        if args.mnemo is None:
            parser.print_help()
        else:
            dest_filename = 'agenda_%s.csv'%args.mnemo
            try:
                process(args.mnemo, args.server, args.d, dest_filename)
            except Exception as inst:
                print 'problem encountered with \n%s\nNothing saved.\n'%args
                print type(inst)     # the exception instance
                print inst.args      # arguments stored in .args
                print inst           # __str__ allows args to printed directly
            else:
                print '%s saved\n'%dest_filename            <|endoftext|>


<commit_before>
import LIMS2DB.objectsDB.objectsDB as DB
import pprint

from LIMS2DB.classes import ProjectSQL
from genologics.config import BASEURI, USERNAME, PASSWORD
from genologics.lims import Lims
from LIMS2DB.utils import setupLog
from genologics_sql.utils import *

def diff_project_objects(pj_id, couch, logfile, new=True):

    proj_db = couch['projects']
    samp_db = couch['samples']
    log = setupLog('diff - {}'.format(pj_id), logfile)
    lims = Lims(BASEURI, USERNAME, PASSWORD)

    view = proj_db.view('projects/lims_followed')

    try:
        old_project_couchid = view[pj_id].rows[0].value
    except KeyError, IndexError:
        log.error("No such project {}".format(pj_id))

    old_project = proj_db.get(old_project_couchid)
    old_project.pop('_id', None)
    old_project.pop('_rev', None)
    old_project.pop('modification_time', None)
    old_project.pop('creation_time', None)

    try:
        if new:
            session=get_session()
            host=get_configuration()['url']
            new_project=ProjectSQL(session, log, pj_id, host)
        else:
            new_project = DB.ProjectDB(lims, pj_id, samp_db, log)
    except:
        return {}

    fediff=diff_objects(old_project, new_project.obj)

    return fediff

def diff_objects(o1, o2, parent=''):
    diffs={}

    for key in o1:
        if key in o2:
            if isinstance(o1[key], dict):
                more_diffs=diff_objects(o1[key], o2[key], "{} {}".format(parent,key))
                diffs.update(more_diffs)

            else:
                if o1[key]!= o2[key]:
                    diffs["{} {}".format(parent, key)]=[o1[key], o2[key]]

        else:
            if o1[key]:
                diffs["key {} {}".format(parent, key)]=[o1[key], "missing"]

    for key in o2:
        if key not in o1 and o2[key]:
            diffs["key {} {}".format(parent, key)]=["missing", o2[key]]

    return diffs

if __name__ == "__main__":

    a={'a' : 1, 'b': 2, 'c':{'d':3, 'e':{'f':5}}}
    b={'a' : 1, 'b': 7, 'c':{'d':4, 'e':{'f':4}}}
    diffs=diff_objects(a,b)
    print diffs
<commit_msg>allowing diffs for old and new methods<commit_after>
from genologics.config import BASEURI, USERNAME, PASSWORD
from genologics.lims import Lims
from LIMS2DB.utils import setupLog
from genologics_sql.utils import *

def diff_project_objects(pj_id, couch, logfile, new=True):

    proj_db = couch['projects']
    samp_db = couch['samples']
    log = setupLog('diff - {}'.format(pj_id), logfile)
    lims = Lims(BASEURI, USERNAME, PASSWORD)

    view = proj_db.view('projects/lims_followed')

    try:
        old_project_couchid = view[pj_id].rows[0].value
    except KeyError, IndexError:
        log.error("No such project {}".format(pj_id))

    old_project = proj_db.get(old_project_couchid)
    old_project.pop('_id', None)
    old_project.pop('_rev', None)
    old_project.pop('modification_time', None)
    old_project.pop('creation_time', None)

    if new:
        from LIMS2DB.classes import ProjectSQL
        session=get_session()
        host=get_configuration()['url']
        new_project=ProjectSQL(session, log, pj_id, host, couch)
    else:
        import LIMS2DB.objectsDB.objectsDB as DB
        new_project = DB.ProjectDB(lims, pj_id, samp_db, log)

    fediff=diff_objects(old_project, new_project.obj)

    return (fediff, old_project, new_project.obj)

def diff_objects(o1, o2, parent=''):
    diffs={}

    for key in o1:
        if key in o2:
            if isinstance(o1[key], dict):
                more_diffs=diff_objects(o1[key], o2[key], "{} {}".format(parent,key))
                diffs.update(more_diffs)

            else:
                if o1[key]!= o2[key]:
                    diffs["{} {}".format(parent, key)]=[o1[key], o2[key]]

        else:
            if o1[key]:
                diffs["key {} {}".format(parent, key)]=[o1[key], "missing"]

    for key in o2:
        if key not in o1 and o2[key]:
            diffs["key {} {}".format(parent, key)]=["missing", o2[key]]

    return diffs

if __name__ == "__main__":

    a={'a' : 1, 'b': 2, 'c':{'d':3, 'e':{'f':5}}}
    b={'a' : 1, 'b': 7, 'c':{'d':4, 'e':{'f':4}}}
    diffs=diff_objects(a,b)
    print diffs
<|endoftext|>


<commit_before>#try:
    #import gui_thread
#except:
    #print "Warning:  wxPython not loaded"

from scipy_version import scipy_version as __version__

# SciPy has levels
# Level 0 -- Numeric and core routines in scipy_base
#
# Level 1 -- Level 0 + fft, special, linalg, stats
# Level 1a -- Core routines which depend on Level 1.

# Level 2 -- plotting interface.
#
# Level 3
# Packages which define own functions plus depend on Levels 0-2.
#
# Level 0, 1, 2 should be imported in order and then other levels imported
#   as available.

import Numeric
import os,sys
import string

# Level 0
# modules to import under the scipy namespace
from scipy_base import *
import Matrix
mat = Matrix.Matrix

from helpmod import *

try:
    id(help)
except NameError:
    help = info

# Level 1
# these modules will just be imported (not subsumed)
import special, io, linalg, stats, fftpack
from fftpack import fft, fftn, fft2, ifft, ifft2, ifftn, fftshift, ifftshift, cont_ft, fftfreq, zeropad
from stats import mean, median, std, cov, corrcoef
from special import isinf, isfinite, isnan

# Functions to be subsumed that need Level 0 and Level 1
from common import *

try:
    from pilutil import *
except ImportError:
    pass

try:
    import fftw
except ImportError:
    pass  # Not default anymore

# Level 2
import optimize, integrate, signal, special, interpolate, cow, ga, cluster, weave

# Level 3
_plot = []
try:
    if sys.platform != 'win32':
        import xplt
        #__all__.append('xplt')
        _plot.append('xplt')
except ImportError:
    pass

try:
#   gplt on win32 messes up focus and takes up 99%
#   of processor -- works fine on *nix.
    if sys.platform != 'win32':
        import gplt
        #__all__.append('gplt')
        _plot.append('gplt')
except ImportError:
    pass

#if _plot == []:
#    print "Warning: No plotting available."
#else:
#    print "Plotting methods available: ", _plot

#---- testing ----#

def test(level=1):
    """ From this top level, there are possibly many many tests.
        Test only the quick tests by default.
    """
    import unittest
    runner = unittest.TextTestRunner()
    runner.run(test_suite(level))
    return runner

def test_all(level=10):
    test(level)

def test_suite(level = 1):
    import scipy_base.testing
    import scipy
    ignore = ['xplt','plt','gplt','gui_thread','sparse','scipy_version']
    return scipy_base.testing.harvest_test_suites(scipy,ignore,level=level)
<commit_msg>Added documentation for info(scipy)<commit_after>"""
SciPy --- A scientific computing package for Python

Available subpackages
======================
"""

#try:
    #import gui_thread
#except:
    #print "Warning:  wxPython not loaded"

from scipy_version import scipy_version as __version__

# SciPy has levels
# Level 0 -- Numeric and core routines in scipy_base
#
# Level 1 -- Level 0 + fft, special, linalg, stats
# Level 1a -- Core routines which depend on Level 1.

# Level 2 -- plotting interface.
#
# Level 3
# Packages which define own functions plus depend on Levels 0-2.
#
# Level 0, 1, 2 should be imported in order and then other levels imported
#   as available.

import Numeric
import os,sys
import string

# Level 0
# modules to import under the scipy namespace
from scipy_base import *
import Matrix
mat = Matrix.Matrix

from helpmod import *

try:
    id(help)
except NameError:
    help = info

# Level 1
# these modules will just be imported (not subsumed)
import special, io, linalg, stats, fftpack
from fftpack import fft, fftn, fft2, ifft, ifft2, ifftn, fftshift, ifftshift, cont_ft, fftfreq, zeropad
from stats import mean, median, std, cov, corrcoef
from special import isinf, isfinite, isnan

# Functions to be subsumed that need Level 0 and Level 1
from common import *

try:
    from pilutil import *
except ImportError:
    pass

try:
    import fftw
except ImportError:
    pass  # Not default anymore

# Level 2
import optimize, integrate, signal, special, interpolate, cow, ga, cluster, weave

# Level 3
_plot = []
try:
    if sys.platform != 'win32':
        import xplt
        #__all__.append('xplt')
        _plot.append('xplt')
except ImportError:
    pass

try:
#   gplt on win32 messes up focus and takes up 99%
#   of processor -- works fine on *nix.
    if sys.platform != 'win32':
        import gplt
        #__all__.append('gplt')
        _plot.append('gplt')
except ImportError:
    pass

#if _plot == []:
#    print "Warning: No plotting available."
#else:
#    print "Plotting methods available: ", _plot

_pkgs = ['cluster','cow','fftpack','fftw','ga','gplt','integrate',
         'interpolate', 'io', 'linalg', 'optimize', 'plt',
         'signal', 'sparse', 'special', 'stats', 'weave',
         'xplt']

_pkg_doc = ['Vector Quantization / Kmeans',
            'Cluster of Workstations',
            'FFT algorithms',
            'FFT algorithms using fftw',
            'Genetic Algorithms',
            'Plotting with gnuplot',
            'Integration',
            'Interpolation',
            'Input/Output',
            'Linear Algebra',
            'Optimization',
            'Plotting with wxPython',
            'Signal Processing',
            'Sparse Matrices',
            'Special Functions',
            'Statistics',
            'C/C++ integration',
            'Plotting with X']

def _extend_doc(st,p,pd):
    _lengths = [len(x) for x in p]
    _ml = max(_lengths)
    k = 0
    for name in p:
        try:
            exec "import %s" % name
            st += "%s%s --- %s\n" % (name, ' '*(_ml-_lengths[k]), pd[k])
        except ImportError:
            pass
        k += 1
    return st

__doc__ = _extend_doc(__doc__,_pkgs,_pkg_doc)

#---- testing ----#

def test(level=1):
    """ From this top level, there are possibly many many tests.
        Test only the quick tests by default.
    """
    import unittest
    runner = unittest.TextTestRunner()
    runner.run(test_suite(level))
    return runner

def test_all(level=10):
    test(level)

def test_suite(level = 1):
    import scipy_base.testing
    import scipy
    ignore = ['xplt','plt','gplt','gui_thread','sparse','scipy_version']
    return scipy_base.testing.harvest_test_suites(scipy,ignore,level=level)
<|endoftext|>


<commit_before>"""Helper to provide extensibility for pickle/cPickle.

This is only useful to add pickle support for extension types defined in
C, not for instances of user-defined classes.
"""

from types import ClassType as _ClassType

__all__ = ["pickle", "constructor",
           "add_extension", "remove_extension", "clear_extension_cache"]

dispatch_table = {}

def pickle(ob_type, pickle_function, constructor_ob=None):
    if type(ob_type) is _ClassType:
        raise TypeError("copy_reg is not intended for use with classes")

    if not callable(pickle_function):
        raise TypeError("reduction functions must be callable")
    dispatch_table[ob_type] = pickle_function

    if constructor_ob is not None:
        constructor(constructor_ob)

def constructor(object):
    if not callable(object):
        raise TypeError("constructors must be callable")

# Example: provide pickling support for complex numbers.

def pickle_complex(c):
    return complex, (c.real, c.imag)

pickle(type(1j), pickle_complex, complex)

# Support for picking new-style objects

def _reconstructor(cls, base, state):
    obj = base.__new__(cls, state)
    base.__init__(obj, state)
    return obj

_HEAPTYPE = 1<<9

def _reduce(self):
    for base in self.__class__.__mro__:
        if hasattr(base, '__flags__') and not base.__flags__ & _HEAPTYPE:
            break
    else:
        base = object # not really reachable
    if base is object:
        state = None
    else:
        if base is self.__class__:
            raise TypeError, "can't pickle %s objects" % base.__name__
        state = base(self)
    args = (self.__class__, base, state)
    try:
        getstate = self.__getstate__
    except AttributeError:
        try:
            dict = self.__dict__
        except AttributeError:
            dict = None
    else:
        dict = getstate()
    if dict:
        return _reconstructor, args, dict
    else:
        return _reconstructor, args

# A better version of _reduce, used by copy and pickle protocol 2

def __newobj__(cls, *args):
    return cls.__new__(cls, *args)

def _better_reduce(obj):
    cls = obj.__class__
    getnewargs = getattr(obj, "__getnewargs__", None)
    if getnewargs:
        args = getnewargs()
    else:
        args = ()
    getstate = getattr(obj, "__getstate__", None)
    if getstate:
        try:
            state = getstate()
        except TypeError, err:
            # XXX Catch generic exception caused by __slots__
            if str(err) != ("a class that defines __slots__ "
                            "without defining __getstate__ "
                            "cannot be pickled"):
                raise # Not that specific exception
            getstate = None
    if not getstate:
        state = getattr(obj, "__dict__", None)
        names = _slotnames(cls)
        if names:
            slots = {}
            nil = []
            for name in names:
                value = getattr(obj, name, nil)
                if value is not nil:
                    slots[name] = value
            if slots:
                state = (state, slots)
    listitems = dictitems = None
    if isinstance(obj, list):
        listitems = iter(obj)
    elif isinstance(obj, dict):
        dictitems = obj.iteritems()
    return __newobj__, (cls,) + args, state, listitems, dictitems

def _slotnames(cls):
    """Return a list of slot names for a given class.

    This needs to find slots defined by the class and its bases, so we
    can't simply return the __slots__ attribute.  We must walk down
    the Method Resolution Order and concatenate the __slots__ of each
    class found there.  (This assumes classes don't modify their
    __slots__ attribute to misrepresent their slots after the class is
    defined.)
    """

    # Get the value from a cache in the class if possible
    names = cls.__dict__.get("__slotnames__")
    if names is not None:
        return names

    # Not cached -- calculate the value
    names = []
    if not hasattr(cls, "__slots__"):
        # This class has no slots
        pass
    else:
        # Slots found -- gather slot names from all base classes
        for c in cls.__mro__:
            if "__slots__" in c.__dict__:
                names += [name for name in c.__dict__["__slots__"]
                               if name not in ("__dict__", "__weakref__")]

    # Cache the outcome in the class if at all possible
    try:
        cls.__slotnames__ = names
    except:
        pass # But don't die if we can't

    return names

# A registry of extension codes.  This is an ad-hoc compression
# mechanism.  Whenever a global reference to <module>, <name> is about
# to be pickled, the (<module>, <name>) tuple is looked up here to see
# if it is a registered extension code for it.  Extension codes are
# universal, so that the meaning of a pickle does not depend on
# context.  (There are also some codes reserved for local use that
# don't have this restriction.)  Codes are positive ints; 0 is
# reserved.

_extension_registry = {}                # key -> code
_inverted_registry = {}                 # code -> key
_extension_cache = {}                   # code -> object
# Don't ever rebind those names:  cPickle grabs a reference to them when
# it's initialized, and won't see a rebinding.

def add_extension(module, name, code):
    """Register an extension code."""
    code = int(code)
    if not 1 <= code <= 0x7fffffff:
        raise ValueError, "code out of range"
    key = (module, name)
    if (_extension_registry.get(key) == code and
        _inverted_registry.get(code) == key):
        return # Redundant registrations are benign
    if key in _extension_registry:
        raise ValueError("key %s is already registered with code %s" %
                         (key, _extension_registry[key]))
    if code in _inverted_registry:
        raise ValueError("code %s is already in use for key %s" %
                         (code, _inverted_registry[code]))
    _extension_registry[key] = code
    _inverted_registry[code] = key

def remove_extension(module, name, code):
    """Unregister an extension code.  For testing only."""
    key = (module, name)
    if (_extension_registry.get(key) != code or
        _inverted_registry.get(code) != key):
        raise ValueError("key %s is not registered with code %s" %
                         (key, code))
    del _extension_registry[key]
    del _inverted_registry[code]
    if code in _extension_cache:
        del _extension_cache[code]

def clear_extension_cache():
    _extension_cache.clear()

# Standard extension code assignments

# Reserved ranges

# First  Last Count  Purpose
#     1   127   127  Reserved for Python standard library
#   128   191    64  Reserved for Zope 3
#   192   239    48  Reserved for 3rd parties
#   240   255    16  Reserved for private use (will never be assigned)
#   256   Inf   Inf  Reserved for future assignment

# Extension codes are assigned by the Python Software Foundation.
<commit_msg>Reserve a range for Zope, not specifically for Zope 3.<commit_after>"""Helper to provide extensibility for pickle/cPickle.

This is only useful to add pickle support for extension types defined in
C, not for instances of user-defined classes.
"""

from types import ClassType as _ClassType

__all__ = ["pickle", "constructor",
           "add_extension", "remove_extension", "clear_extension_cache"]

dispatch_table = {}

def pickle(ob_type, pickle_function, constructor_ob=None):
    if type(ob_type) is _ClassType:
        raise TypeError("copy_reg is not intended for use with classes")

    if not callable(pickle_function):
        raise TypeError("reduction functions must be callable")
    dispatch_table[ob_type] = pickle_function

    if constructor_ob is not None:
        constructor(constructor_ob)

def constructor(object):
    if not callable(object):
        raise TypeError("constructors must be callable")

# Example: provide pickling support for complex numbers.

def pickle_complex(c):
    return complex, (c.real, c.imag)

pickle(type(1j), pickle_complex, complex)

# Support for picking new-style objects

def _reconstructor(cls, base, state):
    obj = base.__new__(cls, state)
    base.__init__(obj, state)
    return obj

_HEAPTYPE = 1<<9

def _reduce(self):
    for base in self.__class__.__mro__:
        if hasattr(base, '__flags__') and not base.__flags__ & _HEAPTYPE:
            break
    else:
        base = object # not really reachable
    if base is object:
        state = None
    else:
        if base is self.__class__:
            raise TypeError, "can't pickle %s objects" % base.__name__
        state = base(self)
    args = (self.__class__, base, state)
    try:
        getstate = self.__getstate__
    except AttributeError:
        try:
            dict = self.__dict__
        except AttributeError:
            dict = None
    else:
        dict = getstate()
    if dict:
        return _reconstructor, args, dict
    else:
        return _reconstructor, args

# A better version of _reduce, used by copy and pickle protocol 2

def __newobj__(cls, *args):
    return cls.__new__(cls, *args)

def _better_reduce(obj):
    cls = obj.__class__
    getnewargs = getattr(obj, "__getnewargs__", None)
    if getnewargs:
        args = getnewargs()
    else:
        args = ()
    getstate = getattr(obj, "__getstate__", None)
    if getstate:
        try:
            state = getstate()
        except TypeError, err:
            # XXX Catch generic exception caused by __slots__
            if str(err) != ("a class that defines __slots__ "
                            "without defining __getstate__ "
                            "cannot be pickled"):
                raise # Not that specific exception
            getstate = None
    if not getstate:
        state = getattr(obj, "__dict__", None)
        names = _slotnames(cls)
        if names:
            slots = {}
            nil = []
            for name in names:
                value = getattr(obj, name, nil)
                if value is not nil:
                    slots[name] = value
            if slots:
                state = (state, slots)
    listitems = dictitems = None
    if isinstance(obj, list):
        listitems = iter(obj)
    elif isinstance(obj, dict):
        dictitems = obj.iteritems()
    return __newobj__, (cls,) + args, state, listitems, dictitems

def _slotnames(cls):
    """Return a list of slot names for a given class.

    This needs to find slots defined by the class and its bases, so we
    can't simply return the __slots__ attribute.  We must walk down
    the Method Resolution Order and concatenate the __slots__ of each
    class found there.  (This assumes classes don't modify their
    __slots__ attribute to misrepresent their slots after the class is
    defined.)
    """

    # Get the value from a cache in the class if possible
    names = cls.__dict__.get("__slotnames__")
    if names is not None:
        return names

    # Not cached -- calculate the value
    names = []
    if not hasattr(cls, "__slots__"):
        # This class has no slots
        pass
    else:
        # Slots found -- gather slot names from all base classes
        for c in cls.__mro__:
            if "__slots__" in c.__dict__:
                names += [name for name in c.__dict__["__slots__"]
                               if name not in ("__dict__", "__weakref__")]

    # Cache the outcome in the class if at all possible
    try:
        cls.__slotnames__ = names
    except:
        pass # But don't die if we can't

    return names

# A registry of extension codes.  This is an ad-hoc compression
# mechanism.  Whenever a global reference to <module>, <name> is about
# to be pickled, the (<module>, <name>) tuple is looked up here to see
# if it is a registered extension code for it.  Extension codes are
# universal, so that the meaning of a pickle does not depend on
# context.  (There are also some codes reserved for local use that
# don't have this restriction.)  Codes are positive ints; 0 is
# reserved.

_extension_registry = {}                # key -> code
_inverted_registry = {}                 # code -> key
_extension_cache = {}                   # code -> object
# Don't ever rebind those names:  cPickle grabs a reference to them when
# it's initialized, and won't see a rebinding.

def add_extension(module, name, code):
    """Register an extension code."""
    code = int(code)
    if not 1 <= code <= 0x7fffffff:
        raise ValueError, "code out of range"
    key = (module, name)
    if (_extension_registry.get(key) == code and
        _inverted_registry.get(code) == key):
        return # Redundant registrations are benign
    if key in _extension_registry:
        raise ValueError("key %s is already registered with code %s" %
                         (key, _extension_registry[key]))
    if code in _inverted_registry:
        raise ValueError("code %s is already in use for key %s" %
                         (code, _inverted_registry[code]))
    _extension_registry[key] = code
    _inverted_registry[code] = key

def remove_extension(module, name, code):
    """Unregister an extension code.  For testing only."""
    key = (module, name)
    if (_extension_registry.get(key) != code or
        _inverted_registry.get(code) != key):
        raise ValueError("key %s is not registered with code %s" %
                         (key, code))
    del _extension_registry[key]
    del _inverted_registry[code]
    if code in _extension_cache:
        del _extension_cache[code]

def clear_extension_cache():
    _extension_cache.clear()

# Standard extension code assignments

# Reserved ranges

# First  Last Count  Purpose
#     1   127   127  Reserved for Python standard library
#   128   191    64  Reserved for Zope
#   192   239    48  Reserved for 3rd parties
#   240   255    16  Reserved for private use (will never be assigned)
#   256   Inf   Inf  Reserved for future assignment

# Extension codes are assigned by the Python Software Foundation.
<|endoftext|>


<commit_before># Parse (absolute and relative) URLs according to latest internet draft:

# Uniform Resource Identifiers Working Group                  R. Fielding
# INTERNET-DRAFT                                                UC Irvine
# Expires February 24, 1995                               August 24, 1994
#
#                   Relative Uniform Resource Locators
#                  <draft-ietf-uri-relative-url-00.txt>

# Standard/builtin Python modules
import string

# A classification of schemes ('' means apply by default)
uses_relative = ['ftp', 'http', 'gopher', 'nntp', 'wais', 'file',
		 'prospero', '']
uses_netloc = ['ftp', 'http', 'gopher', 'nntp', 'telnet', 'wais',
	       'file', 'prospero', '']
non_hierarchical = ['gopher', 'mailto', 'news', 'telnet', 'wais']
uses_params = ['ftp', 'prospero', '']
uses_query = ['http', 'wais', '']
uses_fragment = ['ftp', 'http', 'gopher', 'news', 'nntp', 'wais',
		 'file', 'prospero', '']

# Characters valid in scheme names
scheme_chars = string.letters + string.digits + '+-.'

# Parse a URL into 6 components:
# <scheme>://<netloc>/<path>;<params>?<query>#<fragment>
# Return a 6-tuple: (scheme, netloc, path, params, query, fragment).
# Note that we don't break the components up in smaller bits
# (e.g. netloc is a single string) and we don't expand % escapes.
def urlparse(url, scheme = '', allow_framents = 1):
	netloc = ''
	path = ''
	params = ''
	query = ''
	fragment = ''
	i = string.find(url, ':')
	if i > 0:
		for c in url[:i]:
			if c not in scheme_chars:
				break
		else:
			scheme, url = string.lower(url[:i]), url[i+1:]
	if scheme in uses_netloc:
		if url[:2] == '//':
			i = string.find(url, '/', 2)
			if i < 0:
				i = len(url)
			netloc, url = url[2:i], url[i:]
	if allow_framents and scheme in uses_fragment:
		i = string.rfind(url, '#')
		if i >= 0:
			url, fragment = url[:i], url[i+1:]
	if scheme in uses_query:
		i = string.find(url, '?')
		if i >= 0:
			url, query = url[:i], url[i+1:]
	if scheme in uses_params:
		i = string.find(url, ';')
		if i >= 0:
			url, params = url[:i], url[i+1:]
	return scheme, netloc, url, params, query, fragment

# Put a parsed URL back together again.  This may result in a slightly
# different, but equivalent URL, if the URL that was parsed originally
# had redundant delimiters, e.g. a ? with an empty query (the draft
# states that these are equivalent).
def urlunparse((scheme, netloc, url, params, query, fragment)):
	if netloc:
		url = '//' + netloc + url
	if scheme:
		url = scheme + ':' + url
	if params:
		url = url + ';' + params
	if query:
		url = url + '?' + query
	if fragment:
		url = url + '#' + fragment
	return url

# Join a base URL and a possibly relative URL to form an absolute
# interpretation of the latter.
def urljoin(base, url, allow_framents = 1):
	if not base:
		return url
	bscheme, bnetloc, bpath, bparams, bquery, bfragment = \
		  urlparse(base, '', allow_framents)
	scheme, netloc, path, params, query, fragment = \
		urlparse(url, bscheme, allow_framents)
	# XXX Unofficial hack: default netloc to bnetloc even if
	# schemes differ
	if scheme != bscheme and not netloc and \
	   scheme in uses_relative and bscheme in uses_relative and \
	   scheme in uses_netloc and bscheme in uses_netloc:
	   netloc = bnetloc
	   # Strip the port number
	   i = string.find(netloc, '@')
	   if i < 0: i = 0
	   i = string.find(netloc, ':', i)
	   if i >= 0:
		   netloc = netloc[:i]
	if scheme != bscheme or scheme not in uses_relative:
		return urlunparse((scheme, netloc, path,
				   params, query, fragment))
	if scheme in uses_netloc:
		if netloc:
			return urlunparse((scheme, netloc, path,
					   params, query, fragment))
		netloc = bnetloc
	if path[:1] == '/':
		return urlunparse((scheme, netloc, path,
				   params, query, fragment))
	if not path:
		path = bpath
		if not query:
			query = bquery
		return urlunparse((scheme, netloc, path,
				   params, query, fragment))
	i = string.rfind(bpath, '/')
	if i < 0:
		i = len(bpath)
	path = bpath[:i] + '/' + path
	segments = string.splitfields(path, '/')
	if segments[-1] == '.':
		segments[-1] = ''
	while '.' in segments:
		segments.remove('.')
	while 1:
		i = 1
		n = len(segments) - 1
		while i < n:
			if segments[i] == '..' and segments[i-1]:
				del segments[i-1:i+1]
				break
			i = i+1
		else:
			break
	if len(segments) >= 2 and segments[-1] == '..':
		segments[-2:] = ['']
	path = string.joinfields(segments, '/')
	return urlunparse((scheme, netloc, path,
			   params, query, fragment))

test_input = """
      http://a/b/c/d

      g:h        = <URL:g:h>
      http:g     = <URL:http://a/b/c/g>
      http:      = <URL:http://a/b/c/d>
      g          = <URL:http://a/b/c/g>
      ./g        = <URL:http://a/b/c/g>
      g/         = <URL:http://a/b/c/g/>
      /g         = <URL:http://a/g>
      //g        = <URL:http://g>
      ?y         = <URL:http://a/b/c/d?y>
      g?y        = <URL:http://a/b/c/g?y>
      g?y/./x    = <URL:http://a/b/c/g?y/./x>
      .          = <URL:http://a/b/c/>
      ./         = <URL:http://a/b/c/>
      ..         = <URL:http://a/b/>
      ../        = <URL:http://a/b/>
      ../g       = <URL:http://a/b/g>
      ../..      = <URL:http://a/>
      ../../g    = <URL:http://a/g>
      ../../../g = <URL:http://a/../g>
      ./../g     = <URL:http://a/b/g>
      ./g/.      = <URL:http://a/b/c/g/>
      /./g       = <URL:http://a/./g>
      g/./h      = <URL:http://a/b/c/g/h>
      g/../h     = <URL:http://a/b/c/h>
      http:g     = <URL:http://a/b/c/g>
      http:      = <URL:http://a/b/c/d>
"""

def test():
	import sys
	base = ''
	if sys.argv[1:]:
		fn = sys.argv[1]
		if fn == '-':
			fp = sys.stdin
		else:
			fp = open(fn)
	else:
		import StringIO
		fp = StringIO.StringIO(test_input)
	while 1:
		line = fp.readline()
		if not line: break
		words = string.split(line)
		if not words:
			continue
		url = words[0]
		parts = urlparse(url)
		print '%-10s : %s' % (url, parts)
		abs = urljoin(base, url)
		if not base:
			base = abs
		wrapped = '<URL:%s>' % abs
		print '%-10s = %s' % (url, wrapped)
		if len(words) == 3 and words[1] == '=':
			if wrapped != words[2]:
				print 'EXPECTED', words[2], '!!!!!!!!!!'

if __name__ == '__main__':
	test()
<commit_msg>subtle changes to relative rurl joins<commit_after># Parse (absolute and relative) URLs according to latest internet draft:

# Uniform Resource Identifiers Working Group                  R. Fielding
# INTERNET-DRAFT                                                UC Irvine
# Expires February 24, 1995                               August 24, 1994
#
#                   Relative Uniform Resource Locators
#                  <draft-ietf-uri-relative-url-00.txt>

# Standard/builtin Python modules
import string

# A classification of schemes ('' means apply by default)
uses_relative = ['ftp', 'http', 'gopher', 'nntp', 'wais', 'file',
		 'prospero', '']
uses_netloc = ['ftp', 'http', 'gopher', 'nntp', 'telnet', 'wais',
	       'file', 'prospero', '']
non_hierarchical = ['gopher', 'mailto', 'news', 'telnet', 'wais']
uses_params = ['ftp', 'prospero', '']
uses_query = ['http', 'wais', '']
uses_fragment = ['ftp', 'http', 'gopher', 'news', 'nntp', 'wais',
		 'file', 'prospero', '']

# Characters valid in scheme names
scheme_chars = string.letters + string.digits + '+-.'

# Parse a URL into 6 components:
# <scheme>://<netloc>/<path>;<params>?<query>#<fragment>
# Return a 6-tuple: (scheme, netloc, path, params, query, fragment).
# Note that we don't break the components up in smaller bits
# (e.g. netloc is a single string) and we don't expand % escapes.
def urlparse(url, scheme = '', allow_framents = 1):
	netloc = ''
	path = ''
	params = ''
	query = ''
	fragment = ''
	i = string.find(url, ':')
	if i > 0:
		for c in url[:i]:
			if c not in scheme_chars:
				break
		else:
			scheme, url = string.lower(url[:i]), url[i+1:]
	if scheme in uses_netloc:
		if url[:2] == '//':
			i = string.find(url, '/', 2)
			if i < 0:
				i = len(url)
			netloc, url = url[2:i], url[i:]
	if allow_framents and scheme in uses_fragment:
		i = string.rfind(url, '#')
		if i >= 0:
			url, fragment = url[:i], url[i+1:]
	if scheme in uses_query:
		i = string.find(url, '?')
		if i >= 0:
			url, query = url[:i], url[i+1:]
	if scheme in uses_params:
		i = string.find(url, ';')
		if i >= 0:
			url, params = url[:i], url[i+1:]
	return scheme, netloc, url, params, query, fragment

# Put a parsed URL back together again.  This may result in a slightly
# different, but equivalent URL, if the URL that was parsed originally
# had redundant delimiters, e.g. a ? with an empty query (the draft
# states that these are equivalent).
def urlunparse((scheme, netloc, url, params, query, fragment)):
	if netloc:
		if url[:1] != '/': url = '/' + url
		url = '//' + netloc + url
	if scheme:
		url = scheme + ':' + url
	if params:
		url = url + ';' + params
	if query:
		url = url + '?' + query
	if fragment:
		url = url + '#' + fragment
	return url

# Join a base URL and a possibly relative URL to form an absolute
# interpretation of the latter.
def urljoin(base, url, allow_framents = 1):
	if not base:
		return url
	bscheme, bnetloc, bpath, bparams, bquery, bfragment = \
		  urlparse(base, '', allow_framents)
	scheme, netloc, path, params, query, fragment = \
		urlparse(url, bscheme, allow_framents)
	# XXX Unofficial hack: default netloc to bnetloc even if
	# schemes differ
	if scheme != bscheme and not netloc and \
	   scheme in uses_relative and bscheme in uses_relative and \
	   scheme in uses_netloc and bscheme in uses_netloc:
	   netloc = bnetloc
	   # Strip the port number
	   i = string.find(netloc, '@')
	   if i < 0: i = 0
	   i = string.find(netloc, ':', i)
	   if i >= 0:
		   netloc = netloc[:i]
	if scheme != bscheme or scheme not in uses_relative:
		return urlunparse((scheme, netloc, path,
				   params, query, fragment))
	if scheme in uses_netloc:
		if netloc:
			return urlunparse((scheme, netloc, path,
					   params, query, fragment))
		netloc = bnetloc
	if path[:1] == '/':
		return urlunparse((scheme, netloc, path,
				   params, query, fragment))
	if not path:
		path = bpath
		if not query:
			query = bquery
		return urlunparse((scheme, netloc, path,
				   params, query, fragment))
	i = string.rfind(bpath, '/')
	if i >= 0:
		path = bpath[:i] + '/' + path
	segments = string.splitfields(path, '/')
	if segments[-1] == '.':
		segments[-1] = ''
	while '.' in segments:
		segments.remove('.')
	while 1:
		i = 1
		n = len(segments) - 1
		while i < n:
			if segments[i] == '..' and segments[i-1]:
				del segments[i-1:i+1]
				break
			i = i+1
		else:
			break
	if len(segments) >= 2 and segments[-1] == '..':
		segments[-2:] = ['']
	path = string.joinfields(segments, '/')
	return urlunparse((scheme, netloc, path,
			   params, query, fragment))

test_input = """
      http://a/b/c/d

      g:h        = <URL:g:h>
      http:g     = <URL:http://a/b/c/g>
      http:      = <URL:http://a/b/c/d>
      g          = <URL:http://a/b/c/g>
      ./g        = <URL:http://a/b/c/g>
      g/         = <URL:http://a/b/c/g/>
      /g         = <URL:http://a/g>
      //g        = <URL:http://g>
      ?y         = <URL:http://a/b/c/d?y>
      g?y        = <URL:http://a/b/c/g?y>
      g?y/./x    = <URL:http://a/b/c/g?y/./x>
      .          = <URL:http://a/b/c/>
      ./         = <URL:http://a/b/c/>
      ..         = <URL:http://a/b/>
      ../        = <URL:http://a/b/>
      ../g       = <URL:http://a/b/g>
      ../..      = <URL:http://a/>
      ../../g    = <URL:http://a/g>
      ../../../g = <URL:http://a/../g>
      ./../g     = <URL:http://a/b/g>
      ./g/.      = <URL:http://a/b/c/g/>
      /./g       = <URL:http://a/./g>
      g/./h      = <URL:http://a/b/c/g/h>
      g/../h     = <URL:http://a/b/c/h>
      http:g     = <URL:http://a/b/c/g>
      http:      = <URL:http://a/b/c/d>
"""

def test():
	import sys
	base = ''
	if sys.argv[1:]:
		fn = sys.argv[1]
		if fn == '-':
			fp = sys.stdin
		else:
			fp = open(fn)
	else:
		import StringIO
		fp = StringIO.StringIO(test_input)
	while 1:
		line = fp.readline()
		if not line: break
		words = string.split(line)
		if not words:
			continue
		url = words[0]
		parts = urlparse(url)
		print '%-10s : %s' % (url, parts)
		abs = urljoin(base, url)
		if not base:
			base = abs
		wrapped = '<URL:%s>' % abs
		print '%-10s = %s' % (url, wrapped)
		if len(words) == 3 and words[1] == '=':
			if wrapped != words[2]:
				print 'EXPECTED', words[2], '!!!!!!!!!!'

if __name__ == '__main__':
	test()
<|endoftext|>


<commit_before>import os
import sublime
import sublime_plugin
import subprocess
import tempfile
import time
import threading

# Load settings on plugin load
s = sublime.load_settings('LineProfiler.sublime-settings')
PYTHON = s.get('python')
KERNPROF = s.get('kernprof')
PYTHONPATH = s.get('pythonpath')
POLL_SLEEP_SECONDS = s.get('poll_sleep_seconds')
POLL_TIMEOUT_SECONDS = s.get('poll_timeout_seconds')

class LineProfilerCommand(sublime_plugin.TextCommand):
  def is_enabled(self):
    return 'source.python' in self.view.scope_name(0)

  def run(self, edit):
    if not self.is_enabled():
      return

    # set up paths
    fname = self.view.file_name()
    is_tmpfile = False
    env = os.environ.copy()
    if fname is None:
      env['PYTHONPATH'] = PYTHONPATH
    else:
      env['PYTHONPATH'] = os.path.dirname(fname) + os.pathsep + PYTHONPATH

    # write the file if it's not saved right now
    if fname is None or self.view.is_dirty():
      contents = self.view.substr(sublime.Region(0, self.view.size()))
      with tempfile.NamedTemporaryFile(suffix='.py', delete=False) as fh:
        fh.write(bytes(contents, 'UTF-8'))
        fname = fh.name
      is_tmpfile = True

    # run kernprof with the correct paths
    p = subprocess.Popen([PYTHON, KERNPROF,'-lbv','-o','/dev/null',fname], env=env, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

    # set up the output catcher thread
    window = self.view.window()
    if not is_tmpfile:
      fname = None
    threading.Thread(target=read_output, args=(window, p, fname)).start()

class LineProfilerOutputCommand(sublime_plugin.TextCommand):
  def run(self, edit, profile_data=None):
    if profile_data is None:
      print('This command should only be called by line_profiler')
      return
    self.view.insert(edit,0, profile_data)
    self.view.set_read_only(True)

def read_output(window, p, fname):
  # poll for results
  tic = time.time()
  while p.poll() is None:
    if time.time() - tic > POLL_TIMEOUT_SECONDS:
      print('kernprof timed out, killing process')
      p.kill()
      return
    time.sleep(POLL_SLEEP_SECONDS)

  # read stdout and stderr
  stdout, stderr = p.communicate()
  errors = stderr.decode('UTF-8')
  output = stdout.decode('UTF-8').splitlines()

  # clean up, if needed
  if fname:
    os.unlink(fname)

  # check for success
  if p.returncode != 0:
    print('kernprof exited with code %d' % p.returncode)
    print(errors)
    return

  # parse result
  file_name, func_name, profile = '<file>', '<func>', ''
  for i,line in enumerate(output):
    if line.startswith('File:'):
      file_name = os.path.basename(line[6:])
    elif line.startswith('Function:'):
      func_name = line.split()[1]
    elif line.startswith('====='):
      profile = '\n'.join(x.rstrip() for x in output[i-3:])  # include header and total time
      break

  # display
  scratch = window.new_file()
  scratch.set_scratch(True)
  scratch.set_name('Profile of %s::%s' % (file_name, func_name))
  scratch.run_command('line_profiler_output', {'profile_data': profile})
<commit_msg>adding ST2 support<commit_after>import os
import sublime
import sublime_plugin
import subprocess
import tempfile
import time
import threading

# Load settings on plugin load
s = sublime.load_settings('LineProfiler.sublime-settings')
PYTHON = s.get('python','/usr/bin/python')
KERNPROF = s.get('kernprof','kernprof.py')
PYTHONPATH = s.get('pythonpath','')
POLL_SLEEP_SECONDS = s.get('poll_sleep_seconds',1)
POLL_TIMEOUT_SECONDS = s.get('poll_timeout_seconds',60)

class LineProfilerCommand(sublime_plugin.TextCommand):
  def is_enabled(self):
    return 'source.python' in self.view.scope_name(0)

  def run(self, edit):
    if not self.is_enabled():
      return

    # set up paths
    fname = self.view.file_name()
    is_tmpfile = False
    env = os.environ.copy()
    if fname is None:
      env['PYTHONPATH'] = PYTHONPATH
      cwd = None
    else:
      cwd = os.path.dirname(fname)
      env['PYTHONPATH'] = cwd + os.pathsep + PYTHONPATH

    # write the file if it's not saved right now
    if fname is None or self.view.is_dirty():
      contents = self.view.substr(sublime.Region(0, self.view.size()))
      with tempfile.NamedTemporaryFile(suffix='.py', delete=False) as fh:
        fh.write(contents.encode('UTF-8'))
        fname = fh.name
      is_tmpfile = True

    # run kernprof with the correct paths
    p = subprocess.Popen([PYTHON, KERNPROF,'-lbv','-o','/dev/null',fname],
        env=env, cwd=cwd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

    # set up the output catcher thread
    window = self.view.window()
    if not is_tmpfile:
      fname = None
    threading.Thread(target=read_output, args=(window, p, fname)).start()

class LineProfilerOutputCommand(sublime_plugin.TextCommand):
  def run(self, edit, profile_data=None):
    if profile_data is None:
      print('This command should only be called by line_profiler')
      return
    self.view.insert(edit,0, profile_data)
    self.view.set_read_only(True)

def read_output(window, p, fname):
  # poll for results
  tic = time.time()
  while p.poll() is None:
    if time.time() - tic > POLL_TIMEOUT_SECONDS:
      print('kernprof timed out, killing process')
      p.kill()
      return
    time.sleep(POLL_SLEEP_SECONDS)

  # read stdout and stderr
  stdout, stderr = p.communicate()
  errors = stderr.decode('UTF-8')
  output = stdout.decode('UTF-8').splitlines()

  # clean up, if needed
  if fname:
    os.unlink(fname)

  # check for success
  if p.returncode != 0:
    print('kernprof exited with code %d' % p.returncode)
    print(errors)
    return

  # parse result
  file_name, func_name, profile = '<file>', '<func>', ''
  for i,line in enumerate(output):
    if line.startswith('File:'):
      file_name = os.path.basename(line[6:])
    elif line.startswith('Function:'):
      func_name = line.split()[1]
    elif line.startswith('====='):
      profile = '\n'.join(x.rstrip() for x in output[i-3:])  # include header and total time
      break

  # display
  sublime.set_timeout(lambda: display_results(file_name, func_name, profile), 0)

def display_results(file_name, func_name, profile):
  scratch = sublime.active_window().new_file()
  scratch.set_scratch(True)
  scratch.set_name('Profile of %s::%s' % (file_name, func_name))
  scratch.run_command('line_profiler_output', {'profile_data': profile})
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
# Copyright 2012-2013 UNED
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from django.db.models import Sum

from moocng.mongodb import get_db

def calculate_question_mark(kq, question, user):

    """
    Calculate if the user answer is the correct one, and punctuate accordingly.
    If the user did the task right the platform gives a 10, if not, a 0.

    .. versionadded:: 0.1
    """
    db = get_db()
    answers = db.get_collection('answers')
    user_answer = answers.find_one({
        'user_id': user.id,
        'question_id': question.id
    })

    if user_answer:
        mark = question.is_correct(user_answer)
        return mark
    return 0.0

def calculate_peer_review_mark(kq, peer_review_assignment, user):

    """
    Calculate if the user has done the peer reviewed task. This is done by
    checking if the minimum reviews of the task have been done.

    .. versionadded:: 0.1
    """
    from moocng.peerreview.utils import kq_get_peer_review_score

    mark = kq_get_peer_review_score(kq, user,
                                    peer_review_assignment)
    if mark is None:
        mark = 0
    return mark

def calculate_kq_video_mark(kq, user):

    """
    Mark the video as viewed and give the user the punctuation.

    .. versionadded:: 0.1
    """
    if kq.kq_visited_by(user):
        return 10.0
    return 0.0

def calculate_kq_mark(kq, user):

    """
    Calculate is a answer was right or wrong, this is the main function that
    calls the others depending on the content (peerreview, normal, etc.)

    .. warning:: Don't use this in loops

    .. versionadded:: 0.1
    """
    from moocng.peerreview.models import PeerReviewAssignment
    mark = relative_mark = 0

    try:
        question = kq.question_set.get()
        # KQ has a question
        mark = calculate_question_mark(kq, question, user)
    except kq.question_set.model.DoesNotExist:
        try:
            # KQ has a peer review
            pra = kq.peerreviewassignment
            mark = calculate_peer_review_mark(kq, pra, user)
        except PeerReviewAssignment.DoesNotExist:
            # KQ hasn't a question or peer review
            mark = calculate_kq_video_mark(kq, user)
    relative_mark = normalize_kq_weight(kq) * mark / 100.0
    return (mark, relative_mark)

def normalize_kq_weight(kq, unit_kq_counter=None, total_weight_unnormalized=None):
    # KnowledgeQuantumResource does not send unit_kq_counter  [tastypie api]
    if unit_kq_counter is None:
        unit = kq.unit
        total_weight_unnormalized, unit_kq_counter, uni_kqs = get_unit_intermediate_calculations(unit)
    if total_weight_unnormalized == 0:
        if unit_kq_counter == 0:
            return 0
        else:
            return 100.0 / unit_kq_counter
    return (kq.weight * 100.0) / total_weight_unnormalized

def calculate_unit_mark(unit, user, normalized_unit_weight=None):
    """
    Calculate if a unit is approved.

    .. warning:: Don't use this in loops

    .. versionadded:: 0.1
    """

    if normalized_unit_weight is None:
        total_weight_unnormalized, unit_course_counter, course_units = get_course_intermediate_calculations(unit.course)
        normalized_unit_weight = normalize_unit_weight(unit, unit_course_counter, total_weight_unnormalized)
    unit_mark = 0
    kqs = get_kq_info_from_course(unit, user)
    for kq in kqs:
        unit_mark += kq['relative_mark']
    print "Unit_mark: %d - normalized_unit_weight: %d, normalized_unit_mark: %d" % (unit_mark, normalized_unit_weight, (normalized_unit_weight * unit_mark) / 100.0)
    return (unit_mark, (normalized_unit_weight * unit_mark) / 100.0)

def get_kq_info_from_course(unit, user, db=None):
    db = db or get_db()
    data_unit = {'user_id': user.pk,
                 'unit_id': unit.pk}
    marks_kq = db.get_collection('marks_kq')
    return list(marks_kq.find(data_unit))

def normalize_unit_weight(unit, course_unit_counter, total_weight_unnormalized):
    print "Unit: %s - Course_unit_counter: %d - total_weight_unnormalized: %d" % (unit, course_unit_counter, total_weight_unnormalized)
    if total_weight_unnormalized == 0:
        if course_unit_counter == 0 or not unit.is_scorable():
            return 0
        else:
            return 100.0 / course_unit_counter
    return (unit.weight * 100.0) / total_weight_unnormalized

def get_course_intermediate_calculations(course):
    course_units = course.unit_set.scorables()
    total_weight_unnormalized = course.unit_set.aggregate(Sum('weight'))['weight__sum']
    unit_course_counter = course_units.count()
    return (total_weight_unnormalized, unit_course_counter, course_units)

def get_unit_intermediate_calculations(unit):
    unit_kqs = unit.knowledgequantum_set.all()
    total_weight_unnormalized = unit_kqs.aggregate(Sum('weight'))['weight__sum']
    unit_kqs_counter = unit_kqs.count()
    return (total_weight_unnormalized, unit_kqs_counter, unit_kqs)

def calculate_course_mark(course, user):
    units_info = get_units_info_from_course(course, user)
    total_mark = sum([unit_info['relative_mark'] for unit_info in units_info])
    return total_mark, units_info

def get_units_info_from_course(course, user, db=None):
    db = db or get_db()
    data_course = {'user_id': user.pk,
                   'course_id': course.pk}
    marks_units = db.get_collection('marks_unit')
    return list(marks_units.find(data_course))

def get_course_mark(course, user, db=None):
    data_course = {'user_id': user.pk,
                   'course_id': course.pk}
    db = db or get_db()
    marks_course = db.get_collection('marks_course')
    mark_course_item = marks_course.find_one(data_course)
    if mark_course_item:
        total_mark = mark_course_item['mark']
    else:
        total_mark = 0
    return (total_mark, get_units_info_from_course(course, user, db=db))

def get_unit_mark(unit, user, db=None):
    data_unit = {   'user_id': user.pk,
                    'unit_id': unit.pk }
    db = db or get_db()
    mark_unit_item = db.get_collection('marks_unit').find(data_unit).limit(1)
    if mark_unit_item:
        mark_unit = mark_unit_item['mark']
    else:
        mark_unit = 0
    return mark_unit

def get_unit_relative_mark(unit, user, db=None):
    data_unit = {   'user_id': user.pk,
                    'unit_id': unit.pk }
    db = db or get_db()
    mark_unit_item = db.get_collection('marks_unit').find(data_unit).limit(1)
    if mark_unit_item:
        mark_unit = mark_unit_item['relative_mark']
    else:
        mark_unit = 0
    return mark_unit

def get_kqs_info_from_unit(unit, user, db=None):
    db = db or get_db()
    data_unit = {'user_id': user.pk,
                   'unit_id': unit.pk}
    marks_kqs = db.get_collection('marks_kq')
    return list(marks_kqs.find(data_unit))

def get_kq_mark(kq, user, db=None):
    data_unit = {   'user_id': user.pk,
                    'kq_id': kq.pk }
    db = db or get_db()
    mark_kq_item = db.get_collection('marks_kq').find(data_unit).limit(1)
    if mark_kq_item and mark_kq_item.count() > 0:
        mark_kq = mark_kq_item[0]['mark']
    else:
        mark_kq = 0

    return mark_kq

def get_kq_relative_mark(kq, user, db=None):
    data_unit = {   'user_id': user.pk,
                    'kq_id': kq.pk }
    db = db or get_db()
    mark_kq_item = db.get_collection('marks_kq').find(data_unit).limit(1)
    if mark_kq_item:
        mark_kq = mark_kq_item['relative_mark']
    else:
        mark_kq = 0
    return mark_kq
<commit_msg>Fix Unit not existing in migrate_marks<commit_after># -*- coding: utf-8 -*-
# Copyright 2012-2013 UNED
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from django.db.models import Sum

from moocng.mongodb import get_db

def calculate_question_mark(kq, question, user):

    """
    Calculate if the user answer is the correct one, and punctuate accordingly.
    If the user did the task right the platform gives a 10, if not, a 0.

    .. versionadded:: 0.1
    """
    db = get_db()
    answers = db.get_collection('answers')
    user_answer = answers.find_one({
        'user_id': user.id,
        'question_id': question.id
    })

    if user_answer:
        mark = question.is_correct(user_answer)
        return mark
    return 0.0

def calculate_peer_review_mark(kq, peer_review_assignment, user):

    """
    Calculate if the user has done the peer reviewed task. This is done by
    checking if the minimum reviews of the task have been done.

    .. versionadded:: 0.1
    """
    from moocng.peerreview.utils import kq_get_peer_review_score

    mark = kq_get_peer_review_score(kq, user,
                                    peer_review_assignment)
    if mark is None:
        mark = 0
    return mark

def calculate_kq_video_mark(kq, user):

    """
    Mark the video as viewed and give the user the punctuation.

    .. versionadded:: 0.1
    """
    if kq.kq_visited_by(user):
        return 10.0
    return 0.0

def calculate_kq_mark(kq, user):

    """
    Calculate is a answer was right or wrong, this is the main function that
    calls the others depending on the content (peerreview, normal, etc.)

    .. warning:: Don't use this in loops

    .. versionadded:: 0.1
    """
    from moocng.peerreview.models import PeerReviewAssignment
    mark = relative_mark = 0

    try:
        question = kq.question_set.get()
        # KQ has a question
        mark = calculate_question_mark(kq, question, user)
    except kq.question_set.model.DoesNotExist:
        try:
            # KQ has a peer review
            pra = kq.peerreviewassignment
            mark = calculate_peer_review_mark(kq, pra, user)
        except PeerReviewAssignment.DoesNotExist:
            # KQ hasn't a question or peer review
            mark = calculate_kq_video_mark(kq, user)
    relative_mark = normalize_kq_weight(kq) * mark / 100.0
    return (mark, relative_mark)

def normalize_kq_weight(kq, unit_kq_counter=None, total_weight_unnormalized=None):
    # KnowledgeQuantumResource does not send unit_kq_counter  [tastypie api]
    if unit_kq_counter is None:
        unit = kq.unit
        total_weight_unnormalized, unit_kq_counter, uni_kqs = get_unit_intermediate_calculations(unit)
    if total_weight_unnormalized == 0:
        if unit_kq_counter == 0:
            return 0
        else:
            return 100.0 / unit_kq_counter
    return (kq.weight * 100.0) / total_weight_unnormalized

def calculate_unit_mark(unit, user, normalized_unit_weight=None):
    """
    Calculate if a unit is approved.

    .. warning:: Don't use this in loops

    .. versionadded:: 0.1
    """

    if normalized_unit_weight is None:
        total_weight_unnormalized, unit_course_counter, course_units = get_course_intermediate_calculations(unit.course)
        normalized_unit_weight = normalize_unit_weight(unit, unit_course_counter, total_weight_unnormalized)
    unit_mark = 0
    kqs = get_kq_info_from_course(unit, user)
    for kq in kqs:
        unit_mark += kq['relative_mark']
    # print "Unit_mark: %d - normalized_unit_weight: %d, normalized_unit_mark: %d" % (unit_mark, normalized_unit_weight, (normalized_unit_weight * unit_mark) / 100.0)
    return (unit_mark, (normalized_unit_weight * unit_mark) / 100.0)

def get_kq_info_from_course(unit, user, db=None):
    db = db or get_db()
    data_unit = {'user_id': user.pk,
                 'unit_id': unit.pk}
    marks_kq = db.get_collection('marks_kq')
    return list(marks_kq.find(data_unit))

def normalize_unit_weight(unit, course_unit_counter, total_weight_unnormalized):
    # print "Unit: %s - Course_unit_counter: %d - total_weight_unnormalized: %d" % (unit, course_unit_counter, total_weight_unnormalized)
    if total_weight_unnormalized == 0:
        if course_unit_counter == 0 or not unit.is_scorable():
            return 0
        else:
            return 100.0 / course_unit_counter
    return (unit.weight * 100.0) / total_weight_unnormalized

def get_course_intermediate_calculations(course):
    course_units = course.unit_set.scorables()
    total_weight_unnormalized = course.unit_set.aggregate(Sum('weight'))['weight__sum']
    unit_course_counter = course_units.count()
    return (total_weight_unnormalized, unit_course_counter, course_units)

def get_unit_intermediate_calculations(unit):
    unit_kqs = unit.knowledgequantum_set.all()
    total_weight_unnormalized = unit_kqs.aggregate(Sum('weight'))['weight__sum']
    unit_kqs_counter = unit_kqs.count()
    return (total_weight_unnormalized, unit_kqs_counter, unit_kqs)

def calculate_course_mark(course, user):
    units_info = get_units_info_from_course(course, user)
    total_mark = sum([unit_info['relative_mark'] for unit_info in units_info])
    return total_mark, units_info

def get_units_info_from_course(course, user, db=None):
    db = db or get_db()
    data_course = {'user_id': user.pk,
                   'course_id': course.pk}
    marks_units = db.get_collection('marks_unit')
    return list(marks_units.find(data_course))

def get_course_mark(course, user, db=None):
    data_course = {'user_id': user.pk,
                   'course_id': course.pk}
    db = db or get_db()
    marks_course = db.get_collection('marks_course')
    mark_course_item = marks_course.find_one(data_course)
    if mark_course_item:
        total_mark = mark_course_item['mark']
    else:
        total_mark = 0
    return (total_mark, get_units_info_from_course(course, user, db=db))

def get_unit_mark(unit, user, db=None):
    data_unit = {   'user_id': user.pk,
                    'unit_id': unit.pk }
    db = db or get_db()
    mark_unit_item = db.get_collection('marks_unit').find(data_unit).limit(1)
    if mark_unit_item:
        mark_unit = mark_unit_item['mark']
    else:
        mark_unit = 0
    return mark_unit

def get_unit_relative_mark(unit, user, db=None):
    data_unit = {   'user_id': user.pk,
                    'unit_id': unit.pk }
    db = db or get_db()
    mark_unit_item = db.get_collection('marks_unit').find(data_unit).limit(1)
    if mark_unit_item:
        mark_unit = mark_unit_item['relative_mark']
    else:
        mark_unit = 0
    return mark_unit

def get_kqs_info_from_unit(unit, user, db=None):
    db = db or get_db()
    data_unit = {'user_id': user.pk,
                   'unit_id': unit.pk}
    marks_kqs = db.get_collection('marks_kq')
    return list(marks_kqs.find(data_unit))

def get_kq_mark(kq, user, db=None):
    data_unit = {   'user_id': user.pk,
                    'kq_id': kq.pk }
    db = db or get_db()
    mark_kq_item = db.get_collection('marks_kq').find(data_unit).limit(1)
    if mark_kq_item and mark_kq_item.count() > 0:
        mark_kq = mark_kq_item[0]['mark']
    else:
        mark_kq = 0

    return mark_kq

def get_kq_relative_mark(kq, user, db=None):
    data_unit = {   'user_id': user.pk,
                    'kq_id': kq.pk }
    db = db or get_db()
    mark_kq_item = db.get_collection('marks_kq').find(data_unit).limit(1)
    if mark_kq_item:
        mark_kq = mark_kq_item['relative_mark']
    else:
        mark_kq = 0
    return mark_kq
<|endoftext|>