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

"""
conference.py -- Udacity conference server-side Python App Engine API;
    uses Google Cloud Endpoints

$Id: conference.py,v 1.25 2014/05/24 23:42:19 wesc Exp wesc $

created by wesc on 2014 apr 21

"""

__author__ = 'wesc+api@google.com (Wesley Chun)'

from datetime import datetime
import json
import os
import time

import endpoints
from protorpc import messages
from protorpc import message_types
from protorpc import remote

from google.appengine.api import urlfetch
from google.appengine.ext import ndb

from models import BooleanMessage
from models import ConflictException
from models import Conference
from models import ConferenceForm
from models import ConferenceForms
from models import ConferenceQueryForms
from models import ConferenceQueryForm
from models import Profile
from models import ProfileMiniForm
from models import ProfileForm
from models import TeeShirtSize

from settings import WEB_CLIENT_ID

from utils  import getUserId

EMAIL_SCOPE = endpoints.EMAIL_SCOPE
API_EXPLORER_CLIENT_ID = endpoints.API_EXPLORER_CLIENT_ID

CONF_GET_REQUEST = endpoints.ResourceContainer(
    message_types.VoidMessage,
    websafeConferenceKey = messages.StringField(1),
)

DEFAULTS = {
    "city" : "Default City",
    "maxAttendees" : 0,
    "seatsAvailable" : 0,
    "topics" : ["Default", "Topic"],
}

OPERATORS = {
            'EQ':   '=',
            'GT':   '>',
            'GTEQ': '>=',
            'LT':   '<',
            'LTEQ': '<=',
            'NE':   '!='
            }

FIELDS =    {
            'CITY': 'city',
            'TOPIC': 'topics',
            'MONTH': 'month',
            'MAX_ATTENDEES': 'maxAttendees',
            }

# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

@endpoints.api( name='conference',
                version='v1',
                allowed_client_ids=[WEB_CLIENT_ID, API_EXPLORER_CLIENT_ID],
                scopes=[EMAIL_SCOPE])
class ConferenceApi(remote.Service):
    """Conference API v0.1"""
# - - - Registration - - - - - - - - - - - - - - - - - - - -

    @ndb.transactional(xg=True)
    def _conferenceRegistration(self, request, reg=True):
        """Register or unregister user for selected conference."""
        retval = None
        prof = self._getProfileFromUser()

        # check if conf exists given websafeConfKey
        # get conference, check that it exists
        wsck = request.websafeConferenceKey
        conf = ndb.Key(urlsafe=wsck).get()
        if not conf:
            raise endpoints.NotFoundException(
                    'No conference found with key: %s' %wsck)

        # register
        if reg:
            # check if user already registered otherwise add
            if wsck in prof.conferenceKeysToAttend:
                raise ConflictException(
                        "You already registered for this conference.")

            if conf.seatsAvailable <= 0:
                raise ConflictException(
                        "There are no seats available.")

            # register user, take away one seat
            prof.conferenceKeysToAttend.append(wsck)
            conf.seatsAvailable -= 1
            retval = True

        else:
            # check if user already registered
            if wsck in prof.conferenceKeysToAttend:
                #unregister user, add back one seat
                prof.conferenceKeysToAttend.remove(wsck)
                conf.seatsAvailable += 1
                retval = True
            else:
                retval = False

        prof.put()
        conf.put()
        return BooleanMessage(data=retval)

    @endpoints.method(CONF_GET_REQUEST, BooleanMessage,
                      path='conference/{websafeConferenceKey}',
                      http_method='post', name='registerForConference')
    def registerForConference(self, request):
        """Register user for selected confereence."""
        return self._conferenceRegistration(request)

    @endpoints.method(message_types.VoidMessage, ConferenceForms,
                path='conferences/attending',
                http_method='GET', name='getConferencesToAttend')
    def getConferencesToAttend(self, request):
        """Get list of conferences that user has registered for."""
        profile = self._getProfileFromUser()
        userConfKeys = profile.conferenceKeysToAttend
        keys = [ndb.Key(urlsafe=key) for key in userConfKeys]
        conferences = ndb.get_multi(keys)
        return ConferenceForms(
                items=[self._copyConferenceToForm(conf, "") for conf in conferences]
        )

# - - - Conference Objects- - - - - - - - - - - - - - - - - -

    def _copyConferenceToForm(self, conf, displayName):
        """Copy relevant fields from Conference to ConferenceForm"""
        cf = ConferenceForm()
        for field in cf.all_fields():
            if hasattr(conf, field.name):
                if field.name.endswith('Date'):
                    setattr(cf, field.name, str(getattr(conf, field.name)))
                else:
                    setattr(cf, field.name, getattr(conf, field.name))
            elif field.name == "websafeKey":
                setattr(cf, field.name, conf.key.urlsafe())
        if displayName:
            setattr(cf, 'organizerDisplayName', displayName)
        cf.check_initialized()
        return cf

    def _createConferenceObject(self, request):
        """Create or update Conference object, returning ConferenceForm/request."""
        user = endpoints.get_current_user()
        if not user:
            raise endpoints.UnauthorizedException('Authorization required')
        user_id = getUserId(user)

        if not request.name:
            raise endpoints.BadRequestException("Conference 'name' field required")

        # Copy ConferenceForm/ProtoRPC Message into dict
        data = {field.name: getattr(request, field.name) for field in request.all_fields()}
        del data['websafeKey']
        del data['organizerDisplayName']

        # Add default values for those missing (both data model and outbound Message)
        for df in DEFAULTS:
            if data[df] in (None, []):
                data[df] = DEFAULTS[df]
                setattr(request, df, DEFAULTS[df])

        if data['startDate']:
            data['startDate'] = datetime.strptime(data['startDate'][:10], "%Y-%m-%d").date()
            data['month'] = data['startDate'].month
        else:
            data['month'] = 0
        if data['endDate']:
            data['endDate'] = datetime.strptime(data['endDate'][:10], "%Y-%m-%d").date()

        # set seatsAvailable to be same as maxAttendees on creation
        # both for data model & outbound Message
        if data["maxAttendees"] > 0:
            data["seatsAvailable"] = data["maxAttendees"]
            setattr(request, "seatsAvailable", data["maxAttendees"])

        # make Profile Key from user ID
        p_key = ndb.Key(Profile, user_id)
        # allocate new Conference ID with Profile key as parent
        c_id = Conference.allocate_ids(size=1, parent=p_key)[0]
        # make Conference key from ID
        c_key = ndb.Key(Conference, c_id, parent=p_key)
        data['key'] = c_key
        data['organizerUserId'] = request.organizerUserId = user_id

        # create Conference & return (modified) ConferenceForm
        Conference(**data).put()

        return request

    def _getQuery(self, request):
        """Return formatted query from the submitted filters."""
        q = Conference.query()
        inequality_filter, filters = self._formatFilters(request.filters)

        # If exists, sort on inequality filter first
        if not inequality_filter:
            q = q.order(Conference.name)
        else:
            q = q.order(ndb.GenericProperty(inequality_filter))
            q = q.order(Conference.name)

        for filtr in filters:
            if filtr["field"] in ["month", "maxAttendees"]:
                filtr["value"] = int(filtr["value"])
                formatted_query = ndb.query.FilterNode(filtr["field"], filtr["operator"], filtr["value"])
                q = q.filter(formatted_query)
        return q

    def _formatFilters(self, filters):
        """ Parse, check validity and format user supplied filters."""
        formatted_filters = []
        inequality_field = None

        for f in filters:
            filtr = {field.name: getattr(f, field.name) for field in f.all_fields()}

            try:
                filtr["field"] = FIELDS[filtr["field"]]
                filtr["operator"] = OPERATORS[filtr["operator"]]
            except KeyError:
                raise endpoints.BadRequestException("Filter contains invalid filed or operator.")

            if filtr["operator"] != "=":
                # check if inequality operation has been used in previous filters
                # disallow the filter if inequality was performed on a different field before
                # track the field on which the inequality operation is performed
                if inequality_field and inequality_field != filtr["field"]:
                    raise endpoints.BadRequestException("Inequality filter is allowed on only one field.")
                else:
                    inequality_field = filtr["field"]

            formatted_filters.append(filtr)
        return (inequality_field, formatted_filters)

    @endpoints.method(ConferenceQueryForms, ConferenceForms,
                      path='queryConferences',
                      http_method='POST',
                      name='queryConferences')
    def queryConferences(self, request):
        """Query for conferences."""
        conferences = self._getQuery(request)
        return ConferenceForms(
            items=[self._copyConferenceToForm(conf, "") for conf in conferences]
        )

    @endpoints.method(message_types.VoidMessage, ConferenceForms,
                      path='getConferencesCreated',
                      http_method='POST',
                      name='getConferencesCreated')
    def getConferencesCreated(self, request):
        """Query for conferences created by the user."""
        user = endpoints.get_current_user()
        if not user:
            raise endpoints.UnauthorizedException('Authorization required')
        conferences = Conference.query(ancestor= ndb.Key(Profile, getUserId(user)))
        return ConferenceForms(
            items=[self._copyConferenceToForm(conf, "") for conf in conferences]
        )

    @endpoints.method(message_types.VoidMessage, ConferenceForms,
                      path="filterPlayground",
                      http_method='POST',
                      name='flilterPlayground',)
    def filterPlayground(self, request):
        """Playing around with filters"""

        q = Conference.query().filter(Conference.city == 'Tokyo').filter(Conference.seatsAvailable < 10).filter(Conference.seatsAvailable > 0)

        return ConferenceForms(
            items=[self._copyConferenceToForm(conf, "") for conf in q]
        )

# - - - Profile objects - - - - - - - - - - - - - - - - - - -

    def _copyProfileToForm(self, prof):
        """Copy relevant fields from Profile to ProfileForm."""
        pf = ProfileForm()
        for field in pf.all_fields():
            if hasattr(prof, field.name):
                # convert t-shirt string to Enum; just copy others
                if field.name == 'teeShirtSize':
                    setattr(pf, field.name, getattr(TeeShirtSize, getattr(prof, field.name)))
                else:
                    setattr(pf, field.name, getattr(prof, field.name))
        pf.check_initialized()
        return pf

    def _getProfileFromUser(self):
        """Return user Profile from datastore, creating new one if non-existent."""
        user = endpoints.get_current_user()
        if not user:
            raise endpoints.UnauthorizedException('Authorization required')

        user_id = getUserId(user)
        p_key = ndb.Key(Profile, user_id)

        profile = p_key.get()
        if not profile:
            profile = Profile(
                key = p_key,
                displayName = user.nickname(),
                mainEmail= user.email(),
                teeShirtSize = str(TeeShirtSize.NOT_SPECIFIED),
            )
            profile.put()
        return profile      # return Profile

    def _doProfile(self, save_request=None):
        """Get user Profile and return to user, possibly updating it first."""
        # get user Profile
        prof = self._getProfileFromUser()

        # if saveProfile(), process user-modifyable fields
        if save_request:
            for field in ('displayName', 'teeShirtSize'):
                if hasattr(save_request, field):
                    val = getattr(save_request, field)
                    if val:
                        setattr(prof, field, str(val))
            prof.put()
        # return ProfileForm
        return self._copyProfileToForm(prof)

    @endpoints.method(ConferenceForm, ConferenceForm, path='conference',
                      http_method='POST', name='createConference')
    def createConference(self, request):
        return self._createConferenceObject(request)

    @endpoints.method(message_types.VoidMessage, ProfileForm, path='profile',
                      http_method='GET', name='getProfile')
    def getProfile(self, request):
        """Return user profile."""
        return self._doProfile()

    @endpoints.method(ProfileMiniForm, ProfileForm, path='profile',
                      http_method='POST', name='saveProfile')
    def saveProfile(self, request):
        """Update & return user profile."""
        return self._doProfile(request)

# registers API
api = endpoints.api_server([ConferenceApi])
<commit_msg>Added getConference method, because it didn't exist?<commit_after>#!/usr/bin/env python

"""
conference.py -- Udacity conference server-side Python App Engine API;
    uses Google Cloud Endpoints

$Id: conference.py,v 1.25 2014/05/24 23:42:19 wesc Exp wesc $

created by wesc on 2014 apr 21

"""

__author__ = 'wesc+api@google.com (Wesley Chun)'

from datetime import datetime
import json
import os
import time

import endpoints
from protorpc import messages
from protorpc import message_types
from protorpc import remote

from google.appengine.api import urlfetch
from google.appengine.ext import ndb

from models import BooleanMessage
from models import ConflictException
from models import Conference
from models import ConferenceForm
from models import ConferenceForms
from models import ConferenceQueryForms
from models import ConferenceQueryForm
from models import Profile
from models import ProfileMiniForm
from models import ProfileForm
from models import TeeShirtSize

from settings import WEB_CLIENT_ID

from utils  import getUserId

EMAIL_SCOPE = endpoints.EMAIL_SCOPE
API_EXPLORER_CLIENT_ID = endpoints.API_EXPLORER_CLIENT_ID

CONF_GET_REQUEST = endpoints.ResourceContainer(
    message_types.VoidMessage,
    websafeConferenceKey = messages.StringField(1),
)

DEFAULTS = {
    "city" : "Default City",
    "maxAttendees" : 0,
    "seatsAvailable" : 0,
    "topics" : ["Default", "Topic"],
}

OPERATORS = {
            'EQ':   '=',
            'GT':   '>',
            'GTEQ': '>=',
            'LT':   '<',
            'LTEQ': '<=',
            'NE':   '!='
            }

FIELDS =    {
            'CITY': 'city',
            'TOPIC': 'topics',
            'MONTH': 'month',
            'MAX_ATTENDEES': 'maxAttendees',
            }

# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

@endpoints.api( name='conference',
                version='v1',
                allowed_client_ids=[WEB_CLIENT_ID, API_EXPLORER_CLIENT_ID],
                scopes=[EMAIL_SCOPE])
class ConferenceApi(remote.Service):
    """Conference API v0.1"""
# - - - Registration - - - - - - - - - - - - - - - - - - - -

    @ndb.transactional(xg=True)
    def _conferenceRegistration(self, request, reg=True):
        """Register or unregister user for selected conference."""
        retval = None
        prof = self._getProfileFromUser()

        # check if conf exists given websafeConfKey
        # get conference, check that it exists
        wsck = request.websafeConferenceKey
        conf = ndb.Key(urlsafe=wsck).get()
        if not conf:
            raise endpoints.NotFoundException(
                    'No conference found with key: %s' %wsck)

        # register
        if reg:
            # check if user already registered otherwise add
            if wsck in prof.conferenceKeysToAttend:
                raise ConflictException(
                        "You already registered for this conference.")

            if conf.seatsAvailable <= 0:
                raise ConflictException(
                        "There are no seats available.")

            # register user, take away one seat
            prof.conferenceKeysToAttend.append(wsck)
            conf.seatsAvailable -= 1
            retval = True

        else:
            # check if user already registered
            if wsck in prof.conferenceKeysToAttend:
                #unregister user, add back one seat
                prof.conferenceKeysToAttend.remove(wsck)
                conf.seatsAvailable += 1
                retval = True
            else:
                retval = False

        prof.put()
        conf.put()
        return BooleanMessage(data=retval)

    @endpoints.method(CONF_GET_REQUEST, BooleanMessage,
                      path='conference/{websafeConferenceKey}',
                      http_method='post', name='registerForConference')
    def registerForConference(self, request):
        """Register user for selected confereence."""
        return self._conferenceRegistration(request)

    @endpoints.method(message_types.VoidMessage, ConferenceForms,
                path='conferences/attending',
                http_method='GET', name='getConferencesToAttend')
    def getConferencesToAttend(self, request):
        """Get list of conferences that user has registered for."""
        profile = self._getProfileFromUser()
        userConfKeys = profile.conferenceKeysToAttend
        keys = [ndb.Key(urlsafe=key) for key in userConfKeys]
        conferences = ndb.get_multi(keys)
        return ConferenceForms(
                items=[self._copyConferenceToForm(conf, "") for conf in conferences]
        )

# - - - Conference Objects- - - - - - - - - - - - - - - - - -

    def _copyConferenceToForm(self, conf, displayName):
        """Copy relevant fields from Conference to ConferenceForm"""
        cf = ConferenceForm()
        for field in cf.all_fields():
            if hasattr(conf, field.name):
                if field.name.endswith('Date'):
                    setattr(cf, field.name, str(getattr(conf, field.name)))
                else:
                    setattr(cf, field.name, getattr(conf, field.name))
            elif field.name == "websafeKey":
                setattr(cf, field.name, conf.key.urlsafe())
        if displayName:
            setattr(cf, 'organizerDisplayName', displayName)
        cf.check_initialized()
        return cf

    def _createConferenceObject(self, request):
        """Create or update Conference object, returning ConferenceForm/request."""
        user = endpoints.get_current_user()
        if not user:
            raise endpoints.UnauthorizedException('Authorization required')
        user_id = getUserId(user)

        if not request.name:
            raise endpoints.BadRequestException("Conference 'name' field required")

        # Copy ConferenceForm/ProtoRPC Message into dict
        data = {field.name: getattr(request, field.name) for field in request.all_fields()}
        del data['websafeKey']
        del data['organizerDisplayName']

        # Add default values for those missing (both data model and outbound Message)
        for df in DEFAULTS:
            if data[df] in (None, []):
                data[df] = DEFAULTS[df]
                setattr(request, df, DEFAULTS[df])

        if data['startDate']:
            data['startDate'] = datetime.strptime(data['startDate'][:10], "%Y-%m-%d").date()
            data['month'] = data['startDate'].month
        else:
            data['month'] = 0
        if data['endDate']:
            data['endDate'] = datetime.strptime(data['endDate'][:10], "%Y-%m-%d").date()

        # set seatsAvailable to be same as maxAttendees on creation
        # both for data model & outbound Message
        if data["maxAttendees"] > 0:
            data["seatsAvailable"] = data["maxAttendees"]
            setattr(request, "seatsAvailable", data["maxAttendees"])

        # make Profile Key from user ID
        p_key = ndb.Key(Profile, user_id)
        # allocate new Conference ID with Profile key as parent
        c_id = Conference.allocate_ids(size=1, parent=p_key)[0]
        # make Conference key from ID
        c_key = ndb.Key(Conference, c_id, parent=p_key)
        data['key'] = c_key
        data['organizerUserId'] = request.organizerUserId = user_id

        # create Conference & return (modified) ConferenceForm
        Conference(**data).put()

        return request

    def _getQuery(self, request):
        """Return formatted query from the submitted filters."""
        q = Conference.query()
        inequality_filter, filters = self._formatFilters(request.filters)

        # If exists, sort on inequality filter first
        if not inequality_filter:
            q = q.order(Conference.name)
        else:
            q = q.order(ndb.GenericProperty(inequality_filter))
            q = q.order(Conference.name)

        for filtr in filters:
            if filtr["field"] in ["month", "maxAttendees"]:
                filtr["value"] = int(filtr["value"])
                formatted_query = ndb.query.FilterNode(filtr["field"], filtr["operator"], filtr["value"])
                q = q.filter(formatted_query)
        return q

    def _formatFilters(self, filters):
        """ Parse, check validity and format user supplied filters."""
        formatted_filters = []
        inequality_field = None

        for f in filters:
            filtr = {field.name: getattr(f, field.name) for field in f.all_fields()}

            try:
                filtr["field"] = FIELDS[filtr["field"]]
                filtr["operator"] = OPERATORS[filtr["operator"]]
            except KeyError:
                raise endpoints.BadRequestException("Filter contains invalid filed or operator.")

            if filtr["operator"] != "=":
                # check if inequality operation has been used in previous filters
                # disallow the filter if inequality was performed on a different field before
                # track the field on which the inequality operation is performed
                if inequality_field and inequality_field != filtr["field"]:
                    raise endpoints.BadRequestException("Inequality filter is allowed on only one field.")
                else:
                    inequality_field = filtr["field"]

            formatted_filters.append(filtr)
        return (inequality_field, formatted_filters)

    @endpoints.method(ConferenceQueryForms, ConferenceForms,
                      path='queryConferences',
                      http_method='POST',
                      name='queryConferences')
    def queryConferences(self, request):
        """Query for conferences."""
        conferences = self._getQuery(request)
        return ConferenceForms(
            items=[self._copyConferenceToForm(conf, "") for conf in conferences]
        )

    @endpoints.method(CONF_GET_REQUEST, ConferenceForm,
            path='conference/{websafeConferenceKey}',
            http_method='GET', name='getConference')
    def getConference(self, request):
        """Return requested conference (by websafeConferenceKey)."""
        # get Conference object from request; bail if not found
        conf = ndb.Key(urlsafe=request.websafeConferenceKey).get()
        if not conf:
            raise endpoints.NotFoundException(
                'No conference found with key: %s' % request.websafeConferenceKey)
        prof = conf.key.parent().get()
        # return ConferenceForm
        return self._copyConferenceToForm(conf, getattr(prof, 'displayName'))

    @endpoints.method(message_types.VoidMessage, ConferenceForms,
                      path='getConferencesCreated',
                      http_method='POST',
                      name='getConferencesCreated')
    def getConferencesCreated(self, request):
        """Query for conferences created by the user."""
        user = endpoints.get_current_user()
        if not user:
            raise endpoints.UnauthorizedException('Authorization required')
        conferences = Conference.query(ancestor= ndb.Key(Profile, getUserId(user)))
        return ConferenceForms(
            items=[self._copyConferenceToForm(conf, "") for conf in conferences]
        )

# - - - Profile objects - - - - - - - - - - - - - - - - - - -

    def _copyProfileToForm(self, prof):
        """Copy relevant fields from Profile to ProfileForm."""
        pf = ProfileForm()
        for field in pf.all_fields():
            if hasattr(prof, field.name):
                # convert t-shirt string to Enum; just copy others
                if field.name == 'teeShirtSize':
                    setattr(pf, field.name, getattr(TeeShirtSize, getattr(prof, field.name)))
                else:
                    setattr(pf, field.name, getattr(prof, field.name))
        pf.check_initialized()
        return pf

    def _getProfileFromUser(self):
        """Return user Profile from datastore, creating new one if non-existent."""
        user = endpoints.get_current_user()
        if not user:
            raise endpoints.UnauthorizedException('Authorization required')

        user_id = getUserId(user)
        p_key = ndb.Key(Profile, user_id)

        profile = p_key.get()
        if not profile:
            profile = Profile(
                key = p_key,
                displayName = user.nickname(),
                mainEmail= user.email(),
                teeShirtSize = str(TeeShirtSize.NOT_SPECIFIED),
            )
            profile.put()
        return profile      # return Profile

    def _doProfile(self, save_request=None):
        """Get user Profile and return to user, possibly updating it first."""
        # get user Profile
        prof = self._getProfileFromUser()

        # if saveProfile(), process user-modifyable fields
        if save_request:
            for field in ('displayName', 'teeShirtSize'):
                if hasattr(save_request, field):
                    val = getattr(save_request, field)
                    if val:
                        setattr(prof, field, str(val))
            prof.put()
        # return ProfileForm
        return self._copyProfileToForm(prof)

    @endpoints.method(ConferenceForm, ConferenceForm, path='conference',
                      http_method='POST', name='createConference')
    def createConference(self, request):
        return self._createConferenceObject(request)

    @endpoints.method(message_types.VoidMessage, ProfileForm, path='profile',
                      http_method='GET', name='getProfile')
    def getProfile(self, request):
        """Return user profile."""
        return self._doProfile()

    @endpoints.method(ProfileMiniForm, ProfileForm, path='profile',
                      http_method='POST', name='saveProfile')
    def saveProfile(self, request):
        """Update & return user profile."""
        return self._doProfile(request)

# registers API
api = endpoints.api_server([ConferenceApi])
<|endoftext|>


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

#import the needed modules
import sys
from datetime import datetime, time, timedelta
from random import randint

if __name__ == "__main__":

    numOfRecsToGenerate = 0
    minTemp = 0
    maxTemp = 0
    timeStep = 0

    minNumOfArgs = 5
    numOfArgs = len(sys.argv) - 1
    if numOfArgs == minNumOfArgs:
        try:
            numOfRecsToGenerate = int(sys.argv[1])
            minTemp = int(sys.argv[2])
            maxTemp = int(sys.argv[3])
            timeStep = int(sys.argv[4])
        except ValueError:
            print("Unexpected integer as argument but got %s" % sys.argv[1])
            sys.exit()
        except TypeError:
            print("Unexpected integer as argument but got %s" % sys.argv[1])
            sys.exit()

        filename = sys.argv[5]

        lines = ["#Time\tTemperature\n",]
        currentTime = datetime.now()
        for rec in range(numOfRecsToGenerate):
            currentTime += timedelta(minutes=timeStep)
            lines.append("%s\t%d\n" % (currentTime.strftime('%Y-%m-%d,%H:%M:%S'), randint(minTemp, maxTemp)))

        with open(filename, 'w') as f:
            for line in lines:
                f.write(line)

        if not(f.closed):
            f.close()
    else:
        print("Unexpected number of arguments, Expected %d but got %d" % (minNumOfArgs, numOfArgs))
        print("Usage: python numOfRecs minTemp maxTemp timestep filename")
        print("Generates a specified number of random temperature records separated by the number of minutes given in the timestep")
        print("File is tab-delimted file of type: Time Temperature")
        sys.exit()
<commit_msg>Undo change to comma in time<commit_after>#!/usr/bin/env python

#import the needed modules
import sys
from datetime import datetime, time, timedelta
from random import randint

if __name__ == "__main__":

    numOfRecsToGenerate = 0
    minTemp = 0
    maxTemp = 0
    timeStep = 0

    minNumOfArgs = 5
    numOfArgs = len(sys.argv) - 1
    if numOfArgs == minNumOfArgs:
        try:
            numOfRecsToGenerate = int(sys.argv[1])
            minTemp = int(sys.argv[2])
            maxTemp = int(sys.argv[3])
            timeStep = int(sys.argv[4])
        except ValueError:
            print("Unexpected integer as argument but got %s" % sys.argv[1])
            sys.exit()
        except TypeError:
            print("Unexpected integer as argument but got %s" % sys.argv[1])
            sys.exit()

        filename = sys.argv[5]

        lines = ["#Time\tTemperature\n",]
        currentTime = datetime.now()
        for rec in range(numOfRecsToGenerate):
            currentTime += timedelta(minutes=timeStep)
            lines.append("%s\t%d\n" % (currentTime.strftime('%Y-%m-%d %H:%M:%S'), randint(minTemp, maxTemp)))

        with open(filename, 'w') as f:
            for line in lines:
                f.write(line)

        if not(f.closed):
            f.close()
    else:
        print("Unexpected number of arguments, Expected %d but got %d" % (minNumOfArgs, numOfArgs))
        print("Usage: python numOfRecs minTemp maxTemp timestep filename")
        print("Generates a specified number of random temperature records separated by the number of minutes given in the timestep")
        print("File is tab-delimted file of type: Time Temperature")
        sys.exit()
<|endoftext|>


<commit_before>import logging

import re
from datetime import datetime
from odoo import api, models
from .spec_models import SpecModel

_logger = logging.getLogger(__name__)

tz_datetime = re.compile(r'.*[-+]0[0-9]:00$')

class AbstractSpecMixin(models.AbstractModel):
    _inherit = 'spec.mixin'

    @api.model
    def build(self, node, defaults=False):

        if not defaults:
            defaults = dict()

        # TODO new or create choice
        # TODO ability to match existing record here
        model_name = SpecModel._get_concrete(self._name) or self._name
        model = self.env[model_name]
        attrs = model.build_attrs(node, create_m2o=True, defaults=defaults)
        return model.create(attrs)

    @api.model
    def build_attrs(self, node, create_m2o=False, path='', defaults=False):
        """A recursive Odoo object builder that works along with the
        GenerateDS object builder from the parsed XML.
        Here we take into account the concrete Odoo objects where the schema
        mixins where injected and possible matcher or builder overrides."""

        if not defaults:
            defaults = dict()

        fields = self.fields_get()
        # no default image for easier debugging
        vals = self.default_get([f for f, v in fields.items()
                                 if v['type'] != 'binary'])
        if path == '':
            vals.update(defaults)
        # we sort attrs to be able to define m2o related values
        sorted_attrs = sorted(node.member_data_items_,
                              key=lambda a: a.get_container() in [0, 1],
                              reverse=True)
        for attr in sorted_attrs:
            value = getattr(node, attr.get_name())
            if value is None or value == []:
                continue
            key = "nfe40_%s" % (attr.get_name(),)  # TODO schema wise
            child_path = '%s.%s' % (path, key)

            if key.startswith('nfe40_ICMS') and key not in [
                    'nfe40_ICMS', 'nfe40_ICMSTot', 'nfe40_ICMSUFDest']:
                vals['nfe40_choice11'] = key

            if key.startswith('nfe40_IPI') and key != 'nfe40_IPI':
                vals['nfe40_choice3'] = key

            if key.startswith('nfe40_PIS') and key not in [
                    'nfe40_PIS', 'nfe40_PISST']:
                vals['nfe40_choice12'] = key

            if key.startswith('nfe40_COFINS') and key not in [
                    'nfe40_COFINS', 'nfe40_COFINSST']:
                vals['nfe40_choice15'] = key

            if attr.get_child_attrs().get('type') is None\
                    or attr.get_child_attrs().get('type') == 'xs:string':
                # SimpleType
                if fields[key]['type'] == 'datetime':
                    if 'T' in value:
                        if tz_datetime.match(value):
                            old_value = value
                            value = old_value[:19]
                            # TODO see python3/pysped/xml_sped/base.py#L692
                        value = datetime.strptime(value, '%Y-%m-%dT%H:%M:%S')

                if key not in ['nfe40_CST', 'nfe40_modBC', 'nfe40_CSOSN']:
                    vals[key] = value  # TODO avoid collision with cls prefix
                elif key == 'nfe40_CST':
                    if node.original_tagname_.startswith('ICMS'):
                        vals['icms_cst_id'] = \
                            self.env['l10n_br_fiscal.cst'].search(
                                [('code', '=', value),
                                 ('tax_domain', '=', 'icms')])[0].id
                    if node.original_tagname_.startswith('IPI'):
                        vals['ipi_cst_id'] = \
                            self.env['l10n_br_fiscal.cst'].search(
                                [('code', '=', value),
                                 ('tax_domain', '=', 'ipi')])[0].id
                    if node.original_tagname_.startswith('PIS'):
                        vals['pis_cst_id'] = \
                            self.env['l10n_br_fiscal.cst'].search(
                                [('code', '=', value),
                                 ('tax_domain', '=', 'pis')])[0].id
                    if node.original_tagname_.startswith('COFINS'):
                        vals['cofins_cst_id'] = \
                            self.env['l10n_br_fiscal.cst'].search(
                                [('code', '=', value),
                                 ('tax_domain', '=', 'cofins')])[0].id
                elif key == 'nfe40_modBC':
                    vals['icms_base_type'] = value

            else:
                # ComplexType
                if fields.get(key) and fields[key].get('related'):
                    # example: company.nfe40_enderEmit related on partner_id
                    # then we need to set partner_id, not nfe40_enderEmit
                    key = fields[key]['related'][-1]  # -1 works with _inherits
                    comodel_name = fields[key]['relation']
                else:
                    clean_type = attr.get_child_attrs()[
                        'type'].replace('Type', '').lower()
                    comodel_name = "nfe.40.%s" % (clean_type,)  # TODO clean

                comodel = self.get_concrete_model(comodel_name)

                if attr.get_container() == 0:
                    # m2o
                    new_value = comodel.build_attrs(value,
                                                    create_m2o=create_m2o,
                                                    path=child_path,
                                                    defaults=defaults)
                    child_defaults = self._extract_related_values(vals, key)

                    new_value.update(child_defaults)
                    if comodel._name == self._name or \
                            self._name == 'account.invoice.line' and \
                            comodel._name == 'l10n_br_fiscal.document.line' \
                            or self._name == 'account.invoice' and \
                            comodel._name == 'l10n_br_fiscal.document':
                        # TODO do not hardcode!!
                        # stacked m2o
                        vals.update(new_value)
                    else:
                        vals[key] = comodel.match_or_create_m2o(
                            new_value, vals, create_m2o)
                elif attr.get_container() == 1:
                    # o2m
                    lines = []
                    for line in [l for l in value if l]:
                        line_vals = comodel.build_attrs(line,
                                                        create_m2o=create_m2o,
                                                        path=child_path,
                                                        defaults=defaults)
                        lines.append((0, 0, line_vals))
                    vals[key] = lines

        vals = self._prepare_import_dict(vals, defaults=defaults)
        return vals

    @api.model
    def get_concrete_model(self, comodel_name):
        "Lookup for concrete models where abstract schema mixins were injected"
        if comodel_name == 'nfe.40.tenderemi':  # TODO not a related field
            comodel_name = 'res.partner'
        if hasattr(models.MetaModel, 'mixin_mappings') \
                and models.MetaModel.mixin_mappings.get(comodel_name)\
                is not None:
            return self.env[models.MetaModel.mixin_mappings[comodel_name]]
        else:
            return self.env[comodel_name]

    @api.model
    def _extract_related_values(self, vals, key):
        """Example: prepare nfe40_enderEmit partner legal_name and name
        by reading nfe40_xNome and nfe40_xFant on nfe40_emit"""
        key_vals = {}
        for k, v in self.fields_get().items():
            if v.get('related') is not None\
                    and hasattr(v['related'], '__len__')\
                    and len(v['related']) == 2\
                    and v['related'][0] == key\
                    and vals.get(k) is not None:
                key_vals[v['related'][1]] = vals[k]
        # if key_vals != {}:
        #     _logger.info("\nEXTRACT RELATED FROM PARENT:", self, key, key_vals)
        # TODO use inside match_or_create??
        return key_vals

    @api.model
    def _prepare_import_dict(self, vals, defaults=False):
        """NOTE: this is debatable if we could use an api multi with values in
        self instead of the vals dict. Then that would be like when new()
        is used in account_invoice or sale_order before playing some onchanges
        """

        if not defaults:
            defaults = dict()  # FIXME: default not used

        related_many2ones = {}
        fields = self.fields_get()
        for k, v in fields.items():
            # select schema choices for a friendly UI:
            if k.startswith('nfe40_choice'):  # TODO schema wise
                for item in v.get('selection', []):
                    if vals.get(item[0]) not in [None, []]:
                        vals[k] = item[0]
                        break

            # reverse map related fields as much as possible
            elif v.get('related') is not None and vals.get(k) is not None:
                if len(v['related']) == 1:
                    vals[v['related'][0]] = vals.get(k)
                elif len(v['related']) == 2 and k.startswith('nfe40_'):  # TODO
                    related_m2o = v['related'][0]
                    # don't mess with _inherits write system
                    if not any(related_m2o == i[1]
                               for i in self._inherits.items()):
                        key_vals = related_many2ones.get(related_m2o, {})
                        key_vals[v['related'][1]] = vals.get(k)
                        related_many2ones[related_m2o] = key_vals

        # now we deal with the related m2o with compound related
        for related_m2o, sub_val in related_many2ones.items():
            comodel_name = fields[related_m2o]['relation']
            comodel = self.get_concrete_model(comodel_name)
            if related_many2ones.get('product_id', {}).get('barcode') and \
                    related_many2ones['product_id']['barcode'] == 'SEM GTIN':
                del related_many2ones['product_id']['barcode']
            if hasattr(comodel, 'match_or_create_m2o'):
                vals[related_m2o] = comodel.match_or_create_m2o(sub_val, vals,
                                                                True)
            else:  # res.country for instance
                vals[related_m2o] = self.match_or_create_m2o(sub_val, vals,
                                                             True, comodel)
        return vals

    @api.model
    def match_record(self, rec_dict, parent_dict, model=None):
        """ inpsired from match_* methods from
        https://github.com/OCA/edi/blob/11.0/base_business_document_import
        /models/business_document_import.py"""
        if model is None:
            model = self
        default_key = [model._rec_name or model._concrete_rec_name or 'name']
        if hasattr(model, '_nfe_search_keys'):  # TODO make schema wise
            keys = model._nfe_search_keys + default_key
        else:
            keys = [model._rec_name or model._concrete_rec_name or 'name']
        if model._name == 'product.product' and rec_dict.get('barcode'):
            keys = ['barcode'] + keys
        for key in keys:
            if rec_dict.get(key):
                # TODO enable to build criteria using parent_dict
                # such as state_id when searching for a city
                if hasattr(model, '_nfe_extra_domain'):
                    domain = model._nfe_extra_domain + [(key, '=',
                                                         rec_dict.get(key))]
                else:
                    domain = [(key, '=', rec_dict.get(key))]
                match_ids = model.search(domain)
                if match_ids:
                    if len(match_ids) > 1:
                        _logger.warning("!! WARNING more than 1 record found!!")
                    return match_ids[0].id
        return False

    @api.model
    def match_or_create_m2o(self, rec_dict, parent_dict,
                            create_m2o=False, model=None):
        """Often the parent_dict can be used to refine the search.
        Passing the model makes it possible to override without inheriting
        from this mixin.
        """
        # TODO log things in chatter like in base_business_document_import
        if model is None:
            model = self
        if hasattr(model, '_match_record'):
            rec_id = model.match_record(rec_dict, parent_dict, model)
        else:
            rec_id = self.match_record(rec_dict, parent_dict, model)
        if not rec_id:
            if create_m2o:
                r = model.create(rec_dict)
                # _logger.info('r %s', r)
                rec_id = r.id
            else:  # do we use it?
                rec_id = model.new(rec_dict).id
        return rec_id
<commit_msg>[REF] Encapsulation<commit_after>import logging

import re
from datetime import datetime
from odoo import api, models
from .spec_models import SpecModel

_logger = logging.getLogger(__name__)

tz_datetime = re.compile(r'.*[-+]0[0-9]:00$')

class AbstractSpecMixin(models.AbstractModel):
    _inherit = 'spec.mixin'

    @api.model
    def build(self, node, defaults=False):

        if not defaults:
            defaults = dict()

        # TODO new or create choice
        # TODO ability to match existing record here
        model_name = SpecModel._get_concrete(self._name) or self._name
        model = self.env[model_name]
        attrs = model.build_attrs(node, create_m2o=True, defaults=defaults)
        return model.create(attrs)

    @api.model
    def build_attrs(self, node, create_m2o=False, path='', defaults=False):
        """A recursive Odoo object builder that works along with the
        GenerateDS object builder from the parsed XML.
        Here we take into account the concrete Odoo objects where the schema
        mixins where injected and possible matcher or builder overrides."""

        if not defaults:
            defaults = dict()

        fields = self.fields_get()
        # no default image for easier debugging
        vals = self.default_get([f for f, v in fields.items()
                                 if v['type'] != 'binary'])
        if path == '':
            vals.update(defaults)
        # we sort attrs to be able to define m2o related values
        sorted_attrs = sorted(node.member_data_items_,
                              key=lambda a: a.get_container() in [0, 1],
                              reverse=True)
        for attr in sorted_attrs:
            self._build_attr(node, fields, vals, path, attr, create_m2o,
                             defaults)

        vals = self._prepare_import_dict(vals, defaults=defaults)
        return vals

    def _build_attr(self, node, fields, vals, path, attr, create_m2o,
                    defaults):
        value = getattr(node, attr.get_name())
        if value is None or value == []:
            return False
        key = "nfe40_%s" % (attr.get_name(),)  # TODO schema wise
        child_path = '%s.%s' % (path, key)

        if attr.get_child_attrs().get('type') is None\
                or attr.get_child_attrs().get('type') == 'xs:string':
            # SimpleType
            if fields[key]['type'] == 'datetime':
                if 'T' in value:
                    if tz_datetime.match(value):
                        old_value = value
                        value = old_value[:19]
                        # TODO see python3/pysped/xml_sped/base.py#L692
                    value = datetime.strptime(value, '%Y-%m-%dT%H:%M:%S')

            self._build_string_not_simple_type(key, vals, value, node)

        else:
            # ComplexType
            if fields.get(key) and fields[key].get('related'):
                # example: company.nfe40_enderEmit related on partner_id
                # then we need to set partner_id, not nfe40_enderEmit
                key = fields[key]['related'][-1]  # -1 works with _inherits
                comodel_name = fields[key]['relation']
            else:
                clean_type = attr.get_child_attrs()[
                    'type'].replace('Type', '').lower()
                comodel_name = "nfe.40.%s" % (clean_type,)  # TODO clean

            comodel = self.get_concrete_model(comodel_name)

            if attr.get_container() == 0:
                # m2o
                new_value = comodel.build_attrs(value,
                                                create_m2o=create_m2o,
                                                path=child_path,
                                                defaults=defaults)
                child_defaults = self._extract_related_values(vals, key)

                new_value.update(child_defaults)
                self._build_many2one(comodel, vals, new_value, key,
                                     create_m2o)
            elif attr.get_container() == 1:
                # o2m
                lines = []
                for line in [l for l in value if l]:
                    line_vals = comodel.build_attrs(line,
                                                    create_m2o=create_m2o,
                                                    path=child_path,
                                                    defaults=defaults)
                    lines.append((0, 0, line_vals))
                vals[key] = lines

    def _build_string_not_simple_type(self, key, vals, value, node):
        vals[key] = value

    def _build_many2one(self, comodel, vals, new_value, key, create_m2o):
        if comodel._name == self._name:
            # stacked m2o
            vals.update(new_value)
        else:
            vals[key] = comodel.match_or_create_m2o(
                new_value, vals, create_m2o)

    @api.model
    def get_concrete_model(self, comodel_name):
        "Lookup for concrete models where abstract schema mixins were injected"
        if comodel_name == 'nfe.40.tenderemi':  # TODO not a related field
            comodel_name = 'res.partner'
        if hasattr(models.MetaModel, 'mixin_mappings') \
                and models.MetaModel.mixin_mappings.get(comodel_name)\
                is not None:
            return self.env[models.MetaModel.mixin_mappings[comodel_name]]
        else:
            return self.env[comodel_name]

    @api.model
    def _extract_related_values(self, vals, key):
        """Example: prepare nfe40_enderEmit partner legal_name and name
        by reading nfe40_xNome and nfe40_xFant on nfe40_emit"""
        key_vals = {}
        for k, v in self.fields_get().items():
            if v.get('related') is not None\
                    and hasattr(v['related'], '__len__')\
                    and len(v['related']) == 2\
                    and v['related'][0] == key\
                    and vals.get(k) is not None:
                key_vals[v['related'][1]] = vals[k]
        # if key_vals != {}:
        #     _logger.info("\nEXTRACT RELATED FROM PARENT:", self, key, key_vals)
        # TODO use inside match_or_create??
        return key_vals

    @api.model
    def _prepare_import_dict(self, vals, defaults=False):
        """NOTE: this is debatable if we could use an api multi with values in
        self instead of the vals dict. Then that would be like when new()
        is used in account_invoice or sale_order before playing some onchanges
        """

        if not defaults:
            defaults = dict()  # FIXME: default not used

        related_many2ones = {}
        fields = self.fields_get()
        for k, v in fields.items():
            # select schema choices for a friendly UI:
            if k.startswith('nfe40_choice'):  # TODO schema wise
                for item in v.get('selection', []):
                    if vals.get(item[0]) not in [None, []]:
                        vals[k] = item[0]
                        break

            # reverse map related fields as much as possible
            elif v.get('related') is not None and vals.get(k) is not None:
                if len(v['related']) == 1:
                    vals[v['related'][0]] = vals.get(k)
                elif len(v['related']) == 2 and k.startswith('nfe40_'):  # TODO
                    related_m2o = v['related'][0]
                    # don't mess with _inherits write system
                    if not any(related_m2o == i[1]
                               for i in self._inherits.items()):
                        key_vals = related_many2ones.get(related_m2o, {})
                        key_vals[v['related'][1]] = vals.get(k)
                        related_many2ones[related_m2o] = key_vals

        # now we deal with the related m2o with compound related
        for related_m2o, sub_val in related_many2ones.items():
            comodel_name = fields[related_m2o]['relation']
            comodel = self.get_concrete_model(comodel_name)
            related_many2ones = \
                self._verify_related_many2ones(related_many2ones)
            if hasattr(comodel, 'match_or_create_m2o'):
                vals[related_m2o] = comodel.match_or_create_m2o(sub_val, vals,
                                                                True)
            else:  # res.country for instance
                vals[related_m2o] = self.match_or_create_m2o(sub_val, vals,
                                                             True, comodel)
        return vals

    def _verify_related_many2ones(self, related_many2ones):
        return related_many2ones

    @api.model
    def match_record(self, rec_dict, parent_dict, model=None):
        """ inpsired from match_* methods from
        https://github.com/OCA/edi/blob/11.0/base_business_document_import
        /models/business_document_import.py"""
        if model is None:
            model = self
        default_key = [model._rec_name or model._concrete_rec_name or 'name']
        if hasattr(model, '_nfe_search_keys'):  # TODO make schema wise
            keys = model._nfe_search_keys + default_key
        else:
            keys = [model._rec_name or model._concrete_rec_name or 'name']
        keys = self._get_aditional_keys(model, rec_dict, keys)
        for key in keys:
            if rec_dict.get(key):
                # TODO enable to build criteria using parent_dict
                # such as state_id when searching for a city
                if hasattr(model, '_nfe_extra_domain'):
                    domain = model._nfe_extra_domain + [(key, '=',
                                                         rec_dict.get(key))]
                else:
                    domain = [(key, '=', rec_dict.get(key))]
                match_ids = model.search(domain)
                if match_ids:
                    if len(match_ids) > 1:
                        _logger.warning(
                            "!! WARNING more than 1 record found!!")
                    return match_ids[0].id
        return False

    def _get_aditional_keys(self, model, rec_dict, keys):
        return keys

    @api.model
    def match_or_create_m2o(self, rec_dict, parent_dict,
                            create_m2o=False, model=None):
        """Often the parent_dict can be used to refine the search.
        Passing the model makes it possible to override without inheriting
        from this mixin.
        """
        # TODO log things in chatter like in base_business_document_import
        if model is None:
            model = self
        if hasattr(model, '_match_record'):
            rec_id = model.match_record(rec_dict, parent_dict, model)
        else:
            rec_id = self.match_record(rec_dict, parent_dict, model)
        if not rec_id:
            if create_m2o:
                r = model.create(rec_dict)
                # _logger.info('r %s', r)
                rec_id = r.id
            else:  # do we use it?
                rec_id = model.new(rec_dict).id
        return rec_id
<|endoftext|>


<commit_before>#
# template_serializer.py
#
# Copyright (c) 2013 Luis Garcia.
# This source file is subject to terms of the MIT License. (See accompanying file LICENSE)
#

"""
Template serializer library.
Based in Brevé, http://breve.twisty-industries.com/
"""

import itertools

class TagBase:
	def __init__(self):
		self._children = []

	def __repr__(self):
		return '{0} {1}'.format(self.__class__.__name__, self.__dict__)

	def __eq__(self, other):
		return self.__dict__ == other.__dict__

	def set_arguments():
		return self

	def set_children(self, children):
		self._children = children
		return self

	@property
	def children(self):
		return self._children

class Tag:
	def __init__(self, class_):
		self._element = class_()
		self._children = []

	def __call__(self, ** args):
		self._element.set_arguments(** args)
		return self

	def __getitem__(self, children):
		if isinstance(children, tuple):
			self._children = list(children)
		else:
			self._children = [children]
		return self

	def _list(self):
		return [self]

	def flatten(self):
		source = itertools.chain(* (t._list() for t in self._children))
		items = [e.flatten() for e in source]
		if len(items) > 0:
			self._element.set_children(items)
		return self._element

class TagHandler:
	def __init__(self, class_):
		self._class = class_

	def __call__(self, ** args):
		return Tag(self._class)(** args)

	def __getitem__(self, children):
		return Tag(self._class)[children]

	def flatten(self):
		return Tag(self._class).flatten()

	def _list(self):
		return Tag(self._class)._list()

class ForEachHandler:
	def __init__(self, enumerable, function):
		self._enumerable = enumerable
		self._function = function

	def _list(self):
		return itertools.chain(* (self._function(e)._list() for e in self._enumerable))

def for_each(enumerable, function):
	return ForEachHandler(enumerable, function)
<commit_msg>Add serializer<commit_after>#
# template_serializer.py
#
# Copyright (c) 2013 Luis Garcia.
# This source file is subject to terms of the MIT License. (See accompanying file LICENSE)
#

"""
Template serializer library.
Based in Brevé, http://breve.twisty-industries.com/
"""

import itertools

class TagBase:
	def __init__(self):
		self._children = []

	def __repr__(self):
		return '{0} {1}'.format(self.__class__.__name__, self.__dict__)

	def __eq__(self, other):
		return self.__dict__ == other.__dict__

	def set_arguments(self):
		return self

	def set_children(self, children):
		self._children = children
		return self

	def serialize(self, context):
		for child in self._children:
			child.serialize(context)

	@property
	def children(self):
		return self._children

class Tag:
	def __init__(self, class_):
		self._element = class_()
		self._children = []

	def __call__(self, ** args):
		self._element.set_arguments(** args)
		return self

	def __getitem__(self, children):
		if isinstance(children, tuple):
			self._children = list(children)
		else:
			self._children = [children]
		return self

	def serialize(self, context):
		return self.flatten().serialize(context)

	def _list(self):
		return [self]

	def flatten(self):
		source = itertools.chain(* list(t._list() for t in self._children))
		items = [e.flatten() for e in source]
		if len(items) > 0:
			self._element.set_children(items)
		return self._element

class TagHandler:
	def __init__(self, class_):
		self._class = class_

	def __call__(self, ** args):
		return Tag(self._class)(** args)

	def __getitem__(self, children):
		return Tag(self._class)[children]

	def flatten(self):
		return Tag(self._class).flatten()

	def _list(self):
		return Tag(self._class)._list()

class ForEachHandler:
	def __init__(self, enumerable, function):
		self._enumerable = enumerable
		self._function = function

	def _list(self):
		return itertools.chain(* list(self._function(e)._list() for e in self._enumerable))

class SerializerContext:
	def __init__(self):
		self._output = ''
		self._indentation = 0

	def write(self, str):
		self._output += ' ' * self._indentation + str + '\n'

	def new_line(self):
		self._output += '\n'

	def indent(self):
		self._indentation += 4

	def unindent(self):
		self._indentation -= 4

	@property
	def indentation(self):
		return self._indentation

	@property
	def output(self):
		return self._output

class Serializer:
	def serialize(self, template):
		context = SerializerContext()
		template.serialize(context)
		return context.output

def for_each(enumerable, function):
	return ForEachHandler(enumerable, function)
<|endoftext|>


<commit_before>from boolean import *

def simplify_by_unit_clause(phi, l):
    """
    :param phi: formula
    :param l: unit clause
    :return: simplified formula phi by l
    """
    not_l = Not(l).simplify()
    simpl_phi = []
    for conjunct in phi.terms:
        temp_conj = []
        if isinstance(conjunct, Or):
            for clause in conjunct.terms:
                if clause == l:
                    temp_conj = T
                    break
                elif clause != not_l:
                    temp_conj.append(clause)
            if temp_conj != T:
                if len(temp_conj) > 1:
                    simpl_phi.append(Or(temp_conj))
                else:
                    simpl_phi.append(temp_conj[0])
        elif conjunct == not_l:
            return F
        elif conjunct != l:
            simpl_phi.append(conjunct)
    if len(simpl_phi) == 0:
        return T
    return And(*simpl_phi)

def find_unit_clause(phi):
    """
    Finds the first unit clause in formula phi. If phi has no unit clauses it returns False.
    :param phi: formula
    :return: unit clause or False if there is no unit clause in the formula
    """
    i = 0   # Predpostavljam, da phi.terms ni prazen seznam!
    while i <= len(phi.terms):
        if isinstance(phi.terms[i], Variable):
            return phi.terms[i]
        else:
            i += 1
    return False

def choose_literal(phi):
    """
    This function chooses a literal in case the given formula has no unit clauses.
    :param phi: formula
    :return: a literal
    """
    return phi.terms[0].terms[0]

def SAT_solve(phi, val=[]):
    """
    Main function which takes a formula and computes a satisfying valuation or returns "False" if it is not satisfiable.
    :param phi: formula
    :param val: list of formulas (variables or nots)
    :return: satisfying valuation or False
    """
    valuation = val                     # Seznam z valuacijami
    rep = True                          # V spremenljivki rep se bo kasneje skrival pogoj za
    newphi=phi
    while rep:
        if len(phi.terms) == 0:
            return val
        l = find_unit_clause(newphi)
        if l != False:                  # Če imamo unit clause
            newphi_= simplify_by_unit_clause(newphi, l)
            if newphi_ == F:            # Nek clause se poenostavi v F
                return "unsatisfiable"
            elif newphi_ == T:          # Našli smo valuacijo
                valuation = valuation.append(l)
                return valuation
            else:
                valuation = valuation.append(l)
        else:                           # Če nimamo unit clausa
            l = choose_literal(newphi)  # Izberemo neko spremenljivko
            newphi_ = simplify_by_unit_clause(newphi, l)
            variables_ = SAT_solve(newphi_, variables)
            if variables_ == "unsatisfiable":
                l = Not(l).simplify()
                newphi_ = simplify_by_unit_clause(newphi, l)
                variables_=SAT_solve(newphi_, variables)
                if variables_ == "unsatisfiable":
                    return "unsatisfiable"
                else:
                    variables = variables_.append(l)
            else:
                variables = variables_.append(l)
        newphi = newphi_

# Ideja: popravke v valuation označujemo z spremenljivko, ki smo jo na zadnje izbrali v koraku 4. Hkrati izbire na tem
# koraku shranjujemo v nek list, da vedno lahko najdemo zadnjo izbiro.<commit_msg>Improving resetting valuations (in function SAT_solve) in sat_solver<commit_after>from boolean import *

def simplify_by_unit_clause(phi, l):
    """
    :param phi: formula
    :param l: unit clause
    :return: simplified formula phi by l
    """
    not_l = Not(l).simplify()
    simpl_phi = []
    for conjunct in phi.terms:
        temp_conj = []
        if isinstance(conjunct, Or):
            for clause in conjunct.terms:
                if clause == l:
                    temp_conj = T
                    break
                elif clause != not_l:
                    temp_conj.append(clause)
            if temp_conj != T:
                if len(temp_conj) > 1:
                    simpl_phi.append(Or(temp_conj))
                else:
                    simpl_phi.append(temp_conj[0])
        elif conjunct == not_l:
            return F
        elif conjunct != l:
            simpl_phi.append(conjunct)
    if len(simpl_phi) == 0:
        return T
    return And(*simpl_phi)

def find_unit_clause(phi):
    """
    Finds the first unit clause in formula phi. If phi has no unit clauses it returns False.
    :param phi: formula
    :return: unit clause or False if there is no unit clause in the formula
    """
    i = 0   # Predpostavljam, da phi.terms ni prazen seznam!
    while i <= len(phi.terms):
        if isinstance(phi.terms[i], Variable):
            return phi.terms[i]
        else:
            i += 1
    return False

def choose_literal(phi):
    """
    This function chooses a literal in case the given formula has no unit clauses.
    :param phi: formula
    :return: a literal
    """
    return phi.terms[0].terms[0]

def SAT_solve(phi, val=[]):
    """
    Main function which takes a formula and computes a satisfying valuation or returns "False" if it is not satisfiable.
    :param phi: formula
    :param val: list of formulas (variables or nots)
    :return: satisfying valuation or "unsatisfiable"
    """
    valuation = val                     # Seznam z valuacijami
    rep = True                          # V spremenljivki rep se bo kasneje skrival pogoj za
    newphi=phi
    while rep:
        if len(phi.terms) == 0:
            return val
        l = find_unit_clause(newphi)
        if l != False:                  # Če imamo unit clause
            newphi_= simplify_by_unit_clause(newphi, l)
            if newphi_ == F:            # Nek clause se poenostavi v F
                return "unsatisfiable"
            elif newphi_ == T:          # Našli smo valuacijo
                valuation = valuation.append(l)
                return valuation
            else:
                valuation = valuation.append(l)
        else:                           # Če nimamo unit clausa
            l = choose_literal(newphi)  # Izberemo neko spremenljivko
            newphi_ = simplify_by_unit_clause(newphi, l)
            variables_ = SAT_solve(newphi_, variables)
            if variables_ == "unsatisfiable":
                l = Not(l).simplify()
                newphi_ = simplify_by_unit_clause(newphi, l)
                variables_=SAT_solve(newphi_, variables)
                if variables_ == "unsatisfiable":
                    return "unsatisfiable"
                else:
                    variables = variables_.append(l)
            else:
                variables = variables_.append(l)
        newphi = newphi_

<|endoftext|>


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

# Copyright 2012 splinter authors. All rights reserved.
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.

class StatusCode(object):

    http_errors = (400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411,
                   412, 413, 414, 415, 416, 417, 500, 501, 502, 503, 504, 505)

    def __init__(self, status_code, reason):
        #: A message for the response (example: Success)
        self.reason = reason
        #: Code of the response (example: 200)
        self.code = status_code

    def __eq__(self, other):
        return self.code == other

    def __str__(self):
        return "%s - %s" % (self.code, self.reason)

    def is_success(self):
        """
        Returns ``True`` if the response was succeed, otherwise, returns ``False``.
        """
        if self.code not in self.http_errors:
            return True
        return False
<commit_msg>simplify status_code code<commit_after># -*- coding: utf-8 -*-

# Copyright 2012 splinter authors. All rights reserved.
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.

class StatusCode(object):

    def __init__(self, status_code, reason):
        #: A message for the response (example: Success)
        self.reason = reason
        #: Code of the response (example: 200)
        self.code = status_code

    def __eq__(self, other):
        return self.code == other

    def __str__(self):
        return "{} - {}".format(self.code, self.reason)

    def is_success(self):
        """
        Returns ``True`` if the response was succeed, otherwise, returns ``False``.
        """
        return self.code < 400
<|endoftext|>


<commit_before>from operator import itemgetter
from itertools import chain, izip
from functools import partial

from funcy import imap, is_mapping, repeat, icat

from dxr.indexers import iterable_per_line, with_start_and_end, split_into_lines

def callee_needles(graph):
    """Return needles (('c-callee', callee name), span)."""
    return ((('c-callee', call.callee[0]), call.callee[1]) for call
            in graph)

def sig_needles(condensed):
    """Return needles ((c-sig, type), span)."""
    return ((('c-sig', str(o['type'])), o['span']) for o in
            condensed['function'])

def inherit_needles(condensed, tag, func):
    """Return list of needles ((c-tag, val), span).

    :type func: str -> iterable
    :param func: Map node name to an iterable of other node names.
    :param tag: First element in the needle tuple

    """
    children = (izip(func(c['name']), repeat(c['span'])) for c
                in condensed['type'] if c['kind'] == 'class')

    return imap(lambda (a, (b, c)): ((a, b), c),
                izip(repeat('c-{0}'.format(tag)), icat(children)))

def child_needles(condensed, inherit):
    """Return needles representing subclass relationships.

    :type inherit: mapping parent:str -> Set child:str

    """
    return inherit_needles(condensed, 'child',
                           lambda name: inherit.get(name, []))

def parent_needles(condensed, inherit):
    """Return needles representing super class relationships.

    :type inherit: mapping parent:str -> Set child:str

    """
    def get_parents(name):
        return (parent for parent, children in inherit.items()
                if name in children)

    return inherit_needles(condensed, 'parent', get_parents)

def member_needles(condensed):
    """Return needles for the scopes that various symbols belong to."""
    for vals in condensed.itervalues():
        # Many of the fields are grouped by kind
        if is_mapping(vals):
            continue
        for val in vals:
            if 'scope' not in val:
                continue
            yield ('c-member', val['scope']['name']), val['span']

def _over_needles(condensed, tag, name_key, get_span):
    return ((('c-{0}'.format(tag), func['override'][name_key]), get_span(func))
            for func in condensed['function']
            if name_key in func.get('override', []))

def overrides_needles(condensed):
    """Return needles of methods which override the given one."""
    _overrides_needles = partial(_over_needles, condensed=condensed,
                                tag='overrides', get_span=itemgetter('span'))
    return chain(_overrides_needles(name_key='name'),
                 _overrides_needles(name_key='qualname'))

def overridden_needles(condensed):
    """Return needles of methods which are overridden by the given one."""
    get_span = lambda x: x['override']['span']
    _overriden_needles = partial(_over_needles, condensed=condensed,
                                 tag='overridden', get_span=get_span)
    return chain(_overriden_needles(name_key='name'),
                 _overriden_needles(name_key='qualname'))

# def needles(condensed, inherit, graph):
#     """Return all C plugin needles."""
#
#     return chain(
#         parent_needles(condensed, inherit),
#         child_needles(condensed, inherit),
#         member_needles(condensed),
#         overridden_needles(condensed),
#         overrides_needles(condensed),
#         sig_needles(condensed),
#     )

def needles(condensed, name, suffix='', kind=None, subkind=None, keys=('name', 'qualname')):
    """Return an iterable of needles computed from the condensed representation.

    Each needle is a (needle name, needle value dict, Extent) triple.

    :arg name: The main part of the needle name ("function" in
        "c_function") and the key under which the interesting things are
    :arg suffix: The ending of the needle name ("_ref" in "c_var_ref")
        stored in ``condensed``
    :arg kind: The key under which the interesting things are stored in
         ``condensed``. Defaults to the value of ``name``.
    :arg subkind: The value of the 'kind' key to insist on in things found
        within ``condensed[kind]``. None for no insistence.
    :arg keys: The keys that should be in the final needle value

    """
    kind = kind or name
    matches_subkind = (lambda entity: entity['kind'] == subkind if subkind
                       else lambda entity: True)
    return (('c_{0}{1}'.format(name, suffix),
             dict((k, entity[k]) for k in keys),
             entity['span'])
            for entity in condensed[kind] if matches_subkind(entity))

def qualified_needles(condensed, name, kind=None):
    """Return needles for a top-level kind of thing that has a name and qualname."""
    return needles(condensed, name, kind=kind)

def ref_needles(condensed, name, subkind=None, keys=('name', 'qualname')):
    """Return needles for references to a certain kind of thing.

    References are assumed to have names and qualnames.

    :arg subkind: The value of the 'kind' key to insist on in things within
        ``condensed['ref']``. Defaults to ``name``.

    """
    subkind = subkind or name
    return needles(condensed, name, suffix='_ref', kind='ref', subkind=subkind, keys=keys)

def decl_needles(condensed, name, subkind=None, keys=('name', 'qualname')):
    """Return needles for declarations of things.

    Things are assumed to have names and qualnames.

    """
    return needles(condensed, name, suffix='_decl', kind='decldef', subkind=subkind, keys=keys)

def warning_needles(condensed):
    return (('c_warning', {'name': w['msg']}, w['span']) for w in
            condensed['warning'])

def warning_opt_needles(condensed):
    """Return needles about the command-line options that call forth warnings."""
    return (('c_warning_opt', {'name': w['opt']}, w['span']) for w in
            condensed['warning'])

def macro_needles(condensed):
    return (('c_macro', {'name': m['name']}, m['span']) for m in
            condensed['macro'])

def overrides_needles(condensed):
    return (('c_overrides',
             {'name': f['overridename'], 'qualname': f['overridequalname']},
             f['span']) for f in condensed['function'] if 'overridename' in f)

def all_needles(condensed, _):
    return iterable_per_line(with_start_and_end(split_into_lines(chain(
            qualified_needles(condensed, 'function'),
            ref_needles(condensed, 'function'),

            # Classes:
            qualified_needles(condensed, 'type'),
            ref_needles(condensed, 'type'),

            # Typedefs:
            qualified_needles(condensed, 'type', kind='typedef'),
            ref_needles(condensed, 'type', subkind='typedef'),

            qualified_needles(condensed, 'var', kind='variable'),
            ref_needles(condensed, 'var', subkind='variable'),

            qualified_needles(condensed, 'namespace'),
            ref_needles(condensed, 'namespace'),

            qualified_needles(condensed, 'namespace_alias'),
            ref_needles(condensed, 'namespace_alias'),

            macro_needles(condensed),
            ref_needles(condensed, 'macro', keys=('name',)),

            decl_needles(condensed, 'var', subkind='variable'),
            decl_needles(condensed, 'function'),
            decl_needles(condensed, 'type'),

            warning_needles(condensed),
            warning_opt_needles(condensed),

            qualified_needles(condensed, 'call'),

            overrides_needles(condensed),
    ))))
<commit_msg>Remove dead callee_needles().<commit_after>from operator import itemgetter
from itertools import chain, izip
from functools import partial

from funcy import imap, is_mapping, repeat, icat

from dxr.indexers import iterable_per_line, with_start_and_end, split_into_lines

def sig_needles(condensed):
    """Return needles ((c-sig, type), span)."""
    return ((('c-sig', str(o['type'])), o['span']) for o in
            condensed['function'])

def inherit_needles(condensed, tag, func):
    """Return list of needles ((c-tag, val), span).

    :type func: str -> iterable
    :param func: Map node name to an iterable of other node names.
    :param tag: First element in the needle tuple

    """
    children = (izip(func(c['name']), repeat(c['span'])) for c
                in condensed['type'] if c['kind'] == 'class')

    return imap(lambda (a, (b, c)): ((a, b), c),
                izip(repeat('c-{0}'.format(tag)), icat(children)))

def child_needles(condensed, inherit):
    """Return needles representing subclass relationships.

    :type inherit: mapping parent:str -> Set child:str

    """
    return inherit_needles(condensed, 'child',
                           lambda name: inherit.get(name, []))

def parent_needles(condensed, inherit):
    """Return needles representing super class relationships.

    :type inherit: mapping parent:str -> Set child:str

    """
    def get_parents(name):
        return (parent for parent, children in inherit.items()
                if name in children)

    return inherit_needles(condensed, 'parent', get_parents)

def member_needles(condensed):
    """Return needles for the scopes that various symbols belong to."""
    for vals in condensed.itervalues():
        # Many of the fields are grouped by kind
        if is_mapping(vals):
            continue
        for val in vals:
            if 'scope' not in val:
                continue
            yield ('c-member', val['scope']['name']), val['span']

def _over_needles(condensed, tag, name_key, get_span):
    return ((('c-{0}'.format(tag), func['override'][name_key]), get_span(func))
            for func in condensed['function']
            if name_key in func.get('override', []))

def overrides_needles(condensed):
    """Return needles of methods which override the given one."""
    _overrides_needles = partial(_over_needles, condensed=condensed,
                                tag='overrides', get_span=itemgetter('span'))
    return chain(_overrides_needles(name_key='name'),
                 _overrides_needles(name_key='qualname'))

def overridden_needles(condensed):
    """Return needles of methods which are overridden by the given one."""
    get_span = lambda x: x['override']['span']
    _overriden_needles = partial(_over_needles, condensed=condensed,
                                 tag='overridden', get_span=get_span)
    return chain(_overriden_needles(name_key='name'),
                 _overriden_needles(name_key='qualname'))

# def needles(condensed, inherit, graph):
#     """Return all C plugin needles."""
#
#     return chain(
#         parent_needles(condensed, inherit),
#         child_needles(condensed, inherit),
#         member_needles(condensed),
#         overridden_needles(condensed),
#         overrides_needles(condensed),
#         sig_needles(condensed),
#     )

def needles(condensed, name, suffix='', kind=None, subkind=None, keys=('name', 'qualname')):
    """Return an iterable of needles computed from the condensed representation.

    Each needle is a (needle name, needle value dict, Extent) triple.

    :arg name: The main part of the needle name ("function" in
        "c_function") and the key under which the interesting things are
    :arg suffix: The ending of the needle name ("_ref" in "c_var_ref")
        stored in ``condensed``
    :arg kind: The key under which the interesting things are stored in
         ``condensed``. Defaults to the value of ``name``.
    :arg subkind: The value of the 'kind' key to insist on in things found
        within ``condensed[kind]``. None for no insistence.
    :arg keys: The keys that should be in the final needle value

    """
    kind = kind or name
    matches_subkind = (lambda entity: entity['kind'] == subkind if subkind
                       else lambda entity: True)
    return (('c_{0}{1}'.format(name, suffix),
             dict((k, entity[k]) for k in keys),
             entity['span'])
            for entity in condensed[kind] if matches_subkind(entity))

def qualified_needles(condensed, name, kind=None):
    """Return needles for a top-level kind of thing that has a name and qualname."""
    return needles(condensed, name, kind=kind)

def ref_needles(condensed, name, subkind=None, keys=('name', 'qualname')):
    """Return needles for references to a certain kind of thing.

    References are assumed to have names and qualnames.

    :arg subkind: The value of the 'kind' key to insist on in things within
        ``condensed['ref']``. Defaults to ``name``.

    """
    subkind = subkind or name
    return needles(condensed, name, suffix='_ref', kind='ref', subkind=subkind, keys=keys)

def decl_needles(condensed, name, subkind=None, keys=('name', 'qualname')):
    """Return needles for declarations of things.

    Things are assumed to have names and qualnames.

    """
    return needles(condensed, name, suffix='_decl', kind='decldef', subkind=subkind, keys=keys)

def warning_needles(condensed):
    return (('c_warning', {'name': w['msg']}, w['span']) for w in
            condensed['warning'])

def warning_opt_needles(condensed):
    """Return needles about the command-line options that call forth warnings."""
    return (('c_warning_opt', {'name': w['opt']}, w['span']) for w in
            condensed['warning'])

def macro_needles(condensed):
    return (('c_macro', {'name': m['name']}, m['span']) for m in
            condensed['macro'])

def overrides_needles(condensed):
    return (('c_overrides',
             {'name': f['overridename'], 'qualname': f['overridequalname']},
             f['span']) for f in condensed['function'] if 'overridename' in f)

def all_needles(condensed, _):
    return iterable_per_line(with_start_and_end(split_into_lines(chain(
            qualified_needles(condensed, 'function'),
            ref_needles(condensed, 'function'),

            # Classes:
            qualified_needles(condensed, 'type'),
            ref_needles(condensed, 'type'),

            # Typedefs:
            qualified_needles(condensed, 'type', kind='typedef'),
            ref_needles(condensed, 'type', subkind='typedef'),

            qualified_needles(condensed, 'var', kind='variable'),
            ref_needles(condensed, 'var', subkind='variable'),

            qualified_needles(condensed, 'namespace'),
            ref_needles(condensed, 'namespace'),

            qualified_needles(condensed, 'namespace_alias'),
            ref_needles(condensed, 'namespace_alias'),

            macro_needles(condensed),
            ref_needles(condensed, 'macro', keys=('name',)),

            decl_needles(condensed, 'var', subkind='variable'),
            decl_needles(condensed, 'function'),
            decl_needles(condensed, 'type'),

            warning_needles(condensed),
            warning_opt_needles(condensed),

            qualified_needles(condensed, 'call'),

            overrides_needles(condensed),
    ))))
<|endoftext|>