<commit_before>#!/usr/bin/python3.2
# -*- coding: utf-8 -*-

from functions_core import Function, register
from core import server_config, format, version
from random import sample
import datetime
import google

@Function('ping')
def ping(args, source, target):
    """pong!"""
    return 'pong'

with open('eloges.txt') as file:
    sarah_adjs = file.read().split('\n')

with open('adjs.txt') as file:
    adjs = file.read().split('\n')

hatsu_adjs = ('execrable',
              'laide',
              'grosse',
              'abominable',
              'détestable',
              'épouvantable',
              'insalubre',
              'saccagée',
              'ravagée')

@Function('sarah')
def sarah(args, source, target):
    """vous dira qui est-ce... :)"""
    return 'la plus {0}'.format(sample(sarah_adjs, 1)[0])

@Function('hatsu', requestchans=True)
def hatsu(args, source, target, channels):
    """vous dira qui est-ce... :)"""
    if 'hatsu' not in channels[target].userdict.keys():
        return 'la plus {0}'.format(sample(hatsu_adjs, 1)[0])
    else:
        return 'la plus {0}'.format(sample(sarah_adjs, 1)[0])

@Function('eyecancer')
def eyecancer(args, source, target):
    """just try it :)"""
    return '13,10UNTZ2,3UNTZ2,7UNTZ2,7UNTZ6,13UNTZ12,5UNTZ4,10UNTZ11,6UNTZ9,13UNTZ4,13UNTZ3,11UNTZ3,7UNTZ7,9UNTZ6,10UNTZ9,2UNTZ10,9UNTZ10,7UNTZ4,11UNTZ3,13UNTZ12,11UNTZ9,6UNTZ2,11UNTZ13,7UNTZ3,9UNTZ13,10UNTZ2,10UNTZ8,2UNTZ10,5UNTZ9,10UNTZ9,4UNTZ6,4UNTZ6,9UNTZ7,8UNTZ8,13UNTZ5,11UNTZ10,5UNTZ8,10UNTZ5,10UNTZ2,7UNTZ12,8UNTZ2,8UNTZ9,12UNTZ4,10UNTZ6,3UNTZ2,6UNTZ11,6UNTZ5,13UNTZ8,3UNTZ11,4UNTZ2,11UNTZ6,7UNTZ'

@Function('g')
def search(args, source, target):
    """performs a search via Google"""
    if args is not None:
        q = google.SearchQuery(' '.join(args))
        try:
            r = google.query(q)
        except IndexError as e:
            return 'no results'
        else:
            return '{0}{1}{2} — {3}\n{4}\n{5}{6}{7}{8}'.format(format['bold'],
                                                               r.title,
                                                               format['reset'],
                                                               r.display_url,
                                                               r.abstract,
                                                               format['bold'],
                                                               format['underlined'],
                                                               r.link,
                                                               format['reset'])
    return 'no query specified'

@Function('yt')
def youtube(args, source, target):
    """performs a search on YouTube"""
    if args is not None:
        q = google.YoutubeQuery(' '.join(args))
        try:
            r = google.ytquery(q)
        except IndexError as e:
            return 'no results'
        else:
            return '{0}{1}{2} — {3}\n{4}\n{5}{6}http://youtu.be/{7}{8}'.format(format['bold'],
                                                                               r.title,
                                                                               format['reset'],
                                                                               r.channel,
                                                                               r.description,
                                                                               format['bold'],
                                                                               format['underlined'],
                                                                               r.id,
                                                                               format['reset'])
    return 'no query specified'

with open('pornos.txt') as file:
    pornos = file.read().split('\n')

@Function('film')
def film(args, source, target):
    """un nom de "film" au hasard"""
    return sample(pornos, 1)[0]

@Function('help')
def help(args, source, target):
    """provides help on commands"""
    if args is None: #showing all functions
        return 'commands are: {0}\nto know more about a particular command type {1}help cmdname'.format(', '.join(i.cmdname for i in register), server_config['commands']['cmdprefix'])
    elif len(args) != 1:
        return 'syntax is cmdname'
    else:
        for i in register:
            if i.cmdname == args[0].lower():
                if i.doc is None:
                    return 'command has no documentation yet'
                else:
                    return '{0}{1}{2}: {3}'.format(format['bold'], args[0].lower(), format['reset'], i.doc)
        return 'unknown command "{0}"'.format(args[0].lower())

@Function('quisuisje')
def quisuisje(args, source, target):
    """détermine avec exactitude qui vous êtes, ou plutôt ce que vous êtes"""
    return 'vous êtes plutôt...{0}'.format(adjs[hash(source.nick )%len(adjs)])

@Function('drugs')
def drugs(args, source, target):
    """provides a list of RC shops"""
    if target == '#psychonautfr':
        return 'what the hell do you think you\'re doing??'
    else:
        return 'http://nicolodouma.mooo.com/rc.html http://rcshops.pastebay.net/1279926'

@Function('error')
def error(args, source, target):
    """to test handling of exceptions"""
    raise RuntimeError('FATAL ERROR')

@Function('source')
def source(args, source, target):
    """prints the URL of the source code (on github)"""
    return '{0}source code{1}: https://github.com/suut/psychic-happiness/tree/v2/'.format(format['bold'], format['reset'])

@Function('version')
def version_(args, source, target):
    """prints the actual bot version"""
    return version

with open('drugs.txt') as file:
    list_drugs = file.read().split('\n')

@Function('dotd')
def dotd(args, source, target):
    """drug of the day :)"""
    seed = int('{0}{1}{2}'.format(datetime.datetime.today().day, datetime.datetime.today().month, datetime.datetime.today().year))
    return '{0}drug of the day{1}: {2}'.format(format['bold'],
                                               format['reset'],
                                               list_drugs[seed%len(list_drugs)])
<commit_msg>ajout d'une commande lapin pour faire plaisir à Versane<commit_after>#!/usr/bin/python3.2
# -*- coding: utf-8 -*-

from functions_core import Function, register
from core import server_config, format, version
from random import sample
import datetime
import google

@Function('ping')
def ping(args, source, target):
    """pong!"""
    return 'pong'

with open('eloges.txt') as file:
    sarah_adjs = file.read().split('\n')

with open('adjs.txt') as file:
    adjs = file.read().split('\n')

hatsu_adjs = ('execrable',
              'laide',
              'grosse',
              'abominable',
              'détestable',
              'épouvantable',
              'insalubre',
              'saccagée',
              'ravagée')

@Function('sarah')
def sarah(args, source, target):
    """vous dira qui est-ce... :)"""
    return 'la plus {0}'.format(sample(sarah_adjs, 1)[0])

@Function('hatsu', requestchans=True)
def hatsu(args, source, target, channels):
    """vous dira qui est-ce... :)"""
    if 'hatsu' not in channels[target].userdict.keys():
        return 'la plus {0}'.format(sample(hatsu_adjs, 1)[0])
    else:
        return 'la plus {0}'.format(sample(sarah_adjs, 1)[0])

@Function('eyecancer')
def eyecancer(args, source, target):
    """just try it :)"""
    return '13,10UNTZ2,3UNTZ2,7UNTZ2,7UNTZ6,13UNTZ12,5UNTZ4,10UNTZ11,6UNTZ9,13UNTZ4,13UNTZ3,11UNTZ3,7UNTZ7,9UNTZ6,10UNTZ9,2UNTZ10,9UNTZ10,7UNTZ4,11UNTZ3,13UNTZ12,11UNTZ9,6UNTZ2,11UNTZ13,7UNTZ3,9UNTZ13,10UNTZ2,10UNTZ8,2UNTZ10,5UNTZ9,10UNTZ9,4UNTZ6,4UNTZ6,9UNTZ7,8UNTZ8,13UNTZ5,11UNTZ10,5UNTZ8,10UNTZ5,10UNTZ2,7UNTZ12,8UNTZ2,8UNTZ9,12UNTZ4,10UNTZ6,3UNTZ2,6UNTZ11,6UNTZ5,13UNTZ8,3UNTZ11,4UNTZ2,11UNTZ6,7UNTZ'

@Function('g')
def search(args, source, target):
    """performs a search via Google"""
    if args is not None:
        q = google.SearchQuery(' '.join(args))
        try:
            r = google.query(q)
        except IndexError as e:
            return 'no results'
        else:
            return '{0}{1}{2} — {3}\n{4}\n{5}{6}{7}{8}'.format(format['bold'],
                                                               r.title,
                                                               format['reset'],
                                                               r.display_url,
                                                               r.abstract,
                                                               format['bold'],
                                                               format['underlined'],
                                                               r.link,
                                                               format['reset'])
    return 'no query specified'

@Function('yt')
def youtube(args, source, target):
    """performs a search on YouTube"""
    if args is not None:
        q = google.YoutubeQuery(' '.join(args))
        try:
            r = google.ytquery(q)
        except IndexError as e:
            return 'no results'
        else:
            return '{0}{1}{2} — {3}\n{4}\n{5}{6}http://youtu.be/{7}{8}'.format(format['bold'],
                                                                               r.title,
                                                                               format['reset'],
                                                                               r.channel,
                                                                               r.description,
                                                                               format['bold'],
                                                                               format['underlined'],
                                                                               r.id,
                                                                               format['reset'])
    return 'no query specified'

with open('pornos.txt') as file:
    pornos = file.read().split('\n')

@Function('film')
def film(args, source, target):
    """un nom de "film" au hasard"""
    return sample(pornos, 1)[0]

@Function('help')
def help(args, source, target):
    """provides help on commands"""
    if args is None: #showing all functions
        return 'commands are: {0}\nto know more about a particular command type {1}help cmdname'.format(', '.join(i.cmdname for i in register), server_config['commands']['cmdprefix'])
    elif len(args) != 1:
        return 'syntax is cmdname'
    else:
        for i in register:
            if i.cmdname == args[0].lower():
                if i.doc is None:
                    return 'command has no documentation yet'
                else:
                    return '{0}{1}{2}: {3}'.format(format['bold'], args[0].lower(), format['reset'], i.doc)
        return 'unknown command "{0}"'.format(args[0].lower())

@Function('quisuisje')
def quisuisje(args, source, target):
    """détermine avec exactitude qui vous êtes, ou plutôt ce que vous êtes"""
    return 'vous êtes plutôt...{0}'.format(adjs[hash(source.nick )%len(adjs)])

@Function('drugs')
def drugs(args, source, target):
    """provides a list of RC shops"""
    if target == '#psychonautfr':
        return 'what the hell do you think you\'re doing??'
    else:
        return 'http://rcshops.pastebay.net/1279926'

@Function('error')
def error(args, source, target):
    """to test handling of exceptions"""
    raise RuntimeError('FATAL ERROR')

@Function('source')
def source(args, source, target):
    """prints the URL of the source code (on github)"""
    return '{0}source code{1}: https://github.com/suut/psychic-happiness/tree/v2/'.format(format['bold'], format['reset'])

@Function('version')
def version_(args, source, target):
    """prints the actual bot version"""
    return version

with open('drugs.txt') as file:
    list_drugs = file.read().split('\n')

@Function('dotd')
def dotd(args, source, target):
    """drug of the day :)"""
    seed = int('{0}{1}{2}'.format(datetime.datetime.today().day, datetime.datetime.today().month, datetime.datetime.today().year))
    return '{0}drug of the day{1}: {2}'.format(format['bold'],
                                               format['reset'],
                                               list_drugs[seed%len(list_drugs)])

@Function('lapin')
def lapin(args, source, target):
    """lapin!!"""
    return 'celui qui a une grande..paire d\'oreilles'
<|endoftext|>


<commit_before># This is the homework 1 for algorith thinking
# containing two parts : pepresenting directed graph
# and computing degree distributions

# Representing directed graphs as shown
EX_GRAPH0 = {0: set([1, 2]), 1: set([]), 2: set([])}
EX_GRAPH1 = {0: set([1, 4, 5]), 1: set([2, 6]), 2: set([3]),
             3: set([0]), 4: set([1]), 5: set([2]), 6: set([])}
EX_GRAPH2 = {0: set([1, 4]), 1: set([2, 6]), 2: set([3, 7]),
             3: set([7]), 4: set([1]), 5: set([2]), 6: set([]),
             7: set([3]), 8: set([1, 2]), 9: set([0, 3, 4, 5, 6, 7])}

def make_complete_graph(num_nodes):
    # @param num_nodes is the number of nodes in the graph
    # @return a directed graph with num_nodes nodes and all possible edges
    digraph = {}
    if num_nodes <= 0:
        return digraph  # return a empty graph if num_nodes is not positive
    fullset = set(range(num_nodes))
    for dummy_num in fullset:
        digraph[dummy_num] = fullset - set(dummy_num)
    return digraph

def compute_in_degree(digraph):
    # @param digraph a directed graph represted as adjacent list(dict)
    # @return a dict with keys same as digraph and corresponding in degree
    indegree_dict = {}
    for dummy_val in digraph.values():
        for dummy_node in dummy_val:
            indegree_dict[dummy_node] = indegree_dict.get(dummy_node, 0) + 1
    return indegree_dict

def in_degree_distribution(digraph):
    # @param digraph a directed graph represted as adjacent list(dict)
    # @return a dict,keys as in-degree,val as number of nodes of that in-degree
    indegree_dist = {}
    indegree_by_nodes = compute_in_degree(digraph)
    for dummy_val in indegree_by_nodes.values():
        indegree_dist[dummy_val] = indegree_dist.get(dummy_val, 0) + 1
    return indegree_dist

if __name__ == '__main__':
    print in_degree_distribution(EX_GRAPH1)
<commit_msg>graphtest run through tests<commit_after>'''This is the homework 1 for algorith thinking
 containing two parts : pepresenting directed graph
and computing degree distributions'''

# Representing directed graphs as shown
EX_GRAPH0 = {0: set([1, 2]), 1: set([]), 2: set([])}
EX_GRAPH1 = {0: set([1, 4, 5]), 1: set([2, 6]), 2: set([3]),
             3: set([0]), 4: set([1]), 5: set([2]), 6: set([])}
EX_GRAPH2 = {0: set([1, 4, 5]), 1: set([2, 6]), 2: set([3, 7]),
             3: set([7]), 4: set([1]), 5: set([2]), 6: set([]),
             7: set([3]), 8: set([1, 2]), 9: set([0, 3, 4, 5, 6, 7])}

def make_complete_graph(num_nodes):
    '''@param num_nodes is the number of nodes in the graph
        @return a directed graph with num_nodes nodes and all possible edges'''
    digraph = {}
    if num_nodes <= 0:
        return digraph  # return a empty graph if num_nodes is not positive
    fullset = set(range(num_nodes))
    for dummy_num in fullset:
        digraph[dummy_num] = fullset - set([dummy_num])
    return digraph

def compute_in_degrees(digraph):
    '''@param digraph a directed graph represted as adjacent list(dict)
        @return a dict with keys same as digraph and corresponding in degree'''
    indegree_dict = {}
	for dummy_key in digraph.keys():
		indegree_dict[dummy_key] = 0
    for dummy_val in digraph.values():
        for dummy_node in dummy_val:
            indegree_dict[dummy_node] = indegree_dict.get(dummy_node, 0) + 1
    return indegree_dict

def in_degree_distribution(digraph):
    '''@param digraph a directed graph represted as adjacent list(dict)
        @return a dict,keys as in-degree,val as number of nodes of that in-degree'''
    indegree_dist = {}
    indegree_by_nodes = compute_in_degrees(digraph)
    for dummy_val in indegree_by_nodes.values():
        indegree_dist[dummy_val] = indegree_dist.get(dummy_val, 0) + 1
    return indegree_dist

if __name__ == '__main__':
    print in_degree_distribution(EX_GRAPH1)
<|endoftext|>


<commit_before>#!/usr/bin/env python

# KMHXcodeTools
# functions.py
# Ken M. Haggerty
# CREATED: 2017 Mar 09
# EDITED:  2017 May 01

##### IMPORTS

import re

##### PBXProj Order

### Constants

PBXGroupSectionChildrenKey = "children"
PBXGroupSectionNameKey = "name" # temp
PBXGroupSectionIdKey = "id"

### Regexes

PBXGroupSectionRegex = r"(^[\S\s]*)(\/\*\s*Begin\s+PBXGroup\s+section\s*\*\/s*[^\n]*\n)([\S\s]*)(\n\s*\/\*\s*End\s+PBXGroup\s+section\s*\*\/s*[^\n]*)([\S\s]*$)"
# 1 = Beginning of file
# 2 = PBXGroup section header
# 3 = PBXGroup section body
# 4 = PBXGroup section footer
# 5 = End of file

PBXGroupSectionGroupRegex = r"(.*=.*\{[^\}]*\}\;[\s]*)(\n|$)+"
# 1 = PBXGroup section
# 2 = (newline / end of file)

PBXGroupSectionIdRegex = r"^\s*(\w+)"
# 1 = PBXGroup ID

PBXGroupSectionChildrenRegex = r"children\s*=\s*\(([^\)\;]*)\)\;"
# 1 = PBXGroup children

PBXGroupSectionChildIdRegex = r"(^|\n)\s*(\w+)"
# 1 = (start of file / newline)
# 2 = PBXGroup child ID

PBXGroupSectionNameRegex = r"^.*\/\*\s*((\S+.*\.\S+)|\S+[^\*\/]*).*\*\/" # temp
# 1 = PBXGroup name
# 2 = (unused)

### Functions

def processPBXProjOrder(text):
    pbxGroupSectionBody = re.search(PBXGroupSectionRegex, text).group(3)
    pbxGroupSections = list(map(lambda x: x[0], re.findall(PBXGroupSectionGroupRegex, pbxGroupSectionBody)))
    elements = {}
    parentIds = set([])
    childrenIds = set([])
    for section in pbxGroupSections:
        sectionId = re.search(PBXGroupSectionIdRegex, section).group(1)
        childrenBody = re.search(PBXGroupSectionChildrenRegex, section).group(1)
        childIds = list(map(lambda x: x[1], re.findall(PBXGroupSectionChildIdRegex, childrenBody)))
        dictionary = {}
        if len(childIds) > 0:
            dictionary[PBXGroupSectionChildrenKey] = childIds
        try: # temp
            name = re.search(PBXGroupSectionNameRegex, section).group(1)
            dictionary[PBXGroupSectionNameKey] = name
        except Exception:
            pass
        elements[sectionId] = dictionary
        parentIds.update([sectionId])
        childrenIds.update(childIds)
    parents = parentIds - childrenIds
    pbxProjOrder = []
    for parent in parents:
        dictionary = generateChildren(parent, elements)
        pbxProjOrder.append(dictionary)
    return pbxProjOrder

def generateChildren(node, source):
    dictionary = {
        PBXGroupSectionIdKey : node
    }
    if PBXGroupSectionNameKey in source[node]: # temp
        dictionary[PBXGroupSectionNameKey] = source[node][PBXGroupSectionNameKey]
    children = source[node][PBXGroupSectionChildrenKey]
    i = 0
    while i < len(children):
        child = children[i]
        if child in source:
            children.pop(i)
            grandchildren = generateChildren(child, source)
            children.insert(i, grandchildren)
        i += 1
    dictionary[PBXGroupSectionChildrenKey] = children
    return dictionary

##### PBXBuildFile Section

### Functions

def updatePBXBuildFileSection(text, order):
    return text

##### PBXFileReference Section

### Functions

def updatePBXFileReferenceSection(text, order):
    return text

##### PBXFrameworksBuildPhase Section

### Functions

def updatePBXFrameworksBuildPhaseSection(text, order):
    return text

##### PBXGroup Section

### Functions

def updatePBXGroupSection(text, order):
    return text

##### PBXResourcesBuildPhase Section

### Functions

def updatePBXResourcesBuildPhaseSection(text, order):
    return text

##### PBXSourcesBuildPhase Section

### Functions

def updatePBXSourcesBuildPhaseSection(text, order):
    return text
<commit_msg>Adds ID from PBXBuildFileSection into processPBXProjOrder(text) output.<commit_after>#!/usr/bin/env python

# KMHXcodeTools
# functions.py
# Ken M. Haggerty
# CREATED: 2017 Mar 09
# EDITED:  2017 May 02

##### IMPORTS

import re

##### PBXProj Order

### Constants

PBXGroupSectionChildrenKey = "children"
PBXGroupSectionNameKey = "name" # temp
PBXGroupSectionIdKey = "fileRef"
PBXBuildSectionIdKey = "id"

### Regexes

PBXGroupSectionRegex = r"(^[\S\s]*)(\/\*\s*Begin\s+PBXGroup\s+section\s*\*\/s*[^\n]*\n)([\S\s]*)(\n\s*\/\*\s*End\s+PBXGroup\s+section\s*\*\/s*[^\n]*)([\S\s]*$)"
# 1 = Beginning of file
# 2 = PBXGroup section header
# 3 = PBXGroup section body
# 4 = PBXGroup section footer
# 5 = End of file

PBXGroupSectionGroupRegex = r"(^|\n)([^\n\w]*(\w*)\s*(\/\*\s*(.*)\s*\*\/){0,1}\s*=\s*(\{[^\}]*\})\s*;[^\n]*)"
# 1 = (start of file / newline)
# 2 = (value)
# 3 = PBXGroupSection fileRef
# 4 = (unused)
# 5 = PBXGroupSection name # temp
# 6 = PBXGroupSection dictionary

PBXGroupSectionChildrenRegex = r"children\s*=\s*\(([^\)\;]*)\)\;"
# 1 = PBXGroup children

PBXGroupSectionChildRegex = r"(^|\n)(\s*(\w*)\s*(\/\*\s*((\S+.*\.\S+)|\S+[^\*\/]*).*\*\/)\s*,[^\n]*)"
# 1 = (start of file / newline)
# 2 = (value)
# 3 = PBXGroupSection child fileRef
# 4 = PBXGroupSection name and directory # temp
# 5 = PBXGroupSection name # temp
# 6 = (unused)

PBXBuildFileSectionRegex = r"\/\*\s*Begin\s*PBXBuildFile\s*section\s*\*\/\n*([\S\s]*)\n*\/\*\s*End\s*PBXBuildFile\s*section\s*\*\/"
# 1 = PBXBuildFileSection body

PBXBuildFileSectionLineRegex = r"(^|\n)\s*(\w*).*=\s*\{.*fileRef\s*=\s*(\w+).*\};"
# 1 = (start of file / newline)
# 2 = PBXBuildFile ID
# 3 = PBXBuildFile fileRef

### Functions

def processPBXProjOrder(text):
    pbxGroupSectionBody = re.search(PBXGroupSectionRegex, text).group(3)
    pbxGroupSections = re.findall(PBXGroupSectionGroupRegex, pbxGroupSectionBody)
    pbxBuildFileSectionBody = re.search(PBXBuildFileSectionRegex, text).group(1)
    pbxBuildFileSectionLines = re.findall(PBXBuildFileSectionLineRegex, pbxBuildFileSectionBody)
    fileRefDictionary = {}
    for line in pbxBuildFileSectionLines:
        fileRef = line[2]
        fileId = line[1]
        fileRefDictionary[fileRef] = fileId
    elements = {}
    parentIds = set([])
    childrenIds = set([])
    for section in pbxGroupSections:
        fileRef = section[2]
        dictionary = section[5]
        children = re.search(PBXGroupSectionChildrenRegex, dictionary).group(1)
        children = re.findall(PBXGroupSectionChildRegex, children)
        childDictionaries = []
        for child in children:
            childFileRef = child[2]
            childName = child[4]
            dictionary = {
                PBXGroupSectionIdKey : childFileRef,
                PBXGroupSectionNameKey : childName
            }
            try:
                fileId = fileRefDictionary[childFileRef]
                dictionary[PBXBuildSectionIdKey] = fileId
            except Exception:
                pass
            childDictionaries.append(dictionary)
        children = list(map(lambda x: x[2], children))
        dictionary = {}
        if len(childDictionaries) > 0:
            dictionary[PBXGroupSectionChildrenKey] = childDictionaries
        try: # temp
            name = section[4]
            dictionary[PBXGroupSectionNameKey] = name
        except Exception:
            pass
        elements[fileRef] = dictionary
        parentIds.update([fileRef])
        childrenIds.update(children)
    parents = parentIds - childrenIds
    pbxProjOrder = []
    for parent in parents:
        dictionary = generateChildren(parent, elements)
        pbxProjOrder.append(dictionary)
    return pbxProjOrder

def generateChildren(node, source):
    dictionary = {
        PBXGroupSectionIdKey : node
    }
    if PBXGroupSectionNameKey in source[node]: # temp
        dictionary[PBXGroupSectionNameKey] = source[node][PBXGroupSectionNameKey]
    children = source[node][PBXGroupSectionChildrenKey]
    i = 0
    while i < len(children):
        child = children[i]
        childFileRef = child[PBXGroupSectionIdKey]
        if childFileRef in source:
            children.pop(i)
            grandchildren = generateChildren(childFileRef, source)
            children.insert(i, grandchildren)
        i += 1
    dictionary[PBXGroupSectionChildrenKey] = children
    return dictionary

##### PBXBuildFile Section

### Functions

def updatePBXBuildFileSection(text, order):
    return text

##### PBXFileReference Section

### Functions

def updatePBXFileReferenceSection(text, order):
    return text

##### PBXFrameworksBuildPhase Section

### Functions

def updatePBXFrameworksBuildPhaseSection(text, order):
    return text

##### PBXGroup Section

### Functions

def updatePBXGroupSection(text, order):
    return text

##### PBXResourcesBuildPhase Section

### Functions

def updatePBXResourcesBuildPhaseSection(text, order):
    return text

##### PBXSourcesBuildPhase Section

### Functions

def updatePBXSourcesBuildPhaseSection(text, order):
    return text
<|endoftext|>


<commit_before>import re
import random

from errors import InvalidStackContentsException
from iposTypes import *

def popArguments(stack, modeList, arity, unpack = True):
	"""
	Expects the stack, a modeList and an arity and returns the operands and the corrosponding mode  in the format
	[mode, operand1, operand2, ...]
	If unpack is True the values of the items are returned, otherwise the instances of the respective types are retuned
	The modeList has the following format:
	[{"types" : [int, str, ...], "name" : modeName}, ...]
	Each list element represents a mode in which the command can work depending on the argument types on the stack
	"""

	if len(stack) < arity:
		message = "Expected %s items on the stack, but the stack only contains %s!" % (arity, len(stack))
		raise InvalidStackContentsException(message)

	# Take the top arity items from the stack
	topStack = stack[-arity:]
	topStackTypes = [type(i) for i in topStack]

	# Loop through all the modes and takes the first on that matches the stack types
	modeName = None
	for mode in modeList:
		if all(map(lambda t: isinstance(t[0], t[1]) , zip(topStack, mode["types"]))):
			modeName = mode["name"]
			break

	if modeName:
		return [modeName] + [stack.pop().value if unpack else stack.pop() for i in range(arity)][::-1]
	else:
		typesList = [m["types"] for m in modeList]
		message =  "Excepted one of the types %s on the stack, but got %s" % (typesList, topStackTypes)
		raise InvalidStackContentsException(message)

def IClearStack(stack):
	"""Clears the stack"""
	del stack[:]

def IDuplicateTopStackItem(stack):
	modeList = [{
			"types" : [Item],
			"name" : "duplicate"
		},
	]

	M, A = popArguments(stack, modeList, 1, unpack=False)

	# Duplicate the top item on the stack
	if M == "duplicate":
		stack.append(A)
		stack.append(A)

def ICopyStackItem(stack):
	modeList = [{
			"types" : [Integer],
			"name" : "copy"
		},
	]

	M, A = popArguments(stack, modeList, 1, unpack=False)

	if M == "copy":
		result = stack[A % len(stack)]
		stack.append(result)

def ISwapTopStackItems(stack, unpack=False):
	modeList = [{
			"types" : [Item, Item],
			"name" : "swap"
		},
	]

	M, B, A = popArguments(stack, modeList, 2, unpack=False)

	if M == "swap":
		stack.append(A)
		stack.append(B)

def IRotateTopStack(stack, unpack=False):
	modeList = [{
			"types" : [Item, Item, Item],
			"name" : "rotate"
		},
	]

	M, C, B, A = popArguments(stack, modeList, 3)

	if M == "rotate":
		stack.append(B)
		stack.append(A)
		stack.append(C)

def IReverseStack(stack, unpack=False):
	"""Reverses the stack"""
	stack.reverse()

def IDiscardTopStackItem(stack):
	modeList = [{
			"types" : [Item],
			"name" : "discard"
		},
	]

	M, A = popArguments(stack, modeList, 1)

	# Top item already got popped, nothing to do
	if A == "discard":
		pass

		"""
The following functions take the stack as paramter, pop the needed arguments and push the result.
The stack gets mutated in place, so nothing is returned
A always refers to the top item, B to the item after that, etc.
"""

def IEval(stack):

	modeList = [{
			"types" : [String],
			"name" : "eval"
		},
	]

	M, A = popArguments(stack, modeList, 1)

	# Executes the numeric calculations in A and pushes the result as int
	if M == "eval":
		# only keep chars for numeric calculations
		allowedChars = "1234567890+-/*"
		result = "".join([c for c in A if c in allowedChars])

		# remove leading zeros in number literals
		result = re.sub(r"0+(\d+)", r"\1", result)

		# Replace float through integer division
		result = re.sub(r"[^/]/[^/]", "//", result)

		result = eval(result)

		stack.append(String(result))

def IReverse(stack):

	modeList = [{
			"types" : [String],
			"name" : "reverse"
		},
	]

	M, A = popArguments(stack, modeList, 1)

	# Reverses A
	if M == "reverse":
		result = A[::-1]

		stack.append(String(result))

def IStrip(stack):

	modeList = [{
			"types" : [String, String],
			"name" : "stripString"
		}, {
			"types" : [String, Integer],
			"name" : "stripInt"
		}
	]

	M, B, A = popArguments(stack, modeList, 2)

	# Remove leading and trailing  As from B
	if M == "stripString":
		result = B.strip(A)

		stack.append(result)

	# Remove A leading and trailing chars from B
	elif M == "stripInt":
		result = B[A : -A]

		stack.append(String(result))

def IWrap(stack):

	modeList = [{
			"types" : [String],
			"name" : "wrap"
		},
	]

	M, A = popArguments(stack, modeList, 1)

	# Remove all newlines from A
	if M == "wrap":
		result = "".join(re.split(r"\\n|\\r", A))

		stack.append(String(result))

def IReplace(stack):

	modeList = [{
			"types" : [String, String, String],
			"name" : "replace"
		},
	]

	M, C, B, A = popArguments(stack, modeList, 3)

	# Replaces all occurences of a regex pattern B with A in C
	if M == "replace":
		result = re.sub(B, A, C)

		stack.append(String(result))

def IMultiply(stack):

	modeList = [{
			"types" : [String, Integer],
			"name" : "multiply"
		},
	]

	M, B, A = popArguments(stack, modeList, 2)

	# Repeats every character in B A times
	if M == "multiply":
		result = "".join([c*A for c in B])

		stack.append(String(result))

def ISwapCase(stack):

	modeList = [{
			"types" : [String],
			"name" : "swapCase"
		},
	]

	M, A = popArguments(stack, modeList, 1)

	if M == "swapCase":
		result = A.swapcase()
		stack.append(String(result))

def IPushCommands(stack):

	modeList = [{
			"types" : [String],
			"name" : "pushCommands"
		},
	]

	M, A = popArguments(stack, modeList, 1)

	# Convert A to a Commands-object
	if M == "pushCommands":
		result = Commands(A)

		stack.append(result)

def IExecuteCommands(stack):
	from interpreter import run

	modeList = [{
		"types" : [Commands],
		"name" : "executeCommands"
		},
	]

	M, A = popArguments(stack, modeList, 1)

	# Execute the given commands using and manipulating the stack
	if M == "executeCommands":
		run(A, stack)

def applyCommands(commands, inputStr, rand = False):
	"""
	Helper function for the map commands.
	Executes the given commands with the given input-string and returns the joined stack.
	If random is True, then the commands only get executed with a 50% chance.
	"""
	from interpreter import run, joinStack

	stack = [String(inputStr)]

	if rand and random.choice([0, 1]) or not rand:
		result = joinStack(run(commands, stack))
	else:
		result = joinStack(stack)

	return result

def IApplyToChars(stack):

	modeList = [{
			"types" : [String, Commands],
			"name" : "applyToChars",
		}
	]

	M, B, A = popArguments(stack, modeList, 2)

	# Apply A to every character of B
	if M == "applyToChars":
		result = "".join(map(lambda c: applyCommands(A, c), B))

		stack.append(String(result))

def IApplyToParts(stack):

	modeList = [{
			"types" : [String, String, Commands],
			"name" : "applyToParts",
		}
	]

	M, C, B, A = popArguments(stack, modeList, 3)

	# Apply A to every element of C.split(B)
	if M == "applyToParts":
		result = B.join(map(lambda c: applyCommands(A, c), C.split(B)))

		stack.append(String(result))

def IApplyToPartsRandomly(stack):

	modeList = [{
			"types" : [String, String, Commands],
			"name" : "applyToPartsRandomly",
		}
	]

	M, C, B, A = popArguments(stack, modeList, 3)

	# Apply A to every element of C.split(B)
	if M == "applyToPartsRandomly":
		result = B.join(map(lambda c: applyCommands(A, c, rand = True), C.split(B)))

		stack.append(String(result))<commit_msg>Allowed empty strings as seperator in % and ?<commit_after>import re
import random

from errors import InvalidStackContentsException
from iposTypes import *

def popArguments(stack, modeList, arity, unpack = True):
	"""
	Expects the stack, a modeList and an arity and returns the operands and the corrosponding mode  in the format
	[mode, operand1, operand2, ...]
	If unpack is True the values of the items are returned, otherwise the instances of the respective types are retuned
	The modeList has the following format:
	[{"types" : [int, str, ...], "name" : modeName}, ...]
	Each list element represents a mode in which the command can work depending on the argument types on the stack
	"""

	if len(stack) < arity:
		message = "Expected %s items on the stack, but the stack only contains %s!" % (arity, len(stack))
		raise InvalidStackContentsException(message)

	# Take the top arity items from the stack
	topStack = stack[-arity:]
	topStackTypes = [type(i) for i in topStack]

	# Loop through all the modes and takes the first on that matches the stack types
	modeName = None
	for mode in modeList:
		if all(map(lambda t: isinstance(t[0], t[1]) , zip(topStack, mode["types"]))):
			modeName = mode["name"]
			break

	if modeName:
		return [modeName] + [stack.pop().value if unpack else stack.pop() for i in range(arity)][::-1]
	else:
		typesList = [m["types"] for m in modeList]
		message =  "Excepted one of the types %s on the stack, but got %s" % (typesList, topStackTypes)
		raise InvalidStackContentsException(message)

def IClearStack(stack):
	"""Clears the stack"""
	del stack[:]

def IDuplicateTopStackItem(stack):
	modeList = [{
			"types" : [Item],
			"name" : "duplicate"
		},
	]

	M, A = popArguments(stack, modeList, 1, unpack=False)

	# Duplicate the top item on the stack
	if M == "duplicate":
		stack.append(A)
		stack.append(A)

def ICopyStackItem(stack):
	modeList = [{
			"types" : [Integer],
			"name" : "copy"
		},
	]

	M, A = popArguments(stack, modeList, 1, unpack=False)

	if M == "copy":
		result = stack[A % len(stack)]
		stack.append(result)

def ISwapTopStackItems(stack, unpack=False):
	modeList = [{
			"types" : [Item, Item],
			"name" : "swap"
		},
	]

	M, B, A = popArguments(stack, modeList, 2, unpack=False)

	if M == "swap":
		stack.append(A)
		stack.append(B)

def IRotateTopStack(stack, unpack=False):
	modeList = [{
			"types" : [Item, Item, Item],
			"name" : "rotate"
		},
	]

	M, C, B, A = popArguments(stack, modeList, 3)

	if M == "rotate":
		stack.append(B)
		stack.append(A)
		stack.append(C)

def IReverseStack(stack, unpack=False):
	"""Reverses the stack"""
	stack.reverse()

def IDiscardTopStackItem(stack):
	modeList = [{
			"types" : [Item],
			"name" : "discard"
		},
	]

	M, A = popArguments(stack, modeList, 1)

	# Top item already got popped, nothing to do
	if A == "discard":
		pass

		"""
The following functions take the stack as paramter, pop the needed arguments and push the result.
The stack gets mutated in place, so nothing is returned
A always refers to the top item, B to the item after that, etc.
"""

def IEval(stack):

	modeList = [{
			"types" : [String],
			"name" : "eval"
		},
	]

	M, A = popArguments(stack, modeList, 1)

	# Executes the numeric calculations in A and pushes the result as int
	if M == "eval":
		# only keep chars for numeric calculations
		allowedChars = "1234567890+-/*"
		result = "".join([c for c in A if c in allowedChars])

		# remove leading zeros in number literals
		result = re.sub(r"0+(\d+)", r"\1", result)

		# Replace float through integer division
		result = re.sub(r"[^/]/[^/]", "//", result)

		result = eval(result)

		stack.append(String(result))

def IReverse(stack):

	modeList = [{
			"types" : [String],
			"name" : "reverse"
		},
	]

	M, A = popArguments(stack, modeList, 1)

	# Reverses A
	if M == "reverse":
		result = A[::-1]

		stack.append(String(result))

def IStrip(stack):

	modeList = [{
			"types" : [String, String],
			"name" : "stripString"
		}, {
			"types" : [String, Integer],
			"name" : "stripInt"
		}
	]

	M, B, A = popArguments(stack, modeList, 2)

	# Remove leading and trailing  As from B
	if M == "stripString":
		result = B.strip(A)

		stack.append(result)

	# Remove A leading and trailing chars from B
	elif M == "stripInt":
		result = B[A : -A]

		stack.append(String(result))

def IWrap(stack):

	modeList = [{
			"types" : [String],
			"name" : "wrap"
		},
	]

	M, A = popArguments(stack, modeList, 1)

	# Remove all newlines from A
	if M == "wrap":
		result = "".join(re.split(r"\\n|\\r", A))

		stack.append(String(result))

def IReplace(stack):

	modeList = [{
			"types" : [String, String, String],
			"name" : "replace"
		},
	]

	M, C, B, A = popArguments(stack, modeList, 3)

	# Replaces all occurences of a regex pattern B with A in C
	if M == "replace":
		result = re.sub(B, A, C)

		stack.append(String(result))

def IMultiply(stack):

	modeList = [{
			"types" : [String, Integer],
			"name" : "multiply"
		},
	]

	M, B, A = popArguments(stack, modeList, 2)

	# Repeats every character in B A times
	if M == "multiply":
		result = "".join([c*A for c in B])

		stack.append(String(result))

def ISwapCase(stack):

	modeList = [{
			"types" : [String],
			"name" : "swapCase"
		},
	]

	M, A = popArguments(stack, modeList, 1)

	if M == "swapCase":
		result = A.swapcase()
		stack.append(String(result))

def IPushCommands(stack):

	modeList = [{
			"types" : [String],
			"name" : "pushCommands"
		},
	]

	M, A = popArguments(stack, modeList, 1)

	# Convert A to a Commands-object
	if M == "pushCommands":
		result = Commands(A)

		stack.append(result)

def IExecuteCommands(stack):
	from interpreter import run

	modeList = [{
		"types" : [Commands],
		"name" : "executeCommands"
		},
	]

	M, A = popArguments(stack, modeList, 1)

	# Execute the given commands using and manipulating the stack
	if M == "executeCommands":
		run(A, stack)

def applyCommands(commands, inputStr, rand = False):
	"""
	Helper function for the map commands.
	Executes the given commands with the given input-string and returns the joined stack.
	If random is True, then the commands only get executed with a 50% chance.
	"""
	from interpreter import run, joinStack

	stack = [String(inputStr)]

	if rand and random.choice([0, 1]) or not rand:
		result = joinStack(run(commands, stack))
	else:
		result = joinStack(stack)

	return result

def IApplyToChars(stack):

	modeList = [{
			"types" : [String, Commands],
			"name" : "applyToChars",
		}
	]

	M, B, A = popArguments(stack, modeList, 2)

	# Apply A to every character of B
	if M == "applyToChars":
		result = "".join(map(lambda c: applyCommands(A, c), B))

		stack.append(String(result))

def IApplyToParts(stack):

	modeList = [{
			"types" : [String, String, Commands],
			"name" : "applyToParts",
		}
	]

	M, C, B, A = popArguments(stack, modeList, 3)

	# Apply A to every element of C.split(B)
	if M == "applyToParts":
		splittedStr = C if B == "" else C.split(B)

		result = B.join(map(lambda c: applyCommands(A, c), splittedStr))

		stack.append(String(result))

def IApplyToPartsRandomly(stack):

	modeList = [{
			"types" : [String, String, Commands],
			"name" : "applyToPartsRandomly",
		}
	]

	M, C, B, A = popArguments(stack, modeList, 3)

	# Apply A to every element of C.split(B)
	if M == "applyToPartsRandomly":
		splittedStr = C if B == "" else C.split(B)

		result = B.join(map(lambda c: applyCommands(A, c, rand = True), splittedStr))

		stack.append(String(result))<|endoftext|>


<commit_before>def add(a, b):
	return a+b

c= add(3,4)
print c

def sub(a, b):
	return a-b

d= sub(5,3)
print d

def mul(a,b):
	return a*b

e= mul(4, 4)
print e

def div(a,b):
	return a/b

f= div(2.0,3)
print f

def hours_from_seconds(a,b):
	return a/b

g= hours_from_seconds(86400, 3600)
print g

def circle_area(r):
	return 3.14159265359 * (r**2)
print circle_area(5)
<commit_msg>defined more functions<commit_after>def add(a, b): #defined a function with variables through additon
	return a+b

c= add(3,4)
print c

def sub(a, b): #defined a function with variables through subtraction
	return a-b

d= sub(5,3)
print d

def mul(a,b): #defined a function with variables through multiplication
	return a*b

e= mul(4, 4)
print e

def div(a,b): #defined a function with variables through division
	return a/b

f= div(2.0,3)
print f

def hours_from_seconds(a,b): #defined a function by changing seconds to hours
	return a/b

g= hours_from_seconds(86400, 3600)
print g

import math
def circle_area(r): #defined a function by returning an area of a circle
	return math.pi * (r**2)
print circle_area(5)

import math
def sphere_volume (a): #defined a function by representing an argument and changing it into the volume
	return 1.33333333333 * math.pi * (a**3)
print sphere_volume (5)

def avg_volume (a,b):
	return
h= avg_volume (10,20)
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
##############################################################################
# OEmetaSL
#
# Author: Anael LORIMIER <anael.lorimier@xcg-consulting.fr>
#         Vincent Lhote-Hatakeyama <vincent.lhote@xcg-consulting.fr>
##############################################################################
{
    'name': "OEmetaSL",
    'version': '0.3',
    'author': "XCG Consulting",
    'category': "Custom Module",
    'description': """This module handles methods to modify OpenERP base
    methods.
    """,
    'website': "http://www.openerp-experts.com/",
    'depends': [
        'base',
    ],
    'installable': True,
    'active': False,
}
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
<commit_msg>Bumped to version 0.4 (stable)<commit_after># -*- coding: utf-8 -*-
##############################################################################
# OEmetaSL
#
# Author: Anael LORIMIER <anael.lorimier@xcg-consulting.fr>
#         Vincent Lhote-Hatakeyama <vincent.lhote@xcg-consulting.fr>
##############################################################################
{
    'name': "OEmetaSL",
    'version': '0.4',
    'author': "XCG Consulting",
    'category': "Custom Module",
    'description': """This module handles methods to modify OpenERP base
    methods.
    """,
    'website': "http://www.openerp-experts.com/",
    'depends': [
        'base',
    ],
    'installable': True,
    'active': False,
}
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
<|endoftext|>


<commit_before>"""
This is the dashboard of CEA
"""
from __future__ import division
from __future__ import print_function

import os
import cea.config
import cea.inputlocator
from cea.plots.solar_potential.solar_radiation_curve import solar_radiation_curve
from cea.plots.solar_potential.solar_radiation import solar_radiation_district
from cea.plots.solar_potential.solar_radiation_monthly import solar_radiation_district_monthly
from cea.utilities import epwreader
import pandas as pd
import numpy as np

__author__ = "Jimeno A. Fonseca"
__copyright__ = "Copyright 2018, Architecture and Building Systems - ETH Zurich"
__credits__ = ["Jimeno A. Fonseca"]
__license__ = "MIT"
__version__ = "0.1"
__maintainer__ = "Daren Thomas"
__email__ = "cea@arch.ethz.ch"
__status__ = "Production"

def data_processing(analysis_fields, buildings, locator, weather):

    # get extra data of weather and date
    weather_data = epwreader.epw_reader(weather)[["date", "drybulb_C", "wetbulb_C", "skytemp_C"]]

    # get data of buildings
    input_data_not_aggregated_MW = []
    for i, building in enumerate(buildings):
        df_not_aggregated = {}
        geometry = pd.read_csv(locator.get_radiation_metadata(building))
        geometry['code'] = geometry['TYPE'] + '_' + geometry['orientation']
        insolation = pd.read_json(locator.get_radiation_building(building))
        if i == 0:
            df = {}
            for field in analysis_fields:
                select_sensors = geometry.loc[geometry['code'] == field].set_index('SURFACE')
                df_not_aggregated[field] = np.array([select_sensors.ix[surface, 'AREA_m2'] * insolation[surface] for surface in select_sensors.index]).sum(
                    axis=0)  # W
                df[field] = np.array([select_sensors.ix[surface, 'AREA_m2'] * insolation[surface] for surface in select_sensors.index]).sum(axis=0)# W

            # add date and resample into months
            df_not_aggregated = pd.DataFrame(df_not_aggregated)
            resample_data_frame = (df_not_aggregated.sum(axis=0) / 1000000).round(2)  # into MWh
            input_data_not_aggregated_MW = pd.DataFrame({building: resample_data_frame}, index=resample_data_frame.index).T

        else:
            for field in analysis_fields:
                select_sensors = geometry.loc[geometry['code'] == field].set_index('SURFACE')
                df[field] = df[field] + np.array([select_sensors.ix[surface, 'AREA_m2'] * insolation[surface] for surface in select_sensors.index]).sum(axis=0)# W
                df_not_aggregated[field] = np.array([select_sensors.ix[surface, 'AREA_m2'] * insolation[surface] for surface in select_sensors.index]).sum(
                    axis=0)  # W

            # add date and resample into months
            df_not_aggregated = pd.DataFrame(df_not_aggregated)
            resample_data_frame = (df_not_aggregated.sum(axis=0) / 1000000).round(2)  # into MWh
            intermediate_dataframe = pd.DataFrame({building: resample_data_frame}, index=resample_data_frame.index).T
            input_data_not_aggregated_MW = input_data_not_aggregated_MW.append(intermediate_dataframe)

    # round and add weather vars and date
    input_data_aggregated_kW = (pd.DataFrame(df) / 1000).round(2) # in kW
    input_data_aggregated_kW["T_out_dry_C"] = weather_data["drybulb_C"].values
    input_data_aggregated_kW["DATE"] = weather_data["date"]

    return input_data_aggregated_kW, input_data_not_aggregated_MW

def dashboard(locator, config):

    # Local Variables
    # GET LOCAL VARIABLES
    weather = config.weather
    buildings = config.plots.buildings

    if buildings == []:
        buildings = pd.read_csv(locator.get_total_demand()).Name.values

    #CREATE RADIATION CURVE
    output_path = locator.get_timeseries_plots_file("District" + '_solar_radiation_curve')
    title = "Solar Radiation Curve for District"
    analysis_fields = ['windows_east', 'windows_west', 'windows_south', 'windows_north',
                       'walls_east','walls_west','walls_south','walls_north','roofs_top']
    input_data_aggregated_kW, input_data_not_aggregated_MW = data_processing(analysis_fields, buildings, locator, weather)
    solar_radiation_curve(input_data_aggregated_kW, analysis_fields+["T_out_dry_C"], title, output_path)

    #CREATE RADIATION CURVE_MONTHLY
    output_path = locator.get_timeseries_plots_file("District" + '_solar_radiation_monthly')
    title = "Solar Radiation for District"
    analysis_fields = ['windows_east', 'windows_west', 'windows_south', 'windows_north',
                       'walls_east','walls_west','walls_south','walls_north','roofs_top']
    solar_radiation_district_monthly(input_data_aggregated_kW, analysis_fields, title, output_path)

    #CREATE RADIATION BUILDINGS
    output_path = locator.get_timeseries_plots_file("District" + '_solar_radiation')
    title = "Solar Radiation for District"
    analysis_fields = ['windows_east', 'windows_west', 'windows_south', 'windows_north',
                       'walls_east','walls_west','walls_south','walls_north','roofs_top']
    solar_radiation_district(input_data_not_aggregated_MW, analysis_fields, title, output_path)

def main(config):
    locator = cea.inputlocator.InputLocator(config.scenario)

    # print out all configuration variables used by this script
    print("Running dashboard with scenario = %s" % config.scenario)

    dashboard(locator, config)

if __name__ == '__main__':
    main(cea.config.Configuration())
<commit_msg>refactoring<commit_after>"""
This is the dashboard of CEA
"""
from __future__ import division
from __future__ import print_function

import os
import cea.config
import cea.inputlocator
from cea.plots.solar_potential.solar_radiation_curve import solar_radiation_curve
from cea.plots.solar_potential.solar_radiation import solar_radiation_district
from cea.plots.solar_potential.solar_radiation_monthly import solar_radiation_district_monthly
from cea.utilities import epwreader
import pandas as pd
import numpy as np
import time

__author__ = "Jimeno A. Fonseca"
__copyright__ = "Copyright 2018, Architecture and Building Systems - ETH Zurich"
__credits__ = ["Jimeno A. Fonseca"]
__license__ = "MIT"
__version__ = "0.1"
__maintainer__ = "Daren Thomas"
__email__ = "cea@arch.ethz.ch"
__status__ = "Production"

def plots_main(locator, config):

    # initialize timer
    t0 = time.clock()

    # Local Variables
    buildings = config.plots.buildings
    buildings = ['B01']
    weather = config.weather

    # initialize class
    plots = Plots(locator, buildings, weather)

    if len(buildings) == 1:  # when only one building is passed.
        plots.solar_radiation_curve()
        plots.solar_radiation_district_monthly()
        plots.solar_radiation_district()

    else:  # when two or more buildings are passed
        # generate plots
        plots.solar_radiation_curve()
        plots.solar_radiation_district_monthly()
        plots.solar_radiation_district()

    # print execution time
    time_elapsed = time.clock() - t0
    print('done - time elapsed: %d.2f seconds' % time_elapsed)

    return

class Plots():

    def __init__(self, locator, buildings, weather):
        # local variables
        self.locator = locator
        self.weather = weather
        self.analysis_fields = ['windows_east', 'windows_west', 'windows_south', 'windows_north',
                           'walls_east', 'walls_west', 'walls_south', 'walls_north', 'roofs_top']
        self.buildings = self.preprocess_buildings(buildings)
        self.data_processed_district = self.preprocessing(self.analysis_fields, self.buildings, self.locator, self.weather)
        self.plot_title_tail = self.preprocess_plot_title(buildings)
        self.plot_output_path_header = self.preprocess_plot_outputpath(buildings)

    def preprocess_buildings(self, buildings):
        if buildings == []:  # get all buildings of the district if not indicated a single building
            return self.locator.get_zone_building_names()
        else:
            return buildings

    def preprocess_plot_outputpath(self, buildings):
        if buildings == []:  # get all buildings of the district if not indicated a single building
            return "District"
        elif len(buildings) == 1:
            return "Building_" + str(buildings[0])
        else:
            return "District"

    def preprocess_plot_title(self, buildings):
        if buildings == []:  # get all buildings of the district if not indicated a single building
            return " for District"
        elif len(buildings) == 1:
            return " for Building " + str(buildings[0])
        else:
            return " for Selected Buildings"

    def preprocessing(self, analysis_fields, buildings, locator, weather):

        # get extra data of weather and date
        weather_data = epwreader.epw_reader(weather)[["date", "drybulb_C", "wetbulb_C", "skytemp_C"]]

        # get data of buildings
        input_data_not_aggregated_MW = []
        for i, building in enumerate(buildings):
            df_not_aggregated = {}
            geometry = pd.read_csv(locator.get_radiation_metadata(building))
            geometry['code'] = geometry['TYPE'] + '_' + geometry['orientation']
            insolation = pd.read_json(locator.get_radiation_building(building))
            if i == 0:
                df = {}
                for field in analysis_fields:
                    select_sensors = geometry.loc[geometry['code'] == field].set_index('SURFACE')
                    df_not_aggregated[field] = np.array(
                        [select_sensors.ix[surface, 'AREA_m2'] * insolation[surface] for surface in
                         select_sensors.index]).sum(
                        axis=0)  # W
                    df[field] = np.array([select_sensors.ix[surface, 'AREA_m2'] * insolation[surface] for surface in
                                          select_sensors.index]).sum(axis=0)  # W

                # add date and resample into months
                df_not_aggregated = pd.DataFrame(df_not_aggregated)
                resample_data_frame = (df_not_aggregated.sum(axis=0) / 1000000).round(2)  # into MWh
                input_data_not_aggregated_MW = pd.DataFrame({building: resample_data_frame},
                                                            index=resample_data_frame.index).T

            else:
                for field in analysis_fields:
                    select_sensors = geometry.loc[geometry['code'] == field].set_index('SURFACE')
                    df[field] = df[field] + np.array(
                        [select_sensors.ix[surface, 'AREA_m2'] * insolation[surface] for surface in
                         select_sensors.index]).sum(axis=0)  # W
                    df_not_aggregated[field] = np.array(
                        [select_sensors.ix[surface, 'AREA_m2'] * insolation[surface] for surface in
                         select_sensors.index]).sum(
                        axis=0)  # W

                # add date and resample into months
                df_not_aggregated = pd.DataFrame(df_not_aggregated)
                resample_data_frame = (df_not_aggregated.sum(axis=0) / 1000000).round(2)  # into MWh
                intermediate_dataframe = pd.DataFrame({building: resample_data_frame},
                                                      index=resample_data_frame.index).T
                input_data_not_aggregated_MW = input_data_not_aggregated_MW.append(intermediate_dataframe)

        # round and add weather vars and date
        input_data_aggregated_kW = (pd.DataFrame(df) / 1000).round(2)  # in kW
        input_data_aggregated_kW["T_out_dry_C"] = weather_data["drybulb_C"].values
        input_data_aggregated_kW["DATE"] = weather_data["date"]

        return {'input_data_aggregated_kW': input_data_aggregated_kW, "input_data_not_aggregated_MW":input_data_not_aggregated_MW}

    def solar_radiation_curve(self):
        output_path = self.locator.get_timeseries_plots_file(self.plot_output_path_header  + '_solar_radiation_curve')
        title = "Hourly Solar Radiation Curve" + self.plot_title_tail
        data = self.data_processed_district['input_data_aggregated_kW']
        plot = solar_radiation_curve(data, self.analysis_fields + ["T_out_dry_C"], title, output_path)

        return plot

    def solar_radiation_district_monthly(self):
        output_path = self.locator.get_timeseries_plots_file(self.plot_output_path_header  + '_solar_radiation_monthly')
        title = "Monthly Solar Radiation" + self.plot_title_tail
        data = self.data_processed_district['input_data_aggregated_kW']
        plot = solar_radiation_district_monthly(data, self.analysis_fields, title, output_path)

        return plot

    def solar_radiation_district(self):
        output_path = self.locator.get_timeseries_plots_file(self.plot_output_path_header  + '_solar_radiation_per_building')
        title = "Yearly Solar Radiation" + self.plot_title_tail
        data = self.data_processed_district['input_data_not_aggregated_MW']
        plot = solar_radiation_district(data, self.analysis_fields, title, output_path)

        return plot

def main(config):
    locator = cea.inputlocator.InputLocator(config.scenario)

    print("Running plots with scenario = %s" % config.scenario)

    plots_main(locator, config)

if __name__ == '__main__':
    main(cea.config.Configuration())
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
##############################################################################
#
#    Account Analytic Online, for OpenERP
#    Copyright (C) 2013 XCG Consulting (www.xcg-consulting.fr)
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU Affero General Public License as
#    published by the Free Software Foundation, either version 3 of the
#    License, or (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU Affero General Public License for more details.
#
#    You should have received a copy of the GNU Affero General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################

{
    "name" : "Analytic Structure",
    "version" : "1.2",
    "author" : "XCG Consulting",
    "category": 'Dependency',
    "description": """
This module allows to use several analytic dimensions through a structure related
to an object model.
==================================================================================
    """,
    'website': 'http://www.openerp-experts.com',
    "depends" : ['base'],
    "data": [
        'security/security.xml',
        'security/ir.model.access.csv',
        'security/record_rules.xml',
        'analytic_dimension.xml',
    ],
    #'demo_xml': [],
    'test': [],
    'installable': True,
    'active': False,
}

# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
<commit_msg>Bumped version to 1.2.1 (dev)<commit_after># -*- coding: utf-8 -*-
##############################################################################
#
#    Account Analytic Online, for OpenERP
#    Copyright (C) 2013 XCG Consulting (www.xcg-consulting.fr)
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU Affero General Public License as
#    published by the Free Software Foundation, either version 3 of the
#    License, or (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU Affero General Public License for more details.
#
#    You should have received a copy of the GNU Affero General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################

{
    "name" : "Analytic Structure",
    "version" : "1.2.1",
    "author" : "XCG Consulting",
    "category": 'Dependency',
    "description": """
This module allows to use several analytic dimensions through a structure related
to an object model.
==================================================================================
    """,
    'website': 'http://www.openerp-experts.com',
    "depends" : ['base'],
    "data": [
        'security/security.xml',
        'security/ir.model.access.csv',
        'security/record_rules.xml',
        'analytic_dimension.xml',
    ],
    #'demo_xml': [],
    'test': [],
    'installable': True,
    'active': False,
}

# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
<|endoftext|>


<commit_before>from reportlab.platypus import *
from reportlab.lib.units import *

class MyIndenter(Indenter):
    # Bugs in reportlab?
    def draw(self):
        pass
    width=0
    height=0

class OutlineEntry(Flowable):
    def __init__(self,label,text,level=0,snum=None):
        '''* label is a unique label.
           * text is the text to be displayed in the outline tree
           * level is the level, 0 is outermost, 1 is child of 0, etc.
        '''
        if label is None: # it happens
            self.label=text.replace(u'\xa0', ' ').strip(
                ).replace(' ', '_').encode('ascii', 'replace')
        else:
            self.label=label.strip()
        self.text=text.strip()
        self.level=int(level)
        self.snum=snum
        Flowable.__init__(self)

    def wrap(self,w,h):
        '''This takes no space'''
        return (0,0)

    def draw(self):
        self.canv.bookmarkPage(self.label)
        self.canv.sectName=self.text
        if self.snum is not None:
            self.canv.sectNum=self.snum
        else:
            self.canv.sectNum=""
        self.canv.addOutlineEntry(self.text,
                                  self.label,
                                  self.level, False)

    def __repr__(self):
        return "OutlineEntry (label=%s , text=%s , level=%d) \n"%(self.label,self.text,self.level)

class Separation(Flowable):
    """A simple
-like flowable"""

    def wrap(self,w,h):
        self.w=w
        return (w,1*cm)

    def draw(self):
        self.canv.line(0,0.5*cm,self.w,0.5*cm)
<commit_msg>Cosmetic fixes in the code<commit_after># -*- coding: utf-8 -*-
#$HeadURL$
#$LastChangedDate$
#$LastChangedRevision$
__docformat__ = 'reStructuredText'

from reportlab.platypus import *
from reportlab.lib.units import *

class MyIndenter(Indenter):
    '''I can't remember why this exists'''
    def draw(self):
        pass
    width=0
    height=0

class OutlineEntry(Flowable):
    '''Creates outline entries in the PDF TOC'''
    def __init__(self,label,text,level=0,snum=None):
        '''* label is a unique label.
           * text is the text to be displayed in the outline tree
           * level is the level, 0 is outermost, 1 is child of 0, etc.
        '''
        if label is None: # it happens
            self.label=text.replace(u'\xa0', ' ').strip(
                ).replace(' ', '_').encode('ascii', 'replace')
        else:
            self.label=label.strip()
        self.text=text.strip()
        self.level=int(level)
        self.snum=snum
        Flowable.__init__(self)

    def wrap(self,w,h):
        '''This takes no space'''
        return (0,0)

    def draw(self):
        self.canv.bookmarkPage(self.label)
        self.canv.sectName=self.text
        if self.snum is not None:
            self.canv.sectNum=self.snum
        else:
            self.canv.sectNum=""
        self.canv.addOutlineEntry(self.text,
                                  self.label,
                                  self.level, False)

    def __repr__(self):
        return "OutlineEntry (label=%s , text=%s , level=%d) \n"%(self.label,self.text,self.level)

class Separation(Flowable):
    """A simple
-like flowable"""

    def wrap(self,w,h):
        self.w=w
        return (w,1*cm)

    def draw(self):
        self.canv.line(0,0.5*cm,self.w,0.5*cm)
<|endoftext|>


<commit_before>#!/usr/bin/env python
#
# 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 __future__ import absolute_import

import argparse
import fileinput
import os
import re
import subprocess
import sys

from bashate import messages

MESSAGES = messages.MESSAGES

def not_continuation(line):
    return not re.search('\\\\$', line)

def check_for_do(line, report):
    if not_continuation(line):
        match = re.match('^\s*(for|while|until)\s', line)
        if match:
            operator = match.group(1).strip()
            if operator == "for":
                # "for i in ..." and "for ((" is bash, but
                # "for (" is likely from an embedded awk script,
                # so skip it
                if re.search('for \([^\(]', line):
                    return
            if not re.search(';\s*do$', line):
                report.print_error((MESSAGES['E010'].msg % operator), line)

def check_if_then(line, report):
    if not_continuation(line):
        if re.search('^\s*(el)?if \[', line):
            if not re.search(';\s*then$', line):
                report.print_error(MESSAGES['E011'].msg, line)

def check_no_trailing_whitespace(line, report):
    if re.search('[ \t]+$', line):
        report.print_error(MESSAGES['E001'].msg, line)

def check_no_long_lines(line, report):
    if len(line.rstrip("\r\n")) > 79:
        report.print_error(MESSAGES['E006'].msg, line)

def check_indents(line, report):
    m = re.search('^(?P<indent>[ \t]+)', line)
    if m:
        if re.search('\t', m.group('indent')):
            report.print_error(MESSAGES['E002'].msg, line)
        elif (len(m.group('indent')) % 4) != 0:
            report.print_error(MESSAGES['E003'].msg, line)

def check_function_decl(line, report):
    failed = False
    if line.startswith("function"):
        if not re.search('^function [\w-]* \{$', line):
            failed = True
    else:
        # catch the case without "function", e.g.
        # things like '^foo() {'
        if re.search('^\s*?\(\)\s*?\{', line):
            failed = True

    if failed:
        report.print_error(MESSAGES['E020'].msg, line)

def starts_multiline(line):
    # note, watch out for <<EOF and <<'EOF' ; quotes in the
    # deliminator are part of syntax
    m = re.search("[^<]<<\s*([\'\"]?)(?P<token>\w+)([\'\"]?)", line)
    return m.group('token') if m else False

def end_of_multiline(line, token):
    return token and re.search("^%s\s*$" % token, line)

def check_arithmetic(line, report):
    if "$[" in line:
        report.print_error(MESSAGES['E041'].msg, line)

def check_local_subshell(line, report):
    if line.lstrip().startswith('local ') and \
       ("=$(" in line or "=`" in line):
        report.print_error(MESSAGES['E042'].msg, line)

def check_hashbang(line, filename, report):
    # this check only runs on the first line
    #  maybe this should check for shell?
    if not line.startswith("#!") and not filename.endswith(".sh"):
        report.print_error(MESSAGES['E005'].msg, line)

def check_syntax(filename, report):
    # run the file through "bash -n" to catch basic syntax errors and
    # other warnings
    matches = []

    # sample lines we want to match:
    # foo.sh: line 4: warning: \
    #    here-document at line 1 delimited by end-of-file (wanted `EOF')
    # foo.sh: line 9: syntax error: unexpected end of file
    # foo.sh: line 7: syntax error near unexpected token `}'
    #
    # i.e. consistency with ":"'s isn't constant, so just do our
    # best...
    r = re.compile(
        '^(?P<file>.*): line (?P<lineno>[0-9]+): (?P<error>.*)')
    # we are parsing the error message, so force it to ignore the
    # system locale so we don't get messages in another language
    bash_environment = os.environ
    bash_environment['LC_ALL'] = 'C'
    proc = subprocess.Popen(
        ['bash', '-n', filename], stdout=subprocess.PIPE,
        stderr=subprocess.PIPE, env=bash_environment)
    outputs = proc.communicate()

    for line in outputs[1].split('\n'):
        m = r.match(line)
        if m:
            matches.append(m)

    for m in matches:
        if 'syntax error' in m.group('error'):
            msg = '%s: %s' % (MESSAGES['E040'].msg, m.group('error'))
            report.print_error(msg, filename=filename,
                               filelineno=int(m.group('lineno')))

        # Matching output from bash warning about here-documents not
        # ending.
        # FIXME: are there other warnings that might come out
        # with "bash -n"?  A quick scan of the source code suggests
        # no, but there might be other interesting things we could
        # catch.
        if 'warning:' in m.group('error'):
            if 'delimited by end-of-file' in m.group('error'):
                start = re.match('^.*line (?P<start>[0-9]+).*$',
                                 m.group('error'))
                report.print_error(
                    MESSAGES['E012'].msg % int(start.group('start')),
                    filename=filename,
                    filelineno=int(m.group('lineno')))

class BashateRun(object):

    def __init__(self):
        self.error_count = 0
        self.error_list = None
        self.ignore_list = None
        self.warning_count = 0
        self.warning_list = None

    def register_ignores(self, ignores):
        if ignores:
            self.ignore_list = '^(' + '|'.join(ignores.split(',')) + ')'

    def register_warnings(self, warnings):
        if warnings:
            self.warning_list = '^(' + '|'.join(warnings.split(',')) + ')'

    def register_errors(self, errors):
        if errors:
            self.error_list = '^(' + '|'.join(errors.split(',')) + ')'

    def should_ignore(self, error):
        return self.ignore_list and re.search(self.ignore_list, error)

    def should_warn(self, error):
        # if in the errors list, overrides warning level
        if self.error_list and re.search(self.error_list, error):
            return False
        if messages.is_default_warning(error):
            return True
        return self.warning_list and re.search(self.warning_list, error)

    def print_error(self, error, line='',
                    filename=None, filelineno=None):
        if self.should_ignore(error):
            return

        warn = self.should_warn(error)

        if not filename:
            filename = fileinput.filename()
        if not filelineno:
            filelineno = fileinput.filelineno()
        if warn:
            self.warning_count = self.warning_count + 1
        else:
            self.error_count = self.error_count + 1

        self.log_error(error, line, filename, filelineno, warn)

    def log_error(self, error, line, filename, filelineno, warn=False):
        print("[%(warn)s] %(error)s: '%(line)s'" %
              {'warn': "W" if warn else "E",
               'error': error,
               'line': line.rstrip('\n')})
        print(" - %s : L%s" % (filename, filelineno))

    def check_files(self, files, verbose):
        in_multiline = False
        logical_line = ""
        token = False
        prev_file = None
        prev_line = ""
        prev_lineno = 0

        # NOTE(mrodden): magic; replace with proper
        # report class when necessary
        report = self

        for fname in files:
            # simple syntax checking, as files can pass style but still cause
            # syntax errors when you try to run them.
            check_syntax(fname, report)

            for line in fileinput.input(fname):
                if fileinput.isfirstline():

                    # last line of a previous file should always end with a
                    # newline
                    if prev_file and not prev_line.endswith('\n'):
                        report.print_error(
                            MESSAGES['E004'].msg,
                            prev_line,
                            filename=prev_file,
                            filelineno=prev_lineno)

                    prev_file = fileinput.filename()

                    check_hashbang(line, fileinput.filename(), report)

                    if verbose:
                        print("Running bashate on %s" % fileinput.filename())

                # strip out heredocs, and don't run any checks on
                # their contents.  These are usually things like yaml
                # files or other bits and pieces that don't obey our
                # syntax such as indenting or line-length.
                if not in_multiline:
                    logical_line = line
                    token = starts_multiline(line)
                    if token:
                        in_multiline = True
                        continue
                else:
                    logical_line = logical_line + line
                    if not end_of_multiline(line, token):
                        continue
                    else:
                        in_multiline = False
                        # XXX: if we want to do something with
                        # heredocs in the future, then the whole thing
                        # is now stored in logical_line.  for now,
                        # skip
                        continue

                # Don't run any tests on comment lines
                if logical_line.lstrip().startswith('#'):
                    prev_line = logical_line
                    prev_lineno = fileinput.filelineno()
                    continue

                # Strip trailing comments. From bash:
                #
                #   a word beginning with # causes that word and all
                #   remaining characters on that line to be ignored.
                #   ...
                #   A character that, when unquoted, separates
                #   words. One of the following: | & ; ( ) < > space
                #   tab
                #
                # for simplicity, we strip inline comments by
                # matching just '<space>#'.
                ll_split = logical_line.split(' #', 1)
                if len(ll_split) > 1:
                    logical_line = ll_split[0].rstrip()

                check_no_trailing_whitespace(logical_line, report)
                check_no_long_lines(logical_line, report)
                check_indents(logical_line, report)
                check_for_do(logical_line, report)
                check_if_then(logical_line, report)
                check_function_decl(logical_line, report)
                check_arithmetic(logical_line, report)
                check_local_subshell(logical_line, report)

                prev_line = logical_line
                prev_lineno = fileinput.filelineno()

def main():

    parser = argparse.ArgumentParser(
        description='A bash script style checker')
    parser.add_argument('files', metavar='file', nargs='*',
                        help='files to scan for errors')
    parser.add_argument('-i', '--ignore', help='Rules to ignore')
    parser.add_argument('-w', '--warn',
                        help='Rules to always warn (rather than error)')
    parser.add_argument('-e', '--error',
                        help='Rules to always error (rather than warn)')
    parser.add_argument('-v', '--verbose', action='store_true', default=False)
    parser.add_argument('-s', '--show', action='store_true', default=False)
    opts = parser.parse_args()

    if opts.show:
        messages.print_messages()
        sys.exit(0)

    files = opts.files
    if not files:
        parser.print_usage()
        return 1

    run = BashateRun()
    run.register_ignores(opts.ignore)
    run.register_warnings(opts.warn)
    run.register_errors(opts.error)

    try:
        run.check_files(files, opts.verbose)
    except IOError as e:
        print("bashate: %s" % e)
        return 1

    if run.warning_count > 0:
        print("%d bashate warning(s) found" % run.warning_count)

    if run.error_count > 0:
        print("%d bashate error(s) found" % run.error_count)
        return 1

    return 0

if __name__ == "__main__":
    sys.exit(main())
<commit_msg>Cleanup continuation line handling<commit_after>#!/usr/bin/env python
#
# 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 __future__ import absolute_import

import argparse
import fileinput
import os
import re
import subprocess
import sys

from bashate import messages

MESSAGES = messages.MESSAGES

def is_continuation(line):
    return re.search('\\\\\s*$', line)

def check_for_do(line, report):
    if not is_continuation(line):
        match = re.match('^\s*(for|while|until)\s', line)
        if match:
            operator = match.group(1).strip()
            if operator == "for":
                # "for i in ..." and "for ((" is bash, but
                # "for (" is likely from an embedded awk script,
                # so skip it
                if re.search('for \([^\(]', line):
                    return
            if not re.search(';\s*do$', line):
                report.print_error((MESSAGES['E010'].msg % operator), line)

def check_if_then(line, report):
    if not is_continuation(line):
        if re.search('^\s*(el)?if \[', line):
            if not re.search(';\s*then$', line):
                report.print_error(MESSAGES['E011'].msg, line)

def check_no_trailing_whitespace(line, report):
    if re.search('[ \t]+$', line):
        report.print_error(MESSAGES['E001'].msg, line)

def check_no_long_lines(line, report):
    if len(line.rstrip("\r\n")) > 79:
        report.print_error(MESSAGES['E006'].msg, line)

def check_indents(line, report):
    m = re.search('^(?P<indent>[ \t]+)', line)
    if m:
        if re.search('\t', m.group('indent')):
            report.print_error(MESSAGES['E002'].msg, line)
        elif (len(m.group('indent')) % 4) != 0:
            report.print_error(MESSAGES['E003'].msg, line)

def check_function_decl(line, report):
    failed = False
    if line.startswith("function"):
        if not re.search('^function [\w-]* \{$', line):
            failed = True
    else:
        # catch the case without "function", e.g.
        # things like '^foo() {'
        if re.search('^\s*?\(\)\s*?\{', line):
            failed = True

    if failed:
        report.print_error(MESSAGES['E020'].msg, line)

def starts_heredoc(line):
    # note, watch out for <<EOF and <<'EOF' ; quotes in the
    # deliminator are part of syntax
    m = re.search("[^<]<<\s*([\'\"]?)(?P<token>\w+)([\'\"]?)", line)
    return m.group('token') if m else False

def end_of_heredoc(line, token):
    return token and re.search("^%s\s*$" % token, line)

def check_arithmetic(line, report):
    if "$[" in line:
        report.print_error(MESSAGES['E041'].msg, line)

def check_local_subshell(line, report):
    if line.lstrip().startswith('local ') and \
       ("=$(" in line or "=`" in line):
        report.print_error(MESSAGES['E042'].msg, line)

def check_hashbang(line, filename, report):
    # this check only runs on the first line
    #  maybe this should check for shell?
    if not line.startswith("#!") and not filename.endswith(".sh"):
        report.print_error(MESSAGES['E005'].msg, line)

def check_syntax(filename, report):
    # run the file through "bash -n" to catch basic syntax errors and
    # other warnings
    matches = []

    # sample lines we want to match:
    # foo.sh: line 4: warning: \
    #    here-document at line 1 delimited by end-of-file (wanted `EOF')
    # foo.sh: line 9: syntax error: unexpected end of file
    # foo.sh: line 7: syntax error near unexpected token `}'
    #
    # i.e. consistency with ":"'s isn't constant, so just do our
    # best...
    r = re.compile(
        '^(?P<file>.*): line (?P<lineno>[0-9]+): (?P<error>.*)')
    # we are parsing the error message, so force it to ignore the
    # system locale so we don't get messages in another language
    bash_environment = os.environ
    bash_environment['LC_ALL'] = 'C'
    proc = subprocess.Popen(
        ['bash', '-n', filename], stdout=subprocess.PIPE,
        stderr=subprocess.PIPE, env=bash_environment)
    outputs = proc.communicate()

    for line in outputs[1].split('\n'):
        m = r.match(line)
        if m:
            matches.append(m)

    for m in matches:
        if 'syntax error' in m.group('error'):
            msg = '%s: %s' % (MESSAGES['E040'].msg, m.group('error'))
            report.print_error(msg, filename=filename,
                               filelineno=int(m.group('lineno')))

        # Matching output from bash warning about here-documents not
        # ending.
        # FIXME: are there other warnings that might come out
        # with "bash -n"?  A quick scan of the source code suggests
        # no, but there might be other interesting things we could
        # catch.
        if 'warning:' in m.group('error'):
            if 'delimited by end-of-file' in m.group('error'):
                start = re.match('^.*line (?P<start>[0-9]+).*$',
                                 m.group('error'))
                report.print_error(
                    MESSAGES['E012'].msg % int(start.group('start')),
                    filename=filename,
                    filelineno=int(m.group('lineno')))

class BashateRun(object):

    def __init__(self):
        self.error_count = 0
        self.error_list = None
        self.ignore_list = None
        self.warning_count = 0
        self.warning_list = None

    def register_ignores(self, ignores):
        if ignores:
            self.ignore_list = '^(' + '|'.join(ignores.split(',')) + ')'

    def register_warnings(self, warnings):
        if warnings:
            self.warning_list = '^(' + '|'.join(warnings.split(',')) + ')'

    def register_errors(self, errors):
        if errors:
            self.error_list = '^(' + '|'.join(errors.split(',')) + ')'

    def should_ignore(self, error):
        return self.ignore_list and re.search(self.ignore_list, error)

    def should_warn(self, error):
        # if in the errors list, overrides warning level
        if self.error_list and re.search(self.error_list, error):
            return False
        if messages.is_default_warning(error):
            return True
        return self.warning_list and re.search(self.warning_list, error)

    def print_error(self, error, line='',
                    filename=None, filelineno=None):
        if self.should_ignore(error):
            return

        warn = self.should_warn(error)

        if not filename:
            filename = fileinput.filename()
        if not filelineno:
            filelineno = fileinput.filelineno()
        if warn:
            self.warning_count = self.warning_count + 1
        else:
            self.error_count = self.error_count + 1

        self.log_error(error, line, filename, filelineno, warn)

    def log_error(self, error, line, filename, filelineno, warn=False):
        print("[%(warn)s] %(error)s: '%(line)s'" %
              {'warn': "W" if warn else "E",
               'error': error,
               'line': line.rstrip('\n')})
        print(" - %s : L%s" % (filename, filelineno))

    def check_files(self, files, verbose):
        logical_line = ""
        token = False
        prev_file = None
        prev_line = ""
        prev_lineno = 0

        # NOTE(mrodden): magic; replace with proper
        # report class when necessary
        report = self

        for fname in files:

            # reset world
            in_heredoc = False
            in_continuation = False

            # simple syntax checking, as files can pass style but still cause
            # syntax errors when you try to run them.
            check_syntax(fname, report)

            for line in fileinput.input(fname):
                if fileinput.isfirstline():

                    # last line of a previous file should always end with a
                    # newline
                    if prev_file and not prev_line.endswith('\n'):
                        report.print_error(
                            MESSAGES['E004'].msg,
                            prev_line,
                            filename=prev_file,
                            filelineno=prev_lineno)

                    prev_file = fileinput.filename()

                    check_hashbang(line, fileinput.filename(), report)

                    if verbose:
                        print("Running bashate on %s" % fileinput.filename())

                # Don't run any tests on comment lines (but remember
                # inside a heredoc this might be part of the syntax of
                # an embedded script, just ignore that)
                if line.lstrip().startswith('#') and not in_heredoc:
                    prev_line = line
                    prev_lineno = fileinput.filelineno()
                    continue

                # Strip trailing comments. From bash:
                #
                #   a word beginning with # causes that word and all
                #   remaining characters on that line to be ignored.
                #   ...
                #   A character that, when unquoted, separates
                #   words. One of the following: | & ; ( ) < > space
                #   tab
                #
                # for simplicity, we strip inline comments by
                # matching just '<space>#'.
                if not in_heredoc:
                    ll_split = line.split(' #', 1)
                    if len(ll_split) > 1:
                        line = ll_split[0].rstrip()

                # see if this starts a heredoc
                if not in_heredoc:
                    token = starts_heredoc(line)
                    if token:
                        in_heredoc = True
                        logical_line = [line]
                        continue

                # see if this starts a continuation
                if not in_continuation:
                    if is_continuation(line):
                        in_continuation = True
                        logical_line = [line]
                        continue

                # if we are in a heredoc or continuation, just loop
                # back and keep buffering the lines into
                # "logical_line" until the end of the
                # heredoc/continuation.
                if in_heredoc:
                    logical_line.append(line)
                    if not end_of_heredoc(line, token):
                        continue
                    else:
                        in_heredoc = False
                        # FIXME: if we want to do something with
                        # heredocs in the future, then the whole thing
                        # is now stored in logical_line.  for now,
                        # skip
                        continue
                elif in_continuation:
                    logical_line.append(line)
                    if is_continuation(line):
                        continue
                    else:
                        in_continuation = False
                else:
                    logical_line = [line]

                # at this point, logical_line is an array that holds
                # the whole continuation.  XXX : historically, we've
                # just handled every line in a continuation
                # separatley.  Stick with what works...
                for line in logical_line:
                    check_no_trailing_whitespace(line, report)
                    check_no_long_lines(line, report)
                    check_indents(line, report)
                    check_for_do(line, report)
                    check_if_then(line, report)
                    check_function_decl(line, report)
                    check_arithmetic(line, report)
                    check_local_subshell(line, report)

                prev_line = line
                prev_lineno = fileinput.filelineno()

def main():

    parser = argparse.ArgumentParser(
        description='A bash script style checker')
    parser.add_argument('files', metavar='file', nargs='*',
                        help='files to scan for errors')
    parser.add_argument('-i', '--ignore', help='Rules to ignore')
    parser.add_argument('-w', '--warn',
                        help='Rules to always warn (rather than error)')
    parser.add_argument('-e', '--error',
                        help='Rules to always error (rather than warn)')
    parser.add_argument('-v', '--verbose', action='store_true', default=False)
    parser.add_argument('-s', '--show', action='store_true', default=False)
    opts = parser.parse_args()

    if opts.show:
        messages.print_messages()
        sys.exit(0)

    files = opts.files
    if not files:
        parser.print_usage()
        return 1

    run = BashateRun()
    run.register_ignores(opts.ignore)
    run.register_warnings(opts.warn)
    run.register_errors(opts.error)

    try:
        run.check_files(files, opts.verbose)
    except IOError as e:
        print("bashate: %s" % e)
        return 1

    if run.warning_count > 0:
        print("%d bashate warning(s) found" % run.warning_count)

    if run.error_count > 0:
        print("%d bashate error(s) found" % run.error_count)
        return 1

    return 0

if __name__ == "__main__":
    sys.exit(main())
<|endoftext|>