<commit_before>#!/usr/bin/env python
'''''
 This kind of works - if it files a manifest within a dir, it uses that as source reference,
 but it also generates a destination sidecar, so you end up with an outdated source manifest that exists within the folder,
and the enwer sidecar, which contains the md5 within the folder, in a weird recusrsive loop.
Also - copying all of a root drive on osx seems to be close to impossible, unless you ignore hidden folders.
The hidden folders automatically change upon movement, such as spotlight folders. So perhaps there should be a different script
for a whole drive copy, which intentionally skips hidden folders. Ugh.
'''''
import sys
import subprocess
import os
import pdb
import filecmp
from sys import platform as _platform
import tempfile
import time
import argparse
import getpass
import hashlib

def hashlib_md5(filename, manifest):

   m = hashlib.md5()

   with open(str(filename), 'rb') as f:
       while True:
           buf = f.read(2**20)
           if not buf:
               break
           m.update(buf)
   md5_output = m.hexdigest()

   return md5_output + '  ' + os.path.abspath(filename) +  '\n'
# Currently, destination manifest will be overwritten. user input should be required. source manifest will not be overwritten, it will be read.
parser = argparse.ArgumentParser(description='Copy directory with checksum comparison and manifest generation.'
                                 ' Written by Kieran O\'Leary.')
parser.add_argument('source', help='Input directory')
parser.add_argument('destination', help='Destination directory')
parser.add_argument('-b', '-benchmark', action='store_true', help='display benchmark')
#parser.add_argument('-sha', '-sha512', action='store_true', help='use sha512 instead of md5')
'''
if args.sha:
    crf_value = args.crf
else:
    crf_value = '23'
openssl/ and use archivematica tests for verification
'''
global rootpos
rootpos = ''
args = parser.parse_args()

source               = args.source
source_parent_dir    = os.path.dirname(source)

normpath             = os.path.normpath(source)
dirname              = os.path.split(os.path.basename(source))[1]
if dirname == '':

    rootpos = 'y'
    dirname = raw_input('What do you want your destination folder to be called?\n')
relative_path        = normpath.split(os.sep)[-1]

destination                    = args.destination # or hardcode

destination_final_path         = destination + '/%s' % dirname
if rootpos == 'y':
    # manifest will exist within the dir, mirroring what it's like at source. another manifest check needs to be carried out.
    manifest_destination = destination_final_path + '/%s_manifest.md5' % dirname

else:
    manifest_destination           = destination + '/%s_manifest.md5' % dirname
manifest_ =  '/%s_manifest.md5' % dirname
manifest = os.path.expanduser("~/Desktop/%s") % manifest_
manifest_sidecar                = source_parent_dir + '/%s_manifest.md5' % relative_path
manifest_root = source + '/%s_manifest.md5' % os.path.basename(source)
log_name_source_                = dirname + time.strftime("_%Y_%m_%dT%H_%M_%S")

log_name_source = os.path.expanduser("~/Desktop/%s.log") % log_name_source_
log_name_destination           = destination + '/%s_ifi_events_log.log' % dirname

def generate_log(log, what2log):
    if not os.path.isfile(log):
        with open(log,"wb") as fo:
            fo.write(time.strftime("%Y-%m-%dT%H:%M:%S ") + getpass.getuser() + ' ' + what2log + ' \n')
    else:
        with open(log,"ab") as fo:
            fo.write(time.strftime("%Y-%m-%dT%H:%M:%S ") + getpass.getuser() + ' ' + what2log + ' \n')

generate_log(log_name_source, 'move.py started.')
generate_log(log_name_source, 'Source: %s' % source)
generate_log(log_name_source, 'Destination: %s'  % destination)
def display_benchmark():
    print 'SOURCE MANIFEST TIME', source_manifest_time
    print 'COPY TIME', copy_time
    print 'DESTINATION MANIFEST TIME', destination_manifest_time

def test_write_capabilities(directory):
    if os.path.isdir(directory):
        temp = tempfile.mkstemp(dir=directory, suffix='.tmp')
        os.close(temp[0]) # Needed for windows.
        os.remove(temp[1])
    elif os.path.isfile(directory):
        print '\nFile transfer is not currently supported, only directories.\n'
        generate_log(log_name_source, 'Error: Attempted file transfer. Source and Destination must be a directory')
        generate_log(log_name_source, 'move.py exit')
        sys.exit()
    else:
        print ' %s is either not a directory or it does not exist' % directory
        generate_log(log_name_source, ' %s is either not a directory or it does not exist' % directory)
        generate_log(log_name_source, 'move.py exit')
        sys.exit()

def remove_bad_files(root_dir):
    rm_these = ['.DS_Store', 'Thumbs.db', 'desktop.ini']
    for root, dirs, files in os.walk(root_dir):
        for name in files:
            path = os.path.join(root, name)
            for i in rm_these:
                if name == i:
                    print '***********************' + 'removing: ' + path
                    generate_log(log_name_source, 'EVENT = Unwanted file removal - %s was removed' % path)
                    os.remove(path)
manifest_generator = ''
def make_manifest(manifest_dir, relative_manifest_path, manifest_textfile, path_to_remove):
    global manifest_generator
    source_count = 0
    for root, directories, filenames in os.walk(source):
        for files in filenames:
                source_count +=1
    counter2 = 1
    os.chdir(manifest_dir)
    if os.path.isfile(manifest_destination):
        print 'Destination manifest already exists'
    if rootpos == 'y':
        manifest_generator = subprocess.check_output(['md5deep', '-ler', '.'])
    else:
        #manifest_generator = subprocess.check_output(['md5deep', '-ler', relative_manifest_path])
        for root, directories, filenames in os.walk(manifest_dir):
            for files in filenames:
                    if files[0] == '.':
                        print 'DOTFILE'
                        continue
                    print 'processing %s - %d of %d' % (files, counter2, source_count)
                    md5 = hashlib_md5(os.path.join(root, files), manifest)
                    root2 = root.replace(path_to_remove, '')
                    print os.path.dirname(manifest_dir),909090909
                    manifest_generator +=    md5[:32] + ' ' + os.path.join(root2,files).replace("\\", "/") + '\n'
                    counter2 += 1
    manifest_list = manifest_generator.splitlines()
    files_in_manifest = len(manifest_list)
    # http://stackoverflow.com/a/31306961/2188572
    manifest_list = sorted(manifest_list,  key=lambda x:(x[34:]))

    with open(manifest_textfile,"wb") as fo:
        for i in manifest_list:
            fo.write(i + '\n')
    return files_in_manifest

def copy_dir():
    if _platform == "win32":
        subprocess.call(['robocopy',source, destination_final_path, '/E', '/XA:SH'])
        generate_log(log_name_source, 'EVENT = File Transfer - Windows O.S - Software=Robocopy')
    elif _platform == "darwin":
        # https://github.com/amiaopensource/ltopers/blob/master/writelto#L51
        cmd = ['rsync','-rtv', '--stats','--progress', source, destination]
        generate_log(log_name_source, 'EVENT = File Transfer - OSX - Software=gcp')
        print cmd
        subprocess.call(cmd)
    elif _platform == "linux2":
        # https://github.com/amiaopensource/ltopers/blob/master/writelto#L51
        cmd = [ 'cp','--preserve=mode,timestamps', '-nRv',source, destination_final_path]
        generate_log(log_name_source, 'EVENT = File Transfer - Linux- Software=cp')
        subprocess.call(cmd)

def check_overwrite(file2check):
    if os.path.isfile(file2check):
        print 'A manifest already exists at your destination. Overwrite? Y/N?'
        overwrite_destination_manifest = ''
        while overwrite_destination_manifest not in ('Y','y','N','n'):
            overwrite_destination_manifest = raw_input()
            if overwrite_destination_manifest not in ('Y','y','N','n'):
                print 'Incorrect input. Please enter Y or N'
        return overwrite_destination_manifest
def manifest_file_count(manifest2check):
    if os.path.isfile(manifest2check):
        print 'A manifest already exists - Checking if manifest is up to date'
        with open(manifest2check, "r") as fo:
            manifest_lines = [line.split(',') for line in fo.readlines()]
            count_in_manifest =  len(manifest_lines)
    return count_in_manifest

def check_overwrite_dir(dir2check):
    if os.path.isdir(dir2check):
        print 'A directory already exists at your destination. Overwrite? Y/N?'
        overwrite_destination_dir = ''
        while overwrite_destination_dir not in ('Y','y','N','n'):
            overwrite_destination_dir = raw_input()
            if overwrite_destination_dir not in ('Y','y','N','n'):
                print 'Incorrect input. Please enter Y or N'
        return overwrite_destination_dir
'''
try:
    test_write_capabilities(source_parent_dir)
except OSError:
            print 'You cannot write to your source directory!'
            generate_log(log_name_source, 'EVENT = I/O Test - Failure - No write access to source directory.')
            sys.exit()
'''
try:
    test_write_capabilities(destination)
except OSError:
            print 'You cannot write to your destination!'
            generate_log(log_name_source, 'EVENT = I/O Test - Failure - No write access to destination directory.')
            sys.exit()
overwrite_destination_manifest = check_overwrite(manifest_destination)
overwrite_destination_dir = check_overwrite_dir(destination_final_path)

remove_bad_files(source)
source_count = 0

for root, directories, filenames in os.walk(source):
    for files in filenames:
            source_count +=1 #works in windows at least

proceed = 'n'
if os.path.isfile(manifest_root):
    print '1'
    proceed = 'y'
    count_in_manifest = manifest_file_count(manifest_root)
elif os.path.isfile(manifest_sidecar):
    print '2'
    count_in_manifest = manifest_file_count(manifest_sidecar)
    proceed = 'y'
elif os.path.isfile(manifest):
    print '3'
    count_in_manifest = manifest_file_count(manifest)
    proceed = 'y'
if proceed == 'y':
    print manifest
    if source_count != count_in_manifest:
        print source_count, count_in_manifest
        print 'This manifest may be outdated as the number of files in your directory does not match the number of files in the manifest'
        generate_log(log_name_source, 'EVENT = Existing source manifest check - Failure - The number of files in the source directory is not equal to the number of files in the source manifest ')
        sys.exit()
source_manifest_start_time = time.time()

if os.path.isfile(manifest_sidecar):
    print 'Manifest Sidecar exists - Source manifest Generation will be skipped.'
    sys.exit()
elif os.path.isfile(manifest_sidecar):
    print 'Manifest exists within your source directory- Source manifest generation will be skipped.'
elif not os.path.isfile(manifest):
    try:
        print 'Generating source manifest'
        if rootpos == 'y':
            make_manifest(source, relative_path,manifest)
        else:
            make_manifest(source, relative_path,manifest, os.path.dirname(source))
        generate_log(log_name_source, 'EVENT = Generating source manifest')

    except OSError:
            print 'You do not have access to this directory. Perhaps it is read only, or the wrong file system\n'
            sys.exit()

source_manifest_time = time.time() - source_manifest_start_time

copy_start_time = time.time()
if overwrite_destination_dir not in ('N','n'):
    if overwrite_destination_dir != None:
        generate_log(log_name_source, 'EVENT = File Transfer Overwrite - Destination directory already exists - Overwriting.')
    copy_dir()
else:
    generate_log(log_name_source, 'EVENT = File Transfer Overwrite - Destination directory already exists - Not Overwriting.')

copy_time = time.time() - copy_start_time

start_destination_manifest_time = time.time()
if overwrite_destination_manifest not in ('N','n'):
    if overwrite_destination_manifest == None:
        generate_log(log_name_source, 'EVENT = Destination Manifest Generation')
    else:
        generate_log(log_name_source, 'EVENT = Destination Manifest Overwrite - Destination manifest already exists - Overwriting.')
    print 'Generating destination manifest'
    manifest_generator = ''
    if rootpos == 'y':
        files_in_manifest = make_manifest(destination_final_path,dirname, manifest_destination)
    else:
        files_in_manifest = make_manifest(destination,dirname, manifest_destination, destination)

else:
    generate_log(log_name_source, 'EVENT = File Transfer Overwrite - Destination directory already exists - Not Overwriting.')
remove_bad_files(destination_final_path)

destination_manifest_time = time.time() - start_destination_manifest_time
destination_count = 0

for root, directories, filenames in os.walk(destination_final_path):
    for files in filenames:
            destination_count +=1 #works in windows at least
print destination_count

if filecmp.cmp(manifest, manifest_destination, shallow=False):
    print "Your files have reached their destination and the checksums match"
    generate_log(log_name_source, 'EVENT = File Transfer Judgement - Success')
else:
    print "***********YOUR CHECKSUMS DO NOT MATCH*************"
    if overwrite_destination_manifest not in ('N','n'):
        generate_log(log_name_source, 'EVENT = File Transfer Outcome - Failure')
        print ' There are: \n %s files in your destination manifest \n' % files_in_manifest
        print ' %s files in your destination \n %s files at source' % (destination_count, source_count)
        generate_log(log_name_source, 'EVENT = File Transfer Failure Explanation -  %s files in your destination,  %s files at source' % (destination_count, source_count))
    else:
        print ' %s files in your destination \n %s files at source' % (destination_count, source_count)
if args.b:
    display_benchmark()
<commit_msg>moveit - cleanup and ignore hidden files<commit_after>#!/usr/bin/env python

import sys
import subprocess
import os
import pdb
import filecmp
from sys import platform as _platform
import tempfile
import time
import argparse
import getpass
import hashlib

def generate_log(log, what2log):
    if not os.path.isfile(log):
        with open(log,"wb") as fo:
            fo.write(time.strftime("%Y-%m-%dT%H:%M:%S ") + getpass.getuser() + ' ' + what2log + ' \n')
    else:
        with open(log,"ab") as fo:
            fo.write(time.strftime("%Y-%m-%dT%H:%M:%S ") + getpass.getuser() + ' ' + what2log + ' \n')

def hashlib_md5(filename, manifest):
   m = hashlib.md5()
   with open(str(filename), 'rb') as f:
       while True:
           buf = f.read(2**20)
           if not buf:
               break
           m.update(buf)
   md5_output = m.hexdigest()
   return md5_output + '  ' + os.path.abspath(filename) +  '\n'

def display_benchmark():
    print 'SOURCE MANIFEST TIME', source_manifest_time
    print 'COPY TIME', copy_time
    print 'DESTINATION MANIFEST TIME', destination_manifest_time

def test_write_capabilities(directory):
    if os.path.isdir(directory):
        temp = tempfile.mkstemp(dir=directory, suffix='.tmp')
        os.close(temp[0]) # Needed for windows.
        os.remove(temp[1])
    elif os.path.isfile(directory):
        print '\nFile transfer is not currently supported, only directories.\n'
        generate_log(log_name_source, 'Error: Attempted file transfer. Source and Destination must be a directory')
        generate_log(log_name_source, 'move.py exit')
        sys.exit()
    else:
        print ' %s is either not a directory or it does not exist' % directory
        generate_log(log_name_source, ' %s is either not a directory or it does not exist' % directory)
        generate_log(log_name_source, 'move.py exit')
        sys.exit()

def remove_bad_files(root_dir):
    rm_these = ['.DS_Store', 'Thumbs.db', 'desktop.ini']
    for root, dirs, files in os.walk(root_dir):
        for name in files:
            path = os.path.join(root, name)
            for i in rm_these:
                if name == i:
                    print '***********************' + 'removing: ' + path
                    generate_log(log_name_source, 'EVENT = Unwanted file removal - %s was removed' % path)
                    os.remove(path)

def make_manifest(manifest_dir, relative_manifest_path, manifest_textfile, path_to_remove):
    global manifest_generator
    source_count = 0
    for root, directories, filenames in os.walk(source):
        filenames = [f for f in filenames if not f[0] == '.']
        directories[:] = [d for d in directories if not d[0] == '.']
        for files in filenames:
                source_count +=1
    counter2 = 1
    os.chdir(manifest_dir)
    if os.path.isfile(manifest_destination):
        print 'Destination manifest already exists'

    for root, directories, filenames in os.walk(manifest_dir):
            filenames = [f for f in filenames if not f[0] == '.']
            directories[:] = [d for d in directories if not d[0] == '.']
            for files in filenames:

                print 'Generating MD5 for %s - %d of %d' % (files, counter2, source_count)
                md5 = hashlib_md5(os.path.join(root, files), manifest)
                root2 = root.replace(path_to_remove, '')
                manifest_generator +=    md5[:32] + ' ' + os.path.join(root2,files).replace("\\", "/") + '\n'
                counter2 += 1
    manifest_list = manifest_generator.splitlines()
    files_in_manifest = len(manifest_list)
    # http://stackoverflow.com/a/31306961/2188572
    manifest_list = sorted(manifest_list,  key=lambda x:(x[34:]))

    with open(manifest_textfile,"wb") as fo:
        for i in manifest_list:
            fo.write(i + '\n')
    return files_in_manifest

def copy_dir():
    if _platform == "win32":
        subprocess.call(['robocopy',source, destination_final_path, '/E', '/XA:SH'])
        generate_log(log_name_source, 'EVENT = File Transfer - Windows O.S - Software=Robocopy')
    elif _platform == "darwin":
        # https://github.com/amiaopensource/ltopers/blob/master/writelto#L51
        if rootpos == 'y':
            if not os.path.isdir(destination + '/' + dirname):
                os.makedirs(destination + '/' + dirname)
            cmd = ['rsync','-rtv', '--exclude=.*', '--exclude=.*/', '--stats','--progress', source, destination + '/' + dirname]
        else:
            cmd = ['rsync','-rtv', '--exclude=.*', '--exclude=.*/', '--stats','--progress', source, destination]
        generate_log(log_name_source, 'EVENT = File Transfer - OSX - Software=rsync')
        print cmd
        subprocess.call(cmd)
    elif _platform == "linux2":
        # https://github.com/amiaopensource/ltopers/blob/master/writelto#L51
        cmd = [ 'cp','--preserve=mode,timestamps', '-nRv',source, destination_final_path]
        generate_log(log_name_source, 'EVENT = File Transfer - Linux- Software=cp')
        subprocess.call(cmd)

def check_overwrite(file2check):
    if os.path.isfile(file2check):
        print 'A manifest already exists at your destination. Overwrite? Y/N?'
        overwrite_destination_manifest = ''
        while overwrite_destination_manifest not in ('Y','y','N','n'):
            overwrite_destination_manifest = raw_input()
            if overwrite_destination_manifest not in ('Y','y','N','n'):
                print 'Incorrect input. Please enter Y or N'
        return overwrite_destination_manifest
def manifest_file_count(manifest2check):
    if os.path.isfile(manifest2check):
        print 'A manifest already exists - Checking if manifest is up to date'
        with open(manifest2check, "r") as fo:
            manifest_lines = [line.split(',') for line in fo.readlines()]
            count_in_manifest =  len(manifest_lines)
    return count_in_manifest

def check_overwrite_dir(dir2check):
    if os.path.isdir(dir2check):
        print 'A directory already exists at your destination. Overwrite? Y/N?'
        overwrite_destination_dir = ''
        while overwrite_destination_dir not in ('Y','y','N','n'):
            overwrite_destination_dir = raw_input()
            if overwrite_destination_dir not in ('Y','y','N','n'):
                print 'Incorrect input. Please enter Y or N'
        return overwrite_destination_dir
# Currently, destination manifest will be overwritten. user input should be required. source manifest will not be overwritten, it will be read.
parser = argparse.ArgumentParser(description='Copy directory with checksum comparison and manifest generation.'
                                 ' Written by Kieran O\'Leary.')
parser.add_argument('source', help='Input directory')
parser.add_argument('destination', help='Destination directory')
parser.add_argument('-b', '-benchmark', action='store_true', help='display benchmark')
#parser.add_argument('-sha', '-sha512', action='store_true', help='use sha512 instead of md5')

global rootpos
rootpos = ''
args = parser.parse_args()
source               = args.source
source_parent_dir    = os.path.dirname(source)
normpath             = os.path.normpath(source)
dirname              = os.path.split(os.path.basename(source))[1]
if dirname == '':
    rootpos = 'y'
    dirname = raw_input('What do you want your destination folder to be called?\n')
relative_path        = normpath.split(os.sep)[-1]
destination                    = args.destination # or hardcode
destination_final_path         = destination + '/%s' % dirname
manifest_destination = destination + '/%s_manifest.md5' % dirname
manifest_ =  '/%s_manifest.md5' % dirname
manifest = os.path.expanduser("~/Desktop/%s") % manifest_
manifest_sidecar                = source_parent_dir + '/%s_manifest.md5' % relative_path
manifest_root = source + '/%s_manifest.md5' % os.path.basename(source)
log_name_source_                = dirname + time.strftime("_%Y_%m_%dT%H_%M_%S")
log_name_source = os.path.expanduser("~/Desktop/%s.log") % log_name_source_
log_name_destination           = destination + '/%s_ifi_events_log.log' % dirname
generate_log(log_name_source, 'move.py started.')
generate_log(log_name_source, 'Source: %s' % source)
generate_log(log_name_source, 'Destination: %s'  % destination)

manifest_generator = ''

try:
    test_write_capabilities(destination)
except OSError:
            print 'You cannot write to your destination!'
            generate_log(log_name_source, 'EVENT = I/O Test - Failure - No write access to destination directory.')
            sys.exit()
overwrite_destination_manifest = check_overwrite(manifest_destination)
overwrite_destination_dir = check_overwrite_dir(destination_final_path)

remove_bad_files(source)
source_count = 0

for root, directories, filenames in os.walk(source):
    for files in filenames:
            source_count +=1

proceed = 'n'
if os.path.isfile(manifest_root):
    print '1'
    proceed = 'y'
    count_in_manifest = manifest_file_count(manifest_root)
elif os.path.isfile(manifest_sidecar):
    print '2'
    count_in_manifest = manifest_file_count(manifest_sidecar)
    proceed = 'y'
elif os.path.isfile(manifest):
    print '3'
    count_in_manifest = manifest_file_count(manifest)
    proceed = 'y'
if proceed == 'y':
    if source_count != count_in_manifest:
        print source_count, count_in_manifest
        print 'This manifest may be outdated as the number of files in your directory does not match the number of files in the manifest'
        generate_log(log_name_source, 'EVENT = Existing source manifest check - Failure - The number of files in the source directory is not equal to the number of files in the source manifest ')
        sys.exit()
source_manifest_start_time = time.time()

if os.path.isfile(manifest_sidecar):
    print 'Manifest Sidecar exists - Source manifest Generation will be skipped.'
    manifest = manifest_sidecar
elif not os.path.isfile(manifest):
    try:
        print 'Generating source manifest'
        if rootpos == 'y':
            make_manifest(source, relative_path,manifest, source)
        else:
            make_manifest(source, relative_path,manifest, os.path.dirname(source))
        generate_log(log_name_source, 'EVENT = Generating source manifest')

    except OSError:
            print 'You do not have access to this directory. Perhaps it is read only, or the wrong file system\n'
            sys.exit()

source_manifest_time = time.time() - source_manifest_start_time

copy_start_time = time.time()
if overwrite_destination_dir not in ('N','n'):
    if overwrite_destination_dir != None:
        generate_log(log_name_source, 'EVENT = File Transfer Overwrite - Destination directory already exists - Overwriting.')
    copy_dir()
else:
    generate_log(log_name_source, 'EVENT = File Transfer Overwrite - Destination directory already exists - Not Overwriting.')

copy_time = time.time() - copy_start_time
start_destination_manifest_time = time.time()
if overwrite_destination_manifest not in ('N','n'):
    if overwrite_destination_manifest == None:
        generate_log(log_name_source, 'EVENT = Destination Manifest Generation')
    else:
        generate_log(log_name_source, 'EVENT = Destination Manifest Overwrite - Destination manifest already exists - Overwriting.')
    print 'Generating destination manifest'
    manifest_generator = ''
    if rootpos == 'y':
        files_in_manifest = make_manifest(destination_final_path,dirname, manifest_destination, destination)
    else:
        files_in_manifest = make_manifest(destination_final_path,dirname, manifest_destination, destination)
else:
    generate_log(log_name_source, 'EVENT = File Transfer Overwrite - Destination directory already exists - Not Overwriting.')
remove_bad_files(destination_final_path)

destination_manifest_time = time.time() - start_destination_manifest_time
destination_count = 0

for root, directories, filenames in os.walk(destination_final_path):
    for files in filenames:
            destination_count +=1 #works in windows at least
print destination_count

if rootpos == 'y':
    manifest_temp = tempfile.mkstemp(dir=os.path.expanduser("~/Desktop"), suffix='.md5')
    os.close(manifest_temp[0]) # Needed for windows.
    with open(manifest, 'r') as fo:
        dest_manifest_list = fo.readlines()
        with open(manifest_temp[1], 'w') as temp_object:
            for i in dest_manifest_list:
                temp_object.write(i[:33] + '/' + dirname + '/' + i[33:])
        manifest = manifest_temp[1]

if filecmp.cmp(manifest, manifest_destination, shallow=False):
    print "Your files have reached their destination and the checksums match"
    generate_log(log_name_source, 'EVENT = File Transfer Judgement - Success')
else:
    print "***********YOUR CHECKSUMS DO NOT MATCH*************"
    if overwrite_destination_manifest not in ('N','n'):
        generate_log(log_name_source, 'EVENT = File Transfer Outcome - Failure')
        print ' There are: \n %s files in your destination manifest \n' % files_in_manifest
        print ' %s files in your destination \n %s files at source' % (destination_count, source_count)
        generate_log(log_name_source, 'EVENT = File Transfer Failure Explanation -  %s files in your destination,  %s files at source' % (destination_count, source_count))
    else:
        print ' %s files in your destination \n %s files at source' % (destination_count, source_count)
if args.b:
    display_benchmark()
<|endoftext|>


<commit_before>import re
import sublime
import sublime_plugin
class ConsolewrapCommand(sublime_plugin.TextCommand):
    def run(self, edit):
        view = self.view
        cursor = view.sel()[0]
        line_region = view.line(cursor)
        string = view.substr(line_region)
        match = re.search(r"(\s*)", string)

        file_name = view.file_name()
        if file_name is None:
            extension = None
        else:
            extension = file_name[file_name.rfind('.') + 1:]

        if match:
            if cursor.empty():
                var_text = sublime.get_clipboard()
            else:
                var_text = view.substr(cursor)
            if var_text[-1:] == ";":
                var_text = var_text[:-1]

            if len(var_text) == 0:
                sublime.status_message('Please make a selection or copy something.')
            else:
                var_text_escaped = var_text.replace("'", "\\'")
                text = ConsolewrapCommand.get_wrapper(extension, match.group(1), var_text, var_text_escaped)
                view.insert(edit, line_region.end(), text)
                end = view.line(line_region.end() + 1).end()
                view.sel().clear()
                view.sel().add(sublime.Region(end, end))

    @staticmethod
    def get_wrapper(lang, spaces, var_text, var_text_escaped):
        if lang == 'rb':
            return "\n%sputs '-----------------------------[log][auto][%s]:';p %s" % (spaces, var_text_escaped, var_text)
        elif lang == 'erb':
            return "<% \n%sputs '-----------------------------[log][auto][%s]:';p %s %>" % (spaces, var_text_escaped, var_text)
        else:
            return "\n%sconsole.log('%s ' , %s);" % (spaces, var_text_escaped, var_text)

class ConsoleremoveCommand(sublime_plugin.TextCommand):
    def run(self, edit):
        self.get_selections()
        cursor = self.view.sel()[0]
        line_region = self.view.line(cursor)
        string = self.view.substr(line_region)
        newstring = re.sub(r"(?m)^((?!//|/\*).)*console\.log.*", '', string)
        self.view.replace(edit, line_region, newstring)
        self.view.sel().clear()

    def get_selections(self):
        selections = self.view.sel()
        has_selections = False
        for sel in selections:
            if sel.empty() == False:
                has_selections = True
        if not has_selections:
            full_region = sublime.Region(0, self.view.size())
            selections.add(full_region)
        return selections
<commit_msg>Fixed .erb<commit_after>import re
import sublime
import sublime_plugin
class ConsolewrapCommand(sublime_plugin.TextCommand):
    def run(self, edit):
        view = self.view
        cursor = view.sel()[0]
        line_region = view.line(cursor)
        string = view.substr(line_region)
        match = re.search(r"(\s*)", string)

        file_name = view.file_name()
        if file_name is None:
            extension = None
        else:
            extension = file_name[file_name.rfind('.') + 1:]

        if match:
            if cursor.empty():
                var_text = sublime.get_clipboard()
            else:
                var_text = view.substr(cursor)
            if var_text[-1:] == ";":
                var_text = var_text[:-1]

            if len(var_text) == 0:
                sublime.status_message('Please make a selection or copy something.')
            else:
                var_text_escaped = var_text.replace("'", "\\'")
                text = ConsolewrapCommand.get_wrapper(extension, match.group(1), var_text, var_text_escaped)
                view.insert(edit, line_region.end(), text)
                end = view.line(line_region.end() + 1).end()
                view.sel().clear()
                view.sel().add(sublime.Region(end, end))

    @staticmethod
    def get_wrapper(lang, spaces, var_text, var_text_escaped):
        if lang == 'rb':
            return "\n%sputs '-----------------------------[log][auto][%s]:';p %s" % (spaces, var_text_escaped, var_text)
        elif lang == 'erb':
            return "\n<%% %sputs '-----------------------------[log][auto][%s]:';p %s %%>" % (spaces, var_text_escaped, var_text)
        else:
            return "\n%sconsole.log('%s ' , %s);" % (spaces, var_text_escaped, var_text)

class ConsoleremoveCommand(sublime_plugin.TextCommand):
    def run(self, edit):
        self.get_selections()
        cursor = self.view.sel()[0]
        line_region = self.view.line(cursor)
        string = self.view.substr(line_region)
        newstring = re.sub(r"(?m)^((?!//|/\*).)*console\.log.*", '', string)
        self.view.replace(edit, line_region, newstring)
        self.view.sel().clear()

    def get_selections(self):
        selections = self.view.sel()
        has_selections = False
        for sel in selections:
            if sel.empty() == False:
                has_selections = True
        if not has_selections:
            full_region = sublime.Region(0, self.view.size())
            selections.add(full_region)
        return selections
<|endoftext|>


<commit_before>"""
This is the primary entry point for Cassiopeia. Accesses the LoL REST API (https://developer.riotgames.com/) and provides the results in easy-to-use Python objects.
"""

import urllib.request
import sys

import cassiopeia.dto.requests
import cassiopeia.type.api.rates
import cassiopeia.dto.staticdataapi
import cassiopeia.core.requests
import cassiopeia.type.core.common
import cassiopeia.type.api.store
from cassiopeia.core.championapi import *
from cassiopeia.core.currentgameapi import *
from cassiopeia.core.featuredgamesapi import *
from cassiopeia.core.gameapi import *
from cassiopeia.core.leagueapi import *
from cassiopeia.core.matchapi import *
from cassiopeia.core.matchlistapi import *
from cassiopeia.core.staticdataapi import *
from cassiopeia.core.statusapi import *
from cassiopeia.core.statsapi import *
from cassiopeia.core.summonerapi import *
from cassiopeia.core.teamapi import *

def set_api_key(key):
    """Set your API key

    key    str    the key to use
    """
    cassiopeia.dto.requests.api_key = key

def set_region(region):
    """Set the region to run API queries against

    region    str | cassiopeia.type.core.common.Region    the region to query against
    """
    if(isinstance(region, cassiopeia.type.core.common.Region)):
        region = cassiopeia.type.core.common.Region(region.lower())
    cassiopeia.dto.requests.region = region.value

def print_calls(on):
    """Sets whether to print calls to stdout as they are made

    on    bool    the region to query against
    """
    cassiopeia.dto.requests.print_calls = on

def set_rate_limit(calls_per_epoch, seconds_per_epoch):
    """Sets the rate limit for cassiopeia to manage internally

    calls_per_epoch      int    the number of calls allowed in each epoch
    seconds_per_epoch    int    the number of seconds per epoch
    """
    cassiopeia.dto.requests.rate_limiter = cassiopeia.type.api.rates.SingleRateLimiter(calls_per_epoch, seconds_per_epoch)

def set_rate_limits(*limits):
    """Sets the rate limits for cassiopeia to manage internally

    *limits    tuple...    the rate limits to apply. Rate limits are of the form (calls_per_epoch, seconds_per_epoch)
    """
    cassiopeia.dto.requests.rate_limiter = cassiopeia.type.api.rates.MultiRateLimiter(*limits)

def set_proxy(url, port=80):
    """Sets a proxy server to tunnel requests to the Riot API through

    url     str    the URL of the proxy server, without port number or protocol
    port    int    the port number to conntect to (default 80)
    """
    if(url):
        cassiopeia.dto.requests.proxy = urllib.request.ProxyHandler({"https": "https://{url}:{port}".format(url=url, port=port)})
        urllib.request.install_opener(urllib.request.build_opener(cassiopeia.dto.requests.proxy))
    else:
        cassiopeia.dto.requests.proxy = urllib.request.ProxyHandler({})
        urllib.request.install_opener(urllib.request.build_opener(cassiopeia.dto.requests.proxy))

def set_locale(locale):
    """Sets the locale (language) to use for calls to the Riot API. Use get_languages() to find valid locales.

    locale    str    the locale to use for calls to the API
    """
    cassiopeia.dto.staticdataapi._locale = locale

def set_load_policy(policy):
    """Sets the load policy to use. Keep your load policy in mind when making calls, as different policies are better for different applications.

    policy    str | cassiopeia.type.core.common.LoadPolicy    the load policy to use for calls to the API
    """
    if(isinstance(policy, cassiopeia.type.core.common.LoadPolicy)):
        policy = cassiopeia.type.core.common.LoadPolicy(policy.upper())
    cassiopeia.core.requests.load_policy = policy

def set_data_store(store):
    """Sets the data store to use for caching the results of API calls.

    store    cassiopeia.type.api.store.DataStore    the data store to use for storing results
    """
    if(not store):
        cassiopeia.core.requests.data_store = cassiopeia.type.api.store.VoidDataStore()
    else:
        cassiopeia.core.requests.data_store = store
<commit_msg>switch conditionals woops<commit_after>"""
This is the primary entry point for Cassiopeia. Accesses the LoL REST API (https://developer.riotgames.com/) and provides the results in easy-to-use Python objects.
"""

import urllib.request
import sys

import cassiopeia.dto.requests
import cassiopeia.type.api.rates
import cassiopeia.dto.staticdataapi
import cassiopeia.core.requests
import cassiopeia.type.core.common
import cassiopeia.type.api.store
from cassiopeia.core.championapi import *
from cassiopeia.core.currentgameapi import *
from cassiopeia.core.featuredgamesapi import *
from cassiopeia.core.gameapi import *
from cassiopeia.core.leagueapi import *
from cassiopeia.core.matchapi import *
from cassiopeia.core.matchlistapi import *
from cassiopeia.core.staticdataapi import *
from cassiopeia.core.statusapi import *
from cassiopeia.core.statsapi import *
from cassiopeia.core.summonerapi import *
from cassiopeia.core.teamapi import *

def set_api_key(key):
    """Set your API key

    key    str    the key to use
    """
    cassiopeia.dto.requests.api_key = key

def set_region(region):
    """Set the region to run API queries against

    region    str | cassiopeia.type.core.common.Region    the region to query against
    """
    if(not isinstance(region, cassiopeia.type.core.common.Region)):
        region = cassiopeia.type.core.common.Region(region.lower())
    cassiopeia.dto.requests.region = region.value

def print_calls(on):
    """Sets whether to print calls to stdout as they are made

    on    bool    the region to query against
    """
    cassiopeia.dto.requests.print_calls = on

def set_rate_limit(calls_per_epoch, seconds_per_epoch):
    """Sets the rate limit for cassiopeia to manage internally

    calls_per_epoch      int    the number of calls allowed in each epoch
    seconds_per_epoch    int    the number of seconds per epoch
    """
    cassiopeia.dto.requests.rate_limiter = cassiopeia.type.api.rates.SingleRateLimiter(calls_per_epoch, seconds_per_epoch)

def set_rate_limits(*limits):
    """Sets the rate limits for cassiopeia to manage internally

    *limits    tuple...    the rate limits to apply. Rate limits are of the form (calls_per_epoch, seconds_per_epoch)
    """
    cassiopeia.dto.requests.rate_limiter = cassiopeia.type.api.rates.MultiRateLimiter(*limits)

def set_proxy(url, port=80):
    """Sets a proxy server to tunnel requests to the Riot API through

    url     str    the URL of the proxy server, without port number or protocol
    port    int    the port number to conntect to (default 80)
    """
    if(url):
        cassiopeia.dto.requests.proxy = urllib.request.ProxyHandler({"https": "https://{url}:{port}".format(url=url, port=port)})
        urllib.request.install_opener(urllib.request.build_opener(cassiopeia.dto.requests.proxy))
    else:
        cassiopeia.dto.requests.proxy = urllib.request.ProxyHandler({})
        urllib.request.install_opener(urllib.request.build_opener(cassiopeia.dto.requests.proxy))

def set_locale(locale):
    """Sets the locale (language) to use for calls to the Riot API. Use get_languages() to find valid locales.

    locale    str    the locale to use for calls to the API
    """
    cassiopeia.dto.staticdataapi._locale = locale

def set_load_policy(policy):
    """Sets the load policy to use. Keep your load policy in mind when making calls, as different policies are better for different applications.

    policy    str | cassiopeia.type.core.common.LoadPolicy    the load policy to use for calls to the API
    """
    if(not isinstance(policy, cassiopeia.type.core.common.LoadPolicy)):
        policy = cassiopeia.type.core.common.LoadPolicy(policy.upper())
    cassiopeia.core.requests.load_policy = policy

def set_data_store(store):
    """Sets the data store to use for caching the results of API calls.

    store    cassiopeia.type.api.store.DataStore    the data store to use for storing results
    """
    if(not store):
        cassiopeia.core.requests.data_store = cassiopeia.type.api.store.VoidDataStore()
    else:
        cassiopeia.core.requests.data_store = store
<|endoftext|>


<commit_before>import sys
import logging
from flask_appbuilder.security.models import User

try:
    from app import app, db

except:
    from flask import Flask
    from flask.ext.sqlalchemy import SQLAlchemy

    if len(sys.argv) < 2:
        print "Without typical app structure use parameter to config"
        print "Use example: python hash_db_password.py sqlite:////home/user/application/app.db"
        exit()
    con_str = sys.argv[1]
    app = Flask(__name__)
    app.config['SQLALCHEMY_DATABASE_URI'] = con_str
    db = SQLAlchemy(app)

logging.basicConfig(format='%(asctime)s:%(levelname)s:%(name)s:%(message)s')
logging.getLogger().setLevel(logging.DEBUG)
log = logging.getLogger(__name__)

def add_column(engine, table, column):
    table_name = table.__tablename__
    column_name = column.key
    column_type = column.type.compile(engine.dialect)
    try:
        engine.execute('ALTER TABLE %s ADD COLUMN %s %s' % (table_name, column_name, column_type))
        log.info("Added Column {0} on {1}".format(column_name, table_name))
    except Exception as e:
        log.error("Error adding Column {0} on {1}: {2}".format(column_name, table_name, str(e)))

def alter_column(engine, table, column):
    table_name = table.__tablename__
    column_name = column.key
    column_type = column.type.compile(engine.dialect)
    try:
        engine.execute('ALTER TABLE %s ALTER COLUMN %s %s' % (table_name, column_name, column_type))
        log.info("Altered Column {0} on {1}".format(column_name, table_name))
    except Exception as e:
        log.error("Error altering Column {0} on {1}: {2}".format(column_name, table_name, str(e)))

engine = db.session.get_bind(mapper=None, clause=None)

alter_column(engine, User, User.password)
add_column(engine, User, User.login_count)
add_column(engine, User, User.created_on)
add_column(engine, User, User.changed_on)
add_column(engine, User, User.created_by_fk)
add_column(engine, User, User.changed_by_fk)
add_column(engine, User, User.last_login)
add_column(engine, User, User.fail_login_count)
<commit_msg>Update migrate_db_0.7.py<commit_after>import sys
import logging
from flask_appbuilder.security.models import User

try:
    from app import app, db

except:
    from flask import Flask
    from flask.ext.sqlalchemy import SQLAlchemy

    if len(sys.argv) < 2:
        print "Without typical app structure use parameter to config"
        print "Use example: python hash_db_password.py sqlite:////home/user/application/app.db"
        exit()
    con_str = sys.argv[1]
    app = Flask(__name__)
    app.config['SQLALCHEMY_DATABASE_URI'] = con_str
    db = SQLAlchemy(app)

logging.basicConfig(format='%(asctime)s:%(levelname)s:%(name)s:%(message)s')
logging.getLogger().setLevel(logging.DEBUG)
log = logging.getLogger(__name__)

def add_column(engine, table, column):
    table_name = table.__tablename__
    column_name = column.key
    column_type = column.type.compile(engine.dialect)
    try:
        engine.execute('ALTER TABLE %s ADD COLUMN %s %s' % (table_name, column_name, column_type))
        log.info("Added Column {0} on {1}".format(column_name, table_name))
    except Exception as e:
        log.error("Error adding Column {0} on {1}: {2}".format(column_name, table_name, str(e)))

def alter_column(engine, table, column):
    table_name = table.__tablename__
    column_name = column.key
    column_type = column.type.compile(engine.dialect)
    try:
        engine.execute('ALTER TABLE %s ALTER COLUMN %s TYPE %s' % (table_name, column_name, column_type))
        log.info("Altered Column {0} on {1}".format(column_name, table_name))
    except Exception as e:
        log.error("Error altering Column {0} on {1}: {2}".format(column_name, table_name, str(e)))

engine = db.session.get_bind(mapper=None, clause=None)

alter_column(engine, User, User.password)
add_column(engine, User, User.login_count)
add_column(engine, User, User.created_on)
add_column(engine, User, User.changed_on)
add_column(engine, User, User.created_by_fk)
add_column(engine, User, User.changed_by_fk)
add_column(engine, User, User.last_login)
add_column(engine, User, User.fail_login_count)
<|endoftext|>


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

import rospy
from flexbe_core import EventState, Logger

from flexbe_core.proxy import ProxyActionClient, ProxyPublisher

from hector_move_base_msgs.msg import MoveBaseAction, MoveBaseGoal, MoveBaseActionPath
from rospy import Time

'''
Created on 15.06.2015

@author: Philipp Schillinger
'''

class MoveAlongPath(EventState):
	'''
	Lets the robot move along a given path.

	># path		PoseStamped[]			Array of Positions of the robot.
	># speed	float				Speed of the robot

	<= reached 					Robot is now located at the specified waypoint.
	<= failed 					Failed to send a motion request to the action server.
	'''

	def __init__(self):
		'''
		Constructor
		'''
		super(MoveAlongPath, self).__init__(outcomes=['reached', 'failed'], input_keys=['path','speed'])

		self._failed = False
		self._reached = False

		self._pathTopic = '/controller/path'
		self._pub = ProxyPublisher({self._pathTopic: MoveBaseActionPath})

	def execute(self, userdata):
		'''
		Execute this state
		'''

		if self._failed:
			return 'failed'
		if self._reached:
			return 'reached'

	def on_enter(self, userdata):

		self._path = MoveBaseActionPath()
		#userdata.path.poses = userdata.path.poses.reverse()
		for i in (0, len(userdata.path.poses)-1):
			userdata.path.poses[i].pose.position.x = -userdata.path.poses[i].pose.position.x
			userdata.path.poses[i].pose.position.y = -userdata.path.poses[i].pose.position.y
			userdata.path.poses[i].pose.position.z = -userdata.path.poses[i].pose.position.z
		#userdata.path.poses = list(reversed(userdata.path.poses))
		self._path.goal.target_path.poses = userdata.path.poses
		self._path.header.frame_id = 'map'

		self._failed = False

		self._pub.publish(self._pathTopic, self._path)
		self._reached = True

	def on_stop(self):
			pass

	def on_exit(self, userdata):

			pass

	def on_pause(self):
		self._move_client.cancel(self._action_topic)

	def on_resume(self, userdata):
		self.on_enter(userdata)
<commit_msg>with fixed orientation<commit_after>#!/usr/bin/env python

import rospy
from flexbe_core import EventState, Logger

from flexbe_core.proxy import ProxyActionClient, ProxyPublisher

from hector_move_base_msgs.msg import MoveBaseAction, MoveBaseGoal, MoveBaseActionPath
from rospy import Time

'''
Created on 15.06.2015

@author: Philipp Schillinger
'''

class MoveAlongPath(EventState):
	'''
	Lets the robot move along a given path.

	># path		PoseStamped[]			Array of Positions of the robot.
	># speed	float				Speed of the robot

	<= reached 					Robot is now located at the specified waypoint.
	<= failed 					Failed to send a motion request to the action server.
	'''

	def __init__(self):
		'''
		Constructor
		'''
		super(MoveAlongPath, self).__init__(outcomes=['reached', 'failed'], input_keys=['path','speed'])

		self._failed = False
		self._reached = False

		self._pathTopic = '/controller/path'
		self._pub = ProxyPublisher({self._pathTopic: MoveBaseActionPath})

	def execute(self, userdata):
		'''
		Execute this state
		'''

		if self._failed:
			return 'failed'
		if self._reached:
			return 'reached'

	def on_enter(self, userdata):

		self._path = MoveBaseActionPath()
		#userdata.path.poses = userdata.path.poses.reverse()
		for i in (0, len(userdata.path.poses)-1):
			#userdata.path.poses[i].pose.position.x = -userdata.path.poses[i].pose.position.x
			#userdata.path.poses[i].pose.position.y = -userdata.path.poses[i].pose.position.y
			#userdata.path.poses[i].pose.position.z = -userdata.path.poses[i].pose.position.z
			userdata.path.poses[i].pose.orientation.x = 0
			userdata.path.poses[i].pose.orientation.y = 0
			userdata.path.poses[i].pose.orientation.z = 0
			userdata.path.poses[i].pose.orientation.w = 1
		userdata.path.poses = list(reversed(userdata.path.poses))
		self._path.goal.target_path.poses = userdata.path.poses
		self._path.header.frame_id = 'map'

		self._failed = False

		self._pub.publish(self._pathTopic, self._path)
		self._reached = True

	def on_stop(self):
			pass

	def on_exit(self, userdata):

			pass

	def on_pause(self):
		self._move_client.cancel(self._action_topic)

	def on_resume(self, userdata):
		self.on_enter(userdata)
<|endoftext|>


<commit_before>import subprocess

"""To be run on travis to generate the results data.

Copare to published results and run other tests on it.

Don't do to many."""

subprocess.call("python bin/prepare_data.py -s M0 M3 M6 M9 -l 4.50 -m 0.0", shell=True)

parameters = [("M0", "Z", 1, "60k"),
              ("M0", "Y", 10, "100k"),
              ("M0", "K", 5, "60k 100k"),
              ("M6", "H", 1, "80k"),
              ("M9", "K", 5, "60k"),
              ("M9", "H", 1, "100k"),
              ("M6", "J", 10, "100k"),
              ("M3", "Y", 5, "80k")]

for sptype, band, vel, res in parameters:

    subprocess.call(["python bin/nIR_run.py -s {0} -b {1} -R {2} -v {3}".format(sptype, band, res, vel)], shell=True)

# List data files
subprocess.call(["ls -R data"], shell=True)
<commit_msg>add missing convolution to run.<commit_after>import subprocess

"""To be run on travis to generate the results data.

Copare to published results and run other tests on it.

Don't do to many."""

subprocess.call("python bin/prepare_data.py -s M0 M3 M6 M9 -l 4.50 -m 0.0", shell=True)

parameters = [("M0", "Z", 1, "60k"),
              ("M0", "H", 1, "60k"),
              ("M0", "Y", 10, "100k"),
              ("M0", "K", 5, "60k 100k"),
              ("M6", "H", 1, "80k"),
              ("M9", "K", 5, "60k"),
              ("M9", "H", 1, "100k"),
              ("M6", "J", 10, "100k"),
              ("M3", "Y", 5, "80k")]

for sptype, band, vel, res in parameters:

    subprocess.call(["python bin/nIR_run.py -s {0} -b {1} -R {2} -v {3}".format(sptype, band, res, vel)], shell=True)

# List data files
subprocess.call(["ls -R data"], shell=True)
<|endoftext|>


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

# Copyright (c) 2013 LE GOFF Vincent
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice, this
#   list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright notice,
#   this list of conditions and the following disclaimer in the documentation
#   and/or other materials provided with the distribution.
# * Neither the name of the copyright holder nor the names of its contributors
#   may be used to endorse or promote products derived from this software
#   without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
# OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.

"""Fichier contenant la volonté Tirer."""

import re

from vector import Vector

from primaires.format.fonctions import contient
from primaires.vehicule.vecteur import get_direction
from secondaires.navigation.constantes import get_portee
from secondaires.navigation.equipage.ordres.charger_boulet import ChargerBoulet
from secondaires.navigation.equipage.ordres.charger_poudre import ChargerPoudre
from secondaires.navigation.equipage.ordres.feu import Feu
from secondaires.navigation.equipage.ordres.long_deplacer import LongDeplacer
from secondaires.navigation.equipage.ordres.viser import Viser
from secondaires.navigation.equipage.volonte import Volonte
from secondaires.navigation.visible import Visible

class Tirer(Volonte):

    """Classe représentant une volonté.

    Cette volonté choisit un matelot pour, si besoin, se déplacer
    dans la salle d'un canon, le charger (en poudre et boulet), viser un
    navire adverse et tirer.

    """

    cle = "tirer"
    ordre_court = re.compile(r"^t\s+(.*)$", re.I)
    ordre_long = re.compile(r"^tirer\s+(.*)$", re.I)
    def __init__(self, navire, adverse=None, bruyant=True):
        """Construit une volonté."""
        Volonte.__init__(self, navire)
        self.adverse = adverse
        self.bruyant = bruyant

    @property
    def arguments(self):
        """Propriété à redéfinir si la volonté comprend des arguments."""
        return (self.adverse, self.bruyant)

    def trouver_canon(self, adverse):
        """Trouve le canon qui peut pointer vers adverse."""
        centre = adverse.salles.get((0, 0, 0))
        equipage = self.navire.equipage
        matelots = equipage.get_matelots_ayant_ordre("feu")
        canons = [m.get_ordre("charger_boulet").canon for m in matelots]
        canons = list(set(canons))
        vec_adverse = Vector(*centre.coords.tuple())
        nav_direction = self.navire.direction.direction
        canon_utilise = None
        canon_libre = None
        for salle in self.navire.salles.values():
            t_canon = salle.get_element("canon")
            if t_canon:
                t_vecteur = Vector(*salle.coords.tuple())
                t_distance = vec_adverse - t_vecteur
                t_direction = get_direction(t_distance)
                t_direction = (t_direction - nav_direction) % 360
                if salle.sabord_oriente(t_direction):
                    if t_canon in canons:
                        canon_utilise = t_canon
                    else:
                        canon_libre = t_canon
                        break

        canon = canon_libre or canon_utilise
        return canon

    def choisir_matelots(self, exception=None):
        """Retourne le matelot le plus apte à accomplir la volonté."""
        navire = self.navire
        equipage = navire.equipage
        canon = self.trouver_canon(self.adverse)
        if canon is None:
            return None

        proches = []
        matelots = equipage.get_matelots_au_poste("artilleur",
                exception=exception)
        graph = self.navire.graph
        for matelot in matelots:
            origine = matelot.salle.mnemonic
            destination = canon.parent.mnemonic
            if origine == destination:
                proches.append((matelot, [], canon))
            else:
                chemin = graph.get((origine, destination))
                if chemin:
                    proches.append((matelot, chemin, canon))

        proches = sorted([couple for couple in proches],
                key=lambda couple: len(couple[1]))
        if proches:
            return proches[0]

        return None

    def executer(self, couple):
        """Exécute la volonté."""
        if couple is None:
            self.terminer()
            return

        navire = self.navire
        adverse = self.adverse
        matelot, sorties, canon = couple
        personnage = matelot.personnage
        ordres = []
        if sorties:
            aller = LongDeplacer(matelot, navire, *sorties)
            ordres.append(aller)

        if canon.onces == 0:
            charger_poudre = ChargerPoudre(matelot, navire, canon,
                    self.bruyant)
            ordres.append(charger_poudre)

        if canon.projectile is None:
            charger_boulet = ChargerBoulet(matelot, navire, canon,
                    self.bruyant)
            ordres.append(charger_boulet)

        viser = Viser(matelot, navire, canon, adverse, self.bruyant)
        ordres.append(viser)

        feu = Feu(matelot, navire, canon, self.bruyant)
        ordres.append(feu)
        self.ajouter_ordres(matelot, ordres)

    def crier_ordres(self, personnage):
        """On fait crier l'ordre au personnage."""
        adverse = self.adverse
        msg = "{} s'écrie : un boulet sur {} !".format(
                personnage.distinction_audible, adverse.desc_survol)
        self.navire.envoyer(msg)

    @classmethod
    def extraire_arguments(cls, navire, nom_navire):
        """Extrait les arguments de la volonté."""
        for navire in cls.trouver_navires(navire):
            if contient(navire.desc_survol, nom_navire):
                return (navire, )

        raise ValueError("Le navire {} n'est pas en vue.".format(
                nom_navire))

    @staticmethod
    def trouver_navires(navire):
        """Trouve les navires autour de navire."""
        # On recherche d'abord le personnage
        equipage = navire.equipage
        vigies = equipage.get_matelots_au_poste("vigie")
        if vigies:
            personnage = vigies[0]
        else:
            personnage = navire.personnages[0]

        portee = get_portee(personnage.salle)
        points = Visible.observer(personnage, portee, 5,
                {"": navire})
        navires = [p[1] for p in points.points.values() if \
                isinstance(p[1], type(navire))]
        return navires
<commit_msg>Correction d'un bug dans la volonté tirer<commit_after># -*-coding:Utf-8 -*

# Copyright (c) 2013 LE GOFF Vincent
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice, this
#   list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright notice,
#   this list of conditions and the following disclaimer in the documentation
#   and/or other materials provided with the distribution.
# * Neither the name of the copyright holder nor the names of its contributors
#   may be used to endorse or promote products derived from this software
#   without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
# OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.

"""Fichier contenant la volonté Tirer."""

import re

from vector import Vector

from primaires.format.fonctions import contient
from primaires.vehicule.vecteur import get_direction
from secondaires.navigation.constantes import get_portee
from secondaires.navigation.equipage.ordres.charger_boulet import ChargerBoulet
from secondaires.navigation.equipage.ordres.charger_poudre import ChargerPoudre
from secondaires.navigation.equipage.ordres.feu import Feu
from secondaires.navigation.equipage.ordres.long_deplacer import LongDeplacer
from secondaires.navigation.equipage.ordres.viser import Viser
from secondaires.navigation.equipage.volonte import Volonte
from secondaires.navigation.visible import Visible

class Tirer(Volonte):

    """Classe représentant une volonté.

    Cette volonté choisit un matelot pour, si besoin, se déplacer
    dans la salle d'un canon, le charger (en poudre et boulet), viser un
    navire adverse et tirer.

    """

    cle = "tirer"
    ordre_court = re.compile(r"^t\s+(.*)$", re.I)
    ordre_long = re.compile(r"^tirer\s+(.*)$", re.I)
    def __init__(self, navire, adverse=None, bruyant=True):
        """Construit une volonté."""
        Volonte.__init__(self, navire)
        self.adverse = adverse
        self.bruyant = bruyant

    @property
    def arguments(self):
        """Propriété à redéfinir si la volonté comprend des arguments."""
        return (self.adverse, self.bruyant)

    def trouver_canon(self, adverse):
        """Trouve le canon qui peut pointer vers adverse."""
        centre = adverse.salles.get((0, 0, 0))
        equipage = self.navire.equipage
        matelots = equipage.get_matelots_ayant_ordre("charger_boulet")
        canons = [m.get_ordre("charger_boulet").canon for m in matelots]
        canons = list(set(canons))
        vec_adverse = Vector(*centre.coords.tuple())
        nav_direction = self.navire.direction.direction
        canon_utilise = None
        canon_libre = None
        for salle in self.navire.salles.values():
            t_canon = salle.get_element("canon")
            if t_canon:
                t_vecteur = Vector(*salle.coords.tuple())
                t_distance = vec_adverse - t_vecteur
                t_direction = get_direction(t_distance)
                t_direction = (t_direction - nav_direction) % 360
                if salle.sabord_oriente(t_direction):
                    if t_canon in canons:
                        canon_utilise = t_canon
                    else:
                        canon_libre = t_canon
                        break

        canon = canon_libre or canon_utilise
        return canon

    def choisir_matelots(self, exception=None):
        """Retourne le matelot le plus apte à accomplir la volonté."""
        navire = self.navire
        equipage = navire.equipage
        canon = self.trouver_canon(self.adverse)
        if canon is None:
            return None

        proches = []
        matelots = equipage.get_matelots_au_poste("artilleur",
                exception=exception)
        graph = self.navire.graph
        for matelot in matelots:
            origine = matelot.salle.mnemonic
            destination = canon.parent.mnemonic
            if origine == destination:
                proches.append((matelot, [], canon))
            else:
                chemin = graph.get((origine, destination))
                if chemin:
                    proches.append((matelot, chemin, canon))

        proches = sorted([couple for couple in proches],
                key=lambda couple: len(couple[1]))
        if proches:
            return proches[0]

        return None

    def executer(self, couple):
        """Exécute la volonté."""
        if couple is None:
            self.terminer()
            return

        navire = self.navire
        adverse = self.adverse
        matelot, sorties, canon = couple
        personnage = matelot.personnage
        ordres = []
        if sorties:
            aller = LongDeplacer(matelot, navire, *sorties)
            ordres.append(aller)

        if canon.onces == 0:
            charger_poudre = ChargerPoudre(matelot, navire, canon,
                    self.bruyant)
            ordres.append(charger_poudre)

        if canon.projectile is None:
            charger_boulet = ChargerBoulet(matelot, navire, canon,
                    self.bruyant)
            ordres.append(charger_boulet)

        viser = Viser(matelot, navire, canon, adverse, self.bruyant)
        ordres.append(viser)

        feu = Feu(matelot, navire, canon, self.bruyant)
        ordres.append(feu)
        self.ajouter_ordres(matelot, ordres)

    def crier_ordres(self, personnage):
        """On fait crier l'ordre au personnage."""
        adverse = self.adverse
        msg = "{} s'écrie : un boulet sur {} !".format(
                personnage.distinction_audible, adverse.desc_survol)
        self.navire.envoyer(msg)

    @classmethod
    def extraire_arguments(cls, navire, nom_navire):
        """Extrait les arguments de la volonté."""
        for navire in cls.trouver_navires(navire):
            if contient(navire.desc_survol, nom_navire):
                return (navire, )

        raise ValueError("Le navire {} n'est pas en vue.".format(
                nom_navire))

    @staticmethod
    def trouver_navires(navire):
        """Trouve les navires autour de navire."""
        # On recherche d'abord le personnage
        equipage = navire.equipage
        vigies = equipage.get_matelots_au_poste("vigie")
        if vigies:
            personnage = vigies[0]
        else:
            personnage = navire.personnages[0]

        portee = get_portee(personnage.salle)
        points = Visible.observer(personnage, portee, 5,
                {"": navire})
        navires = [p[1] for p in points.points.values() if \
                isinstance(p[1], type(navire))]
        return navires
<|endoftext|>


<commit_before>"""
Unit tests for PowerExpansion class
"""

__author__ = 'Dallas R. Trinkle'

import unittest
import numpy as np
from scipy.special import sph_harm
import onsager.PowerExpansion as PE

T3D = PE.Taylor3D

class PowerExpansionTests(unittest.TestCase):
    """Tests to make sure our power expansions are constructed correclty and behaving as advertised"""
    def setUp(self):
        """initial setup for testing"""
        self.phi = np.pi*0.2234
        self.theta = np.pi*0.7261
        self.c = T3D()
        self.basis = [(np.eye(2), np.array([0.5,-np.sqrt(0.75),0.])),
         (np.eye(2), np.array([0.5,np.sqrt(0.75),0.])),
         (np.eye(2), np.array([-1.,0.,0.])),
         (np.eye(2), np.array([-0.5,-np.sqrt(0.75),0.])),
         (np.eye(2), np.array([-0.5,np.sqrt(0.75),0.])),
         (np.eye(2), np.array([1.,0.,0.])),
         (np.eye(2)*2, np.array([0.,0.,1.])),
         (np.eye(2)*2, np.array([0.,0.,-1.])),
        ]

    def testExpansionYlmpow(self):
        """Test the expansion of Ylm into powers"""
        for (phi, theta) in [ (self.phi + dp, self.theta + dt)
                              for dp in (0., 0.25*np.pi, 0.5*np.pi, 0.75*np.pi)
                              for dt in (0., 0.5*np.pi, np.pi, 1.5*np.pi)]:
            utest,umagn = T3D.powexp(np.array([np.sin(phi)*np.cos(theta),
                                               np.sin(phi)*np.sin(theta),
                                               np.cos(phi)]))
            self.assertAlmostEquals(umagn, 1)
            Ylm0 = np.zeros(T3D.NYlm, dtype=complex)
            # Ylm as power expansions
            for lm in range(T3D.NYlm):
                l, m = T3D.ind2Ylm[lm][0], T3D.ind2Ylm[lm][1]
                Ylm0[lm] = sph_harm(m, l, theta, phi)
                Ylmexp = np.dot(T3D.Ylmpow[lm], utest)
                self.assertAlmostEquals(Ylm0[lm], Ylmexp,
                                        msg="Failure for Ylmpow l={} m={}; theta={}, phi={}\n{} != {}".format(l, m, theta, phi, Ylm0[lm], Ylmexp))
            # power expansions in Ylm's
            for p in range(T3D.NYlm):
                pYlm = np.dot(T3D.powYlm[p], Ylm0)
                self.assertAlmostEquals(utest[p], pYlm,
                                        msg="Failure for powYlm {}; theta={}, phi={}\n{} != {}".format(T3D.ind2pow[p], theta, phi, utest[p], pYlm))
            # projection (note that Lproj is symmetric)
            for p in range(T3D.NYlm):
                uproj = np.dot(T3D.Lproj[5][p], utest)
                self.assertAlmostEquals(utest[p], uproj,
                                        msg="Projection failure for {}\n{} != {}".format(T3D.ind2pow[p], uproj, utest[p]))

    def testEvaluation(self):
        """Test out the evaluation functions in an expansion, including with scalar multiply and addition"""
        def approxexp(u):
            """4th order expansion of exp(u)"""
            return 1 + u*(1 + u*(0.5 + u*(1/6 + u/24)))
        def createExpansion(n):
            return lambda u: u**n / PE.factorial(n, True)

        for coeff in self.c.constructexpansion(self.basis):
            self.c.addterms(coeff)
        for (n,l) in self.c.nl():
            self.assertEqual(n, l)
        fnu = { (n,l): createExpansion(n) for (n,l) in self.c.nl() } # or could do this in previous loop

        c2 = 2.*self.c
        c3 = self.c + self.c
        c4 = c2 - self.c
        ### NOTE! We have to do it *this way*; otherwise, it will try to use the sum in np.array,
        ### and that WILL NOT WORK with our expansion.
        c5 = self.c + np.eye(2)

        for u in [ np.zeros(3), np.array([1., 0., 0.]), np.array([0., 1., 0.]), np.array([0., 0., 1.]),
                   np.array([0.234, -0.85, 1.25]),
                   np.array([1.24, 0.71, -0.98])]:
            umagn = np.sqrt(np.dot(u, u))
            fval = { nl: f(umagn) for nl,f in fnu.items()}
            # comparison value:
            value = sum(pre*approxexp(np.dot(u, vec)) for pre, vec in self.basis)
            valsum = self.c(u, fval)
            funcsum = self.c(u, fnu)
            dictsum = sum( fval[k]*v for k,v in self.c(u).items())

            self.assertTrue(np.all(np.isclose(value, valsum)),
                            msg="Failure for call with values for {}\n{} != {}".format(u, value, valsum))
            self.assertTrue(np.all(np.isclose(value, funcsum)),
                            msg="Failure for call with function for {}\n{} != {}".format(u, value, funcsum))
            self.assertTrue(np.all(np.isclose(value, dictsum)),
                            msg="Failure for call with dictionary for {}\n{} != {}".format(u, value, dictsum))
            self.assertTrue(np.all(np.isclose(2*value, c2(u, fval))),
                            msg="Failure with scalar multiply?")
            self.assertTrue(np.all(np.isclose(2*value, c3(u, fval))),
                            msg="Failure with addition?")
            self.assertTrue(np.all(np.isclose(value, c4(u, fval))),
                            msg="Failure with subtraction?")
            self.assertTrue(np.all(np.isclose(value + np.eye(2), c5(u, fval))),
                            msg="Failure with scalar addition?")

    def testProduct(self):
        """Test out the evaluation functions in an expansion, including with scalar multiply and addition"""
        def approxexp(u):
            """4th order expansion of exp(u)"""
            return 1 + u*(1 + u*(0.5 + u*(1/6 + u/24)))
        def createExpansion(n):
            return lambda u: u**n / PE.factorial(n, True)

        for coeff in self.c.constructexpansion(self.basis):
            self.c.addterms(coeff)
        for (n,l) in self.c.nl():
            self.assertEqual(n, l)
        fnu = { (n,l): createExpansion(n) for (n,l) in self.c.nl() } # or could do this in previous loop

        c2 = 2.*self.c
        c3 = self.c + self.c
        c4 = c2 - self.c
        ### NOTE! We have to do it *this way*; otherwise, it will try to use the sum in np.array,
        ### and that WILL NOT WORK with our expansion.
        c5 = self.c + np.eye(2)

        for u in [ np.zeros(3), np.array([1., 0., 0.]), np.array([0., 1., 0.]), np.array([0., 0., 1.]),
                   np.array([0.234, -0.85, 1.25]),
                   np.array([1.24, 0.71, -0.98])]:
            umagn = np.sqrt(np.dot(u, u))
            fval = { nl: f(umagn) for nl,f in fnu.items()}
            # comparison value:
            value = sum(pre*approxexp(np.dot(u, vec)) for pre, vec in self.basis)
            valsum = self.c(u, fval)
            funcsum = self.c(u, fnu)
            dictsum = sum( fval[k]*v for k,v in self.c(u).items())

            self.assertTrue(np.all(np.isclose(value, valsum)),
                            msg="Failure for call with values for {}\n{} != {}".format(u, value, valsum))
            self.assertTrue(np.all(np.isclose(value, funcsum)),
                            msg="Failure for call with function for {}\n{} != {}".format(u, value, funcsum))
            self.assertTrue(np.all(np.isclose(value, dictsum)),
                            msg="Failure for call with dictionary for {}\n{} != {}".format(u, value, dictsum))
            self.assertTrue(np.all(np.isclose(2*value, c2(u, fval))),
                            msg="Failure with scalar multiply?")
            self.assertTrue(np.all(np.isclose(2*value, c3(u, fval))),
                            msg="Failure with addition?")
            self.assertTrue(np.all(np.isclose(value, c4(u, fval))),
                            msg="Failure with subtraction?")
            self.assertTrue(np.all(np.isclose(value + np.eye(2), c5(u, fval))),
                            msg="Failure with scalar addition?")
<commit_msg>Some problems with coefflist not being initialized correctly?<commit_after>"""
Unit tests for PowerExpansion class
"""

__author__ = 'Dallas R. Trinkle'

import unittest
import numpy as np
from scipy.special import sph_harm
import onsager.PowerExpansion as PE

T3D = PE.Taylor3D

class PowerExpansionTests(unittest.TestCase):
    """Tests to make sure our power expansions are constructed correclty and behaving as advertised"""
    def setUp(self):
        """initial setup for testing"""
        self.phi = np.pi*0.2234
        self.theta = np.pi*0.7261
        self.c = T3D()
        self.basis = [(np.eye(2), np.array([0.5,-np.sqrt(0.75),0.])),
         (np.eye(2), np.array([0.5,np.sqrt(0.75),0.])),
         (np.eye(2), np.array([-1.,0.,0.])),
         (np.eye(2), np.array([-0.5,-np.sqrt(0.75),0.])),
         (np.eye(2), np.array([-0.5,np.sqrt(0.75),0.])),
         (np.eye(2), np.array([1.,0.,0.])),
         (np.eye(2)*2, np.array([0.,0.,1.])),
         (np.eye(2)*2, np.array([0.,0.,-1.])),
        ]

    def testExpansionYlmpow(self):
        """Test the expansion of Ylm into powers"""
        for (phi, theta) in [ (self.phi + dp, self.theta + dt)
                              for dp in (0., 0.25*np.pi, 0.5*np.pi, 0.75*np.pi)
                              for dt in (0., 0.5*np.pi, np.pi, 1.5*np.pi)]:
            utest,umagn = T3D.powexp(np.array([np.sin(phi)*np.cos(theta),
                                               np.sin(phi)*np.sin(theta),
                                               np.cos(phi)]))
            self.assertAlmostEquals(umagn, 1)
            Ylm0 = np.zeros(T3D.NYlm, dtype=complex)
            # Ylm as power expansions
            for lm in range(T3D.NYlm):
                l, m = T3D.ind2Ylm[lm][0], T3D.ind2Ylm[lm][1]
                Ylm0[lm] = sph_harm(m, l, theta, phi)
                Ylmexp = np.dot(T3D.Ylmpow[lm], utest)
                self.assertAlmostEquals(Ylm0[lm], Ylmexp,
                                        msg="Failure for Ylmpow l={} m={}; theta={}, phi={}\n{} != {}".format(l, m, theta, phi, Ylm0[lm], Ylmexp))
            # power expansions in Ylm's
            for p in range(T3D.NYlm):
                pYlm = np.dot(T3D.powYlm[p], Ylm0)
                self.assertAlmostEquals(utest[p], pYlm,
                                        msg="Failure for powYlm {}; theta={}, phi={}\n{} != {}".format(T3D.ind2pow[p], theta, phi, utest[p], pYlm))
            # projection (note that Lproj is symmetric)
            for p in range(T3D.NYlm):
                uproj = np.dot(T3D.Lproj[5][p], utest)
                self.assertAlmostEquals(utest[p], uproj,
                                        msg="Projection failure for {}\n{} != {}".format(T3D.ind2pow[p], uproj, utest[p]))

    def testEvaluation(self):
        """Test out the evaluation functions in an expansion, including with scalar multiply and addition"""
        def approxexp(u):
            """4th order expansion of exp(u)"""
            return 1 + u*(1 + u*(0.5 + u*(1/6 + u/24)))
        def createExpansion(n):
            return lambda u: u**n / PE.factorial(n, True)

        c = T3D()
        for coeff in c.constructexpansion(self.basis):
            c.addterms(coeff)
        for (n,l) in c.nl():
            self.assertEqual(n, l)
        fnu = { (n,l): createExpansion(n) for (n,l) in c.nl() } # or could do this in previous loop

        c2 = 2.*c
        c3 = c + c
        c4 = c2 - c
        ### NOTE! We have to do it *this way*; otherwise, it will try to use the sum in np.array,
        ### and that WILL NOT WORK with our expansion.
        c5 = c + np.eye(2)

        for u in [ np.zeros(3), np.array([1., 0., 0.]), np.array([0., 1., 0.]), np.array([0., 0., 1.]),
                   np.array([0.234, -0.85, 1.25]),
                   np.array([1.24, 0.71, -0.98])]:
            umagn = np.sqrt(np.dot(u, u))
            fval = { nl: f(umagn) for nl,f in fnu.items()}
            # comparison value:
            value = sum(pre*approxexp(np.dot(u, vec)) for pre, vec in self.basis)
            valsum = c(u, fval)
            funcsum = c(u, fnu)
            dictsum = sum( fval[k]*v for k,v in c(u).items())

            self.assertTrue(np.all(np.isclose(value, valsum)),
                            msg="Failure for call with values for {}\n{} != {}".format(u, value, valsum))
            self.assertTrue(np.all(np.isclose(value, funcsum)),
                            msg="Failure for call with function for {}\n{} != {}".format(u, value, funcsum))
            self.assertTrue(np.all(np.isclose(value, dictsum)),
                            msg="Failure for call with dictionary for {}\n{} != {}".format(u, value, dictsum))
            self.assertTrue(np.all(np.isclose(2*value, c2(u, fval))),
                            msg="Failure with scalar multiply?")
            self.assertTrue(np.all(np.isclose(2*value, c3(u, fval))),
                            msg="Failure with addition?")
            self.assertTrue(np.all(np.isclose(value, c4(u, fval))),
                            msg="Failure with subtraction?")
            self.assertTrue(np.all(np.isclose(value + np.eye(2), c5(u, fval))),
                            msg="Failure with scalar addition?")

    def testProduct(self):
        """Test out the evaluation functions in an expansion, including with scalar multiply and addition"""
        def approxexp(u):
            """4th order expansion of exp(u)"""
            return 1 + u*(1 + u*(0.5 + u*(1/6 + u/24)))
        def createExpansion(n):
            return lambda u: u**n / PE.factorial(n, True)

        a = PE.Taylor3D()
        print("c: ", a.coefflist)
        print(c.constructexpansion(self.basis, N=2))
        for coeff in c.constructexpansion(self.basis, N=2):
            c.addterms(coeff)
        c2 = c * c
        for (n,l) in c2.nl():
            self.assertEqual(n, l)
        fnu = { (n,l): createExpansion(n) for (n,l) in c2.nl() } # or could do this in previous loop

        for u in [ np.zeros(3), np.array([1., 0., 0.]), np.array([0., 1., 0.]), np.array([0., 0., 1.]),
                   np.array([0.234, -0.85, 1.25]),
                   np.array([1.24, 0.71, -0.98])]:
            umagn = np.sqrt(np.dot(u, u))
            fval = { nl: f(umagn) for nl,f in fnu.items()}
            # comparison value:
            value = sum(pre*approxexp(np.dot(u, vec)) for pre, vec in self.basis)
            valsum = c(u, fval)
            funcsum = c(u, fnu)
            dictsum = sum( fval[k]*v for k,v in c(u).items())

            value2 = np.dot(value2, value2)
            valsum2 = c2(u, fval)
            funcsum2 = c2(u, fnu)
            dictsum2 = sum( fval[k]*v for k,v in c2(u).items())

            self.assertTrue(np.all(np.isclose(value, valsum)),
                            msg="Failure for call with values for {}\n{} != {}".format(u, value, valsum))
            self.assertTrue(np.all(np.isclose(value, funcsum)),
                            msg="Failure for call with function for {}\n{} != {}".format(u, value, funcsum))
            self.assertTrue(np.all(np.isclose(value, dictsum)),
                            msg="Failure for call with dictionary for {}\n{} != {}".format(u, value, dictsum))

            self.assertTrue(np.all(np.isclose(value2, valsum2)),
                            msg="Failure for call with values for {}\n{} != {}".format(u, value2, valsum2))
            self.assertTrue(np.all(np.isclose(value2, funcsum2)),
                            msg="Failure for call with function for {}\n{} != {}".format(u, value2, funcsum2))
            self.assertTrue(np.all(np.isclose(value2, dictsum2)),
                            msg="Failure for call with dictionary for {}\n{} != {}".format(u, value2, dictsum2))
<|endoftext|>


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

###
# Copyright (c) 2002, Jeremiah Fincher
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
#   * Redistributions of source code must retain the above copyright notice,
#     this list of conditions, and the following disclaimer.
#   * Redistributions in binary form must reproduce the above copyright notice,
#     this list of conditions, and the following disclaimer in the
#     documentation and/or other materials provided with the distribution.
#   * Neither the name of the author of this software nor the name of
#     contributors to this software may be used to endorse or promote products
#     derived from this software without specific prior written consent.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
###

import sys
sys.path.insert(0, 'src')
sys.path.insert(0, 'test')
sys.path.insert(0, 'plugins')

import conf
conf.dataDir = 'test-data'

from fix import *

import gc
import re
import glob
import time
import os.path
import unittest

if not os.path.exists(conf.dataDir):
    os.mkdir(conf.dataDir)

for filename in os.listdir(conf.dataDir):
    os.remove(os.path.join(conf.dataDir, filename))

import debug

debug.minimumDebugPriority = 'high'

import world
import irclib
import drivers
import ircmsgs
import ircutils

fd = file(os.path.join('test', 'rfc2812.msgs'), 'r')
rawmsgs = [line.strip() for line in fd]
fd.close()

msgs = []
for s in rawmsgs:
    try:
        msgs.append(ircmsgs.IrcMsg(s))
    except:
        print 'IrcMsg constructor failed: %r' % s

nicks = ['fatjim','scn','moshez','LordVan','MetaCosm','pythong','fishfart',
         'alb','d0rt','jemfinch','StyxAlso','fors','deltab','gd',
         'hellz_hunter','are_j|pub_comp','jason_','dreid','sayke_','winjer',
         'TenOfTen','GoNoVas','queuetue','the|zzz','Hellfried','Therion',
         'shro','DaCa','rexec','polin8','r0ky','aaron_','ironfroggy','eugene',
         'faassen','tirloni','mackstann','Yhg1s','ElBarono','vegai','shang',
         'typo_','kikoforgetme','asqui','TazyTiggy','fab','nixman','liiwi',
         'AdamV','paolo','red_one','_AleX_','lament','jamessan','supybot',
         'macr0_zzz','plaisthos','redghost','disco','mphardy','gt3','mathie',
         'jonez','r0ky-office','tic','d33p','ES3merge','talin','af','flippo',
         'sholden','ameoba','shepherg','j2','Acapnotic','dash','merlin262',
         'Taaus','_moshez','rik','jafo__','blk-majik','JT__','itamar',
         'kermit-','davidmccabe','glyph','jojo','dave_p','goo','hyjinx',
         'SamB','exarkun','drewp','Ragica','skylan','redgore','k3','Ra1stlin',
         'StevenK','carball','h3x','carljm','_jacob','teratorn','frangen',
         'phed','datazone','Yaggo','acct_','nowhere','pyn','ThomasWaldmann',
         'dunker','pilotLight','brainless','LoganH_','jmpnz','steinn',
         'EliasREC','lowks__','OldSmrf','Mad77','snibril','delta','psy',
         'skimpIzu','Kengur','MoonFallen','kotkis','Hyperi']

nicks += [msg.nick for msg in msgs if msg.nick]

def getMsgs(command):
    return [msg for msg in msgs if msg.command == command]

class PluginTestCase(unittest.TestCase):
    """Subclass this to write a test case for a plugin.  See test_FunCommands
    for an example.
    """
    timeout = 10
    plugins = ()
    def setUp(self, nick='test'):
        if not self.plugins:
            raise ValueError, 'PluginTestCase must have a "plugins" attribute.'
        self.nick = nick
        self.prefix = ircutils.joinHostmask(nick, 'user', 'host.domain.tld')
        self.irc = irclib.Irc(nick)
        while self.irc.takeMsg():
            pass
        for name in self.plugins:
            module = __import__(name)
            plugin = module.Class()
            self.irc.addCallback(plugin)

    def tearDown(self):
        self.irc.die()
        gc.collect()

    def _feedMsg(self, query, timeout=None):
        if timeout is None:
            timeout = self.timeout
        self.irc.feedMsg(ircmsgs.privmsg(self.nick, query, prefix=self.prefix))
        fed = time.time()
        response = self.irc.takeMsg()
        while response is None and time.time() - fed < timeout:
            drivers.run()
            response = self.irc.takeMsg()
        return response

    def getMsg(self, query, timeout=None):
        return self._feedMsg(query)

    def feedMsg(self, query):
        """Just feeds it a message, that's all."""
        self.irc.feedMsg(ircmsgs.privmsg(self.nick, query, prefix=self.prefix))

    # These assertError/assertNoError are somewhat fragile.  The proper way to
    # do them would be to use a proxy for the irc object and intercept .error.
    # But that would be hard, so I don't bother.  When this breaks, it'll get
    # fixed, but not until then.
    def assertError(self, query):
        m = self._feedMsg(query)
        self.failUnless(m)
        self.failUnless(m.args[1].startswith('Error:'),
                        '%r did not error: %s' % (query, m.args[1]))

    def assertNotError(self, query):
        m = self._feedMsg(query)
        self.failUnless(m)
        self.failIf(m.args[1].startswith('Error:'),
                    '%r errored: %s' % (query, m.args[1]))

    def assertNoResponse(self, query, timeout=None):
        m = self._feedMsg(query, timeout)
        self.failIf(m)

    def assertResponse(self, query, expectedResponse):
        m = self._feedMsg(query)
        self.failUnless(m)
        self.assertEqual(m.args[1], expectedResponse,
                         '%r != %r' % (expectedResponse, m.args[1]))

    def assertRegexp(self, query, regexp):
        m = self._feedMsg(query)
        self.failUnless(m)
        self.failUnless(re.search(regexp, m.args[1]),
                        '%r does not match %r' % (m.args[1], regexp))

    def assertNotRegexp(self, query, regexp):
        m = self._feedMsg(query)
        self.failUnless(m)
        self.failUnless(re.search(regexp, m.args[1]) is None,
                        '%r matched %r' % (m.args[1], regexp))

    def assertRegexps(self, query, regexps):
        started = time.time()
        total = len(regexps)*self.timeout
        while regexps and time.time() - started < total:
            m = self._feedMsg(query)
            self.failUnless(m, msg)
            regexp = regexps.pop(0)
            self.failUnless(re.search(regexp, m.args[1]),
                            '%r does not match %r' % (m.args[1], regexp))
        self.failIf(time.time() - started > total)

    def assertResponses(self, query, expectedResponses):
        responses = []
        started = time.time()
        while len(responses) < len(expectedResponses) and \
                  time.time() - started > len(expectedResponses)*self.timeout:
            m = self._feedMsg(query)
            self.failUnless(m, 'query %r timed out' % query)
            responses.append(m)
        self.assertEqual(len(expectedResponses), len(responses))
        for (m, expected) in zip(responses, expectedResponses):
            self.assertEqual(m.args[1], expected)

if __name__ == '__main__':
    world.testing = True
    if len(sys.argv) > 1:
        files = sys.argv[1:]
    else:
        files = glob.glob(os.path.join('test', 'test_*.py'))
    names = [os.path.splitext(os.path.basename(file))[0] for file in files]
    suite = unittest.defaultTestLoader.loadTestsFromNames(names)
    runner = unittest.TextTestRunner(verbosity=2)
    runner.run(suite)
    print 'Total asserts: %s' % unittest.asserts
    world.testing = False

# vim:set shiftwidth=4 tabstop=8 expandtab textwidth=78:
<commit_msg>Handled more user-friendlyily the case where they forget to make plugins a tuple and just put a string in PluginTestCase.plugins.<commit_after>#!/usr/bin/env python

###
# Copyright (c) 2002, Jeremiah Fincher
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
#   * Redistributions of source code must retain the above copyright notice,
#     this list of conditions, and the following disclaimer.
#   * Redistributions in binary form must reproduce the above copyright notice,
#     this list of conditions, and the following disclaimer in the
#     documentation and/or other materials provided with the distribution.
#   * Neither the name of the author of this software nor the name of
#     contributors to this software may be used to endorse or promote products
#     derived from this software without specific prior written consent.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
###

import sys
sys.path.insert(0, 'src')
sys.path.insert(0, 'test')
sys.path.insert(0, 'plugins')

import conf
conf.dataDir = 'test-data'

from fix import *

import gc
import re
import glob
import time
import os.path
import unittest

if not os.path.exists(conf.dataDir):
    os.mkdir(conf.dataDir)

for filename in os.listdir(conf.dataDir):
    os.remove(os.path.join(conf.dataDir, filename))

import debug

debug.minimumDebugPriority = 'high'

import world
import irclib
import drivers
import ircmsgs
import ircutils

fd = file(os.path.join('test', 'rfc2812.msgs'), 'r')
rawmsgs = [line.strip() for line in fd]
fd.close()

msgs = []
for s in rawmsgs:
    try:
        msgs.append(ircmsgs.IrcMsg(s))
    except:
        print 'IrcMsg constructor failed: %r' % s

nicks = ['fatjim','scn','moshez','LordVan','MetaCosm','pythong','fishfart',
         'alb','d0rt','jemfinch','StyxAlso','fors','deltab','gd',
         'hellz_hunter','are_j|pub_comp','jason_','dreid','sayke_','winjer',
         'TenOfTen','GoNoVas','queuetue','the|zzz','Hellfried','Therion',
         'shro','DaCa','rexec','polin8','r0ky','aaron_','ironfroggy','eugene',
         'faassen','tirloni','mackstann','Yhg1s','ElBarono','vegai','shang',
         'typo_','kikoforgetme','asqui','TazyTiggy','fab','nixman','liiwi',
         'AdamV','paolo','red_one','_AleX_','lament','jamessan','supybot',
         'macr0_zzz','plaisthos','redghost','disco','mphardy','gt3','mathie',
         'jonez','r0ky-office','tic','d33p','ES3merge','talin','af','flippo',
         'sholden','ameoba','shepherg','j2','Acapnotic','dash','merlin262',
         'Taaus','_moshez','rik','jafo__','blk-majik','JT__','itamar',
         'kermit-','davidmccabe','glyph','jojo','dave_p','goo','hyjinx',
         'SamB','exarkun','drewp','Ragica','skylan','redgore','k3','Ra1stlin',
         'StevenK','carball','h3x','carljm','_jacob','teratorn','frangen',
         'phed','datazone','Yaggo','acct_','nowhere','pyn','ThomasWaldmann',
         'dunker','pilotLight','brainless','LoganH_','jmpnz','steinn',
         'EliasREC','lowks__','OldSmrf','Mad77','snibril','delta','psy',
         'skimpIzu','Kengur','MoonFallen','kotkis','Hyperi']

nicks += [msg.nick for msg in msgs if msg.nick]

def getMsgs(command):
    return [msg for msg in msgs if msg.command == command]

class PluginTestCase(unittest.TestCase):
    """Subclass this to write a test case for a plugin.  See test_FunCommands
    for an example.
    """
    timeout = 10
    plugins = ()
    def setUp(self, nick='test'):
        if not self.plugins:
            raise ValueError, 'PluginTestCase must have a "plugins" attribute.'
        self.nick = nick
        self.prefix = ircutils.joinHostmask(nick, 'user', 'host.domain.tld')
        self.irc = irclib.Irc(nick)
        while self.irc.takeMsg():
            pass
        if isinstance(plugins, str):
            module = __import__(name)
            plugin = module.Class()
            self.irc.addCallback(plugin)
        else:
            for name in self.plugins:
                module = __import__(name)
                plugin = module.Class()
                self.irc.addCallback(plugin)

    def tearDown(self):
        self.irc.die()
        gc.collect()

    def _feedMsg(self, query, timeout=None):
        if timeout is None:
            timeout = self.timeout
        self.irc.feedMsg(ircmsgs.privmsg(self.nick, query, prefix=self.prefix))
        fed = time.time()
        response = self.irc.takeMsg()
        while response is None and time.time() - fed < timeout:
            drivers.run()
            response = self.irc.takeMsg()
        return response

    def getMsg(self, query, timeout=None):
        return self._feedMsg(query)

    def feedMsg(self, query):
        """Just feeds it a message, that's all."""
        self.irc.feedMsg(ircmsgs.privmsg(self.nick, query, prefix=self.prefix))

    # These assertError/assertNoError are somewhat fragile.  The proper way to
    # do them would be to use a proxy for the irc object and intercept .error.
    # But that would be hard, so I don't bother.  When this breaks, it'll get
    # fixed, but not until then.
    def assertError(self, query):
        m = self._feedMsg(query)
        self.failUnless(m)
        self.failUnless(m.args[1].startswith('Error:'),
                        '%r did not error: %s' % (query, m.args[1]))

    def assertNotError(self, query):
        m = self._feedMsg(query)
        self.failUnless(m)
        self.failIf(m.args[1].startswith('Error:'),
                    '%r errored: %s' % (query, m.args[1]))

    def assertNoResponse(self, query, timeout=None):
        m = self._feedMsg(query, timeout)
        self.failIf(m)

    def assertResponse(self, query, expectedResponse):
        m = self._feedMsg(query)
        self.failUnless(m)
        self.assertEqual(m.args[1], expectedResponse,
                         '%r != %r' % (expectedResponse, m.args[1]))

    def assertRegexp(self, query, regexp):
        m = self._feedMsg(query)
        self.failUnless(m)
        self.failUnless(re.search(regexp, m.args[1]),
                        '%r does not match %r' % (m.args[1], regexp))

    def assertNotRegexp(self, query, regexp):
        m = self._feedMsg(query)
        self.failUnless(m)
        self.failUnless(re.search(regexp, m.args[1]) is None,
                        '%r matched %r' % (m.args[1], regexp))

    def assertRegexps(self, query, regexps):
        started = time.time()
        total = len(regexps)*self.timeout
        while regexps and time.time() - started < total:
            m = self._feedMsg(query)
            self.failUnless(m, msg)
            regexp = regexps.pop(0)
            self.failUnless(re.search(regexp, m.args[1]),
                            '%r does not match %r' % (m.args[1], regexp))
        self.failIf(time.time() - started > total)

    def assertResponses(self, query, expectedResponses):
        responses = []
        started = time.time()
        while len(responses) < len(expectedResponses) and \
                  time.time() - started > len(expectedResponses)*self.timeout:
            m = self._feedMsg(query)
            self.failUnless(m, 'query %r timed out' % query)
            responses.append(m)
        self.assertEqual(len(expectedResponses), len(responses))
        for (m, expected) in zip(responses, expectedResponses):
            self.assertEqual(m.args[1], expected)

if __name__ == '__main__':
    world.testing = True
    if len(sys.argv) > 1:
        files = sys.argv[1:]
    else:
        files = glob.glob(os.path.join('test', 'test_*.py'))
    names = [os.path.splitext(os.path.basename(file))[0] for file in files]
    suite = unittest.defaultTestLoader.loadTestsFromNames(names)
    runner = unittest.TextTestRunner(verbosity=2)
    runner.run(suite)
    print 'Total asserts: %s' % unittest.asserts
    world.testing = False

# vim:set shiftwidth=4 tabstop=8 expandtab textwidth=78:
<|endoftext|>