from __future__ import unicode_literals

import json
import unittest

from mopidy.models import (
    Album, Artist, ModelJSONEncoder, Playlist, Ref, SearchResult, TlTrack,
    Track, model_json_decoder)

class GenericCopyTest(unittest.TestCase):
    def compare(self, orig, other):
        self.assertEqual(orig, other)
        self.assertNotEqual(id(orig), id(other))

    def test_copying_track(self):
        track = Track()
        self.compare(track, track.copy())

    def test_copying_artist(self):
        artist = Artist()
        self.compare(artist, artist.copy())

    def test_copying_album(self):
        album = Album()
        self.compare(album, album.copy())

    def test_copying_playlist(self):
        playlist = Playlist()
        self.compare(playlist, playlist.copy())

    def test_copying_track_with_basic_values(self):
        track = Track(name='foo', uri='bar')
        copy = track.copy(name='baz')
        self.assertEqual('baz', copy.name)
        self.assertEqual('bar', copy.uri)

    def test_copying_track_with_missing_values(self):
        track = Track(uri='bar')
        copy = track.copy(name='baz')
        self.assertEqual('baz', copy.name)
        self.assertEqual('bar', copy.uri)

    def test_copying_track_with_private_internal_value(self):
        artist1 = Artist(name='foo')
        artist2 = Artist(name='bar')
        track = Track(artists=[artist1])
        copy = track.copy(artists=[artist2])
        self.assertIn(artist2, copy.artists)

    def test_copying_track_with_invalid_key(self):
        test = lambda: Track().copy(invalid_key=True)
        self.assertRaises(TypeError, test)

    def test_copying_track_to_remove(self):
        track = Track(name='foo').copy(name=None)
        self.assertEquals(track.__dict__, Track().__dict__)

class RefTest(unittest.TestCase):
    def test_uri(self):
        uri = 'an_uri'
        ref = Ref(uri=uri)
        self.assertEqual(ref.uri, uri)
        self.assertRaises(AttributeError, setattr, ref, 'uri', None)

    def test_name(self):
        name = 'a name'
        ref = Ref(name=name)
        self.assertEqual(ref.name, name)
        self.assertRaises(AttributeError, setattr, ref, 'name', None)

    def test_invalid_kwarg(self):
        test = lambda: SearchResult(foo='baz')
        self.assertRaises(TypeError, test)

    def test_repr_without_results(self):
        self.assertEquals(
            "Ref(name=u'foo', type=u'artist', uri=u'uri')",
            repr(Ref(uri='uri', name='foo', type='artist')))

    def test_serialize_without_results(self):
        self.assertDictEqual(
            {'__model__': 'Ref', 'uri': 'uri'},
            Ref(uri='uri').serialize())

    def test_to_json_and_back(self):
        ref1 = Ref(uri='uri')
        serialized = json.dumps(ref1, cls=ModelJSONEncoder)
        ref2 = json.loads(serialized, object_hook=model_json_decoder)
        self.assertEqual(ref1, ref2)

    def test_type_constants(self):
        self.assertEqual(Ref.ALBUM, 'album')
        self.assertEqual(Ref.ARTIST, 'artist')
        self.assertEqual(Ref.DIRECTORY, 'directory')
        self.assertEqual(Ref.PLAYLIST, 'playlist')
        self.assertEqual(Ref.TRACK, 'track')

    def test_album_constructor(self):
        ref = Ref.album(uri='foo', name='bar')
        self.assertEqual(ref.uri, 'foo')
        self.assertEqual(ref.name, 'bar')
        self.assertEqual(ref.type, Ref.ALBUM)

    def test_artist_constructor(self):
        ref = Ref.artist(uri='foo', name='bar')
        self.assertEqual(ref.uri, 'foo')
        self.assertEqual(ref.name, 'bar')
        self.assertEqual(ref.type, Ref.ARTIST)

    def test_directory_constructor(self):
        ref = Ref.directory(uri='foo', name='bar')
        self.assertEqual(ref.uri, 'foo')
        self.assertEqual(ref.name, 'bar')
        self.assertEqual(ref.type, Ref.DIRECTORY)

    def test_playlist_constructor(self):
        ref = Ref.playlist(uri='foo', name='bar')
        self.assertEqual(ref.uri, 'foo')
        self.assertEqual(ref.name, 'bar')
        self.assertEqual(ref.type, Ref.PLAYLIST)

    def test_track_constructor(self):
        ref = Ref.track(uri='foo', name='bar')
        self.assertEqual(ref.uri, 'foo')
        self.assertEqual(ref.name, 'bar')
        self.assertEqual(ref.type, Ref.TRACK)

class ArtistTest(unittest.TestCase):
    def test_uri(self):
        uri = 'an_uri'
        artist = Artist(uri=uri)
        self.assertEqual(artist.uri, uri)
        self.assertRaises(AttributeError, setattr, artist, 'uri', None)

    def test_name(self):
        name = 'a name'
        artist = Artist(name=name)
        self.assertEqual(artist.name, name)
        self.assertRaises(AttributeError, setattr, artist, 'name', None)

    def test_musicbrainz_id(self):
        mb_id = 'mb-id'
        artist = Artist(musicbrainz_id=mb_id)
        self.assertEqual(artist.musicbrainz_id, mb_id)
        self.assertRaises(
            AttributeError, setattr, artist, 'musicbrainz_id', None)

    def test_invalid_kwarg(self):
        test = lambda: Artist(foo='baz')
        self.assertRaises(TypeError, test)

    def test_invalid_kwarg_with_name_matching_method(self):
        test = lambda: Artist(copy='baz')
        self.assertRaises(TypeError, test)

        test = lambda: Artist(serialize='baz')
        self.assertRaises(TypeError, test)

    def test_repr(self):
        self.assertEquals(
            "Artist(name=u'name', uri=u'uri')",
            repr(Artist(uri='uri', name='name')))

    def test_serialize(self):
        self.assertDictEqual(
            {'__model__': 'Artist', 'uri': 'uri', 'name': 'name'},
            Artist(uri='uri', name='name').serialize())

    def test_serialize_falsy_values(self):
        self.assertDictEqual(
            {'__model__': 'Artist', 'uri': '', 'name': None},
            Artist(uri='', name=None).serialize())

    def test_to_json_and_back(self):
        artist1 = Artist(uri='uri', name='name')
        serialized = json.dumps(artist1, cls=ModelJSONEncoder)
        artist2 = json.loads(serialized, object_hook=model_json_decoder)
        self.assertEqual(artist1, artist2)

    def test_to_json_and_back_with_unknown_field(self):
        artist = Artist(uri='uri', name='name').serialize()
        artist['foo'] = 'foo'
        serialized = json.dumps(artist)
        test = lambda: json.loads(serialized, object_hook=model_json_decoder)
        self.assertRaises(TypeError, test)

    def test_to_json_and_back_with_field_matching_method(self):
        artist = Artist(uri='uri', name='name').serialize()
        artist['copy'] = 'foo'
        serialized = json.dumps(artist)
        test = lambda: json.loads(serialized, object_hook=model_json_decoder)
        self.assertRaises(TypeError, test)

    def test_to_json_and_back_with_field_matching_internal_field(self):
        artist = Artist(uri='uri', name='name').serialize()
        artist['__mro__'] = 'foo'
        serialized = json.dumps(artist)
        test = lambda: json.loads(serialized, object_hook=model_json_decoder)
        self.assertRaises(TypeError, test)

    def test_eq_name(self):
        artist1 = Artist(name='name')
        artist2 = Artist(name='name')
        self.assertEqual(artist1, artist2)
        self.assertEqual(hash(artist1), hash(artist2))

    def test_eq_uri(self):
        artist1 = Artist(uri='uri')
        artist2 = Artist(uri='uri')
        self.assertEqual(artist1, artist2)
        self.assertEqual(hash(artist1), hash(artist2))

    def test_eq_musibrainz_id(self):
        artist1 = Artist(musicbrainz_id='id')
        artist2 = Artist(musicbrainz_id='id')
        self.assertEqual(artist1, artist2)
        self.assertEqual(hash(artist1), hash(artist2))

    def test_eq(self):
        artist1 = Artist(uri='uri', name='name', musicbrainz_id='id')
        artist2 = Artist(uri='uri', name='name', musicbrainz_id='id')
        self.assertEqual(artist1, artist2)
        self.assertEqual(hash(artist1), hash(artist2))

    def test_eq_none(self):
        self.assertNotEqual(Artist(), None)

    def test_eq_other(self):
        self.assertNotEqual(Artist(), 'other')

    def test_ne_name(self):
        artist1 = Artist(name='name1')
        artist2 = Artist(name='name2')
        self.assertNotEqual(artist1, artist2)
        self.assertNotEqual(hash(artist1), hash(artist2))

    def test_ne_uri(self):
        artist1 = Artist(uri='uri1')
        artist2 = Artist(uri='uri2')
        self.assertNotEqual(artist1, artist2)
        self.assertNotEqual(hash(artist1), hash(artist2))

    def test_ne_musicbrainz_id(self):
        artist1 = Artist(musicbrainz_id='id1')
        artist2 = Artist(musicbrainz_id='id2')
        self.assertNotEqual(artist1, artist2)
        self.assertNotEqual(hash(artist1), hash(artist2))

    def test_ne(self):
        artist1 = Artist(uri='uri1', name='name1', musicbrainz_id='id1')
        artist2 = Artist(uri='uri2', name='name2', musicbrainz_id='id2')
        self.assertNotEqual(artist1, artist2)
        self.assertNotEqual(hash(artist1), hash(artist2))

class AlbumTest(unittest.TestCase):
    def test_uri(self):
        uri = 'an_uri'
        album = Album(uri=uri)
        self.assertEqual(album.uri, uri)
        self.assertRaises(AttributeError, setattr, album, 'uri', None)

    def test_name(self):
        name = 'a name'
        album = Album(name=name)
        self.assertEqual(album.name, name)
        self.assertRaises(AttributeError, setattr, album, 'name', None)

    def test_artists(self):
        artist = Artist()
        album = Album(artists=[artist])
        self.assertIn(artist, album.artists)
        self.assertRaises(AttributeError, setattr, album, 'artists', None)

    def test_artists_none(self):
        self.assertEqual(set(), Album(artists=None).artists)

    def test_num_tracks(self):
        num_tracks = 11
        album = Album(num_tracks=num_tracks)
        self.assertEqual(album.num_tracks, num_tracks)
        self.assertRaises(AttributeError, setattr, album, 'num_tracks', None)

    def test_num_discs(self):
        num_discs = 2
        album = Album(num_discs=num_discs)
        self.assertEqual(album.num_discs, num_discs)
        self.assertRaises(AttributeError, setattr, album, 'num_discs', None)

    def test_date(self):
        date = '1977-01-01'
        album = Album(date=date)
        self.assertEqual(album.date, date)
        self.assertRaises(AttributeError, setattr, album, 'date', None)

    def test_musicbrainz_id(self):
        mb_id = 'mb-id'
        album = Album(musicbrainz_id=mb_id)
        self.assertEqual(album.musicbrainz_id, mb_id)
        self.assertRaises(
            AttributeError, setattr, album, 'musicbrainz_id', None)

    def test_images(self):
        image = 'data:foobar'
        album = Album(images=[image])
        self.assertIn(image, album.images)
        self.assertRaises(AttributeError, setattr, album, 'images', None)

    def test_images_none(self):
        self.assertEqual(set(), Album(images=None).images)

    def test_invalid_kwarg(self):
        test = lambda: Album(foo='baz')
        self.assertRaises(TypeError, test)

    def test_repr_without_artists(self):
        self.assertEquals(
            "Album(artists=[], images=[], name=u'name', uri=u'uri')",
            repr(Album(uri='uri', name='name')))

    def test_repr_with_artists(self):
        self.assertEquals(
            "Album(artists=[Artist(name=u'foo')], images=[], name=u'name', "
            "uri=u'uri')",
            repr(Album(uri='uri', name='name', artists=[Artist(name='foo')])))

    def test_serialize_without_artists(self):
        self.assertDictEqual(
            {'__model__': 'Album', 'uri': 'uri', 'name': 'name'},
            Album(uri='uri', name='name').serialize())

    def test_serialize_with_artists(self):
        artist = Artist(name='foo')
        self.assertDictEqual(
            {'__model__': 'Album', 'uri': 'uri', 'name': 'name',
                'artists': [artist.serialize()]},
            Album(uri='uri', name='name', artists=[artist]).serialize())

    def test_serialize_with_images(self):
        image = 'data:foobar'
        self.assertDictEqual(
            {'__model__': 'Album', 'uri': 'uri', 'name': 'name',
                'images': [image]},
            Album(uri='uri', name='name', images=[image]).serialize())

    def test_to_json_and_back(self):
        album1 = Album(uri='uri', name='name', artists=[Artist(name='foo')])
        serialized = json.dumps(album1, cls=ModelJSONEncoder)
        album2 = json.loads(serialized, object_hook=model_json_decoder)
        self.assertEqual(album1, album2)

    def test_eq_name(self):
        album1 = Album(name='name')
        album2 = Album(name='name')
        self.assertEqual(album1, album2)
        self.assertEqual(hash(album1), hash(album2))

    def test_eq_uri(self):
        album1 = Album(uri='uri')
        album2 = Album(uri='uri')
        self.assertEqual(album1, album2)
        self.assertEqual(hash(album1), hash(album2))

    def test_eq_artists(self):
        artists = [Artist()]
        album1 = Album(artists=artists)
        album2 = Album(artists=artists)
        self.assertEqual(album1, album2)
        self.assertEqual(hash(album1), hash(album2))

    def test_eq_artists_order(self):
        artist1 = Artist(name='name1')
        artist2 = Artist(name='name2')
        album1 = Album(artists=[artist1, artist2])
        album2 = Album(artists=[artist2, artist1])
        self.assertEqual(album1, album2)
        self.assertEqual(hash(album1), hash(album2))

    def test_eq_num_tracks(self):
        album1 = Album(num_tracks=2)
        album2 = Album(num_tracks=2)
        self.assertEqual(album1, album2)
        self.assertEqual(hash(album1), hash(album2))

    def test_eq_date(self):
        date = '1977-01-01'
        album1 = Album(date=date)
        album2 = Album(date=date)
        self.assertEqual(album1, album2)
        self.assertEqual(hash(album1), hash(album2))

    def test_eq_musibrainz_id(self):
        album1 = Album(musicbrainz_id='id')
        album2 = Album(musicbrainz_id='id')
        self.assertEqual(album1, album2)
        self.assertEqual(hash(album1), hash(album2))

    def test_eq(self):
        artists = [Artist()]
        album1 = Album(
            name='name', uri='uri', artists=artists, num_tracks=2,
            musicbrainz_id='id')
        album2 = Album(
            name='name', uri='uri', artists=artists, num_tracks=2,
            musicbrainz_id='id')
        self.assertEqual(album1, album2)
        self.assertEqual(hash(album1), hash(album2))

    def test_eq_none(self):
        self.assertNotEqual(Album(), None)

    def test_eq_other(self):
        self.assertNotEqual(Album(), 'other')

    def test_ne_name(self):
        album1 = Album(name='name1')
        album2 = Album(name='name2')
        self.assertNotEqual(album1, album2)
        self.assertNotEqual(hash(album1), hash(album2))

    def test_ne_uri(self):
        album1 = Album(uri='uri1')
        album2 = Album(uri='uri2')
        self.assertNotEqual(album1, album2)
        self.assertNotEqual(hash(album1), hash(album2))

    def test_ne_artists(self):
        album1 = Album(artists=[Artist(name='name1')])
        album2 = Album(artists=[Artist(name='name2')])
        self.assertNotEqual(album1, album2)
        self.assertNotEqual(hash(album1), hash(album2))

    def test_ne_num_tracks(self):
        album1 = Album(num_tracks=1)
        album2 = Album(num_tracks=2)
        self.assertNotEqual(album1, album2)
        self.assertNotEqual(hash(album1), hash(album2))

    def test_ne_date(self):
        album1 = Album(date='1977-01-01')
        album2 = Album(date='1977-01-02')
        self.assertNotEqual(album1, album2)
        self.assertNotEqual(hash(album1), hash(album2))

    def test_ne_musicbrainz_id(self):
        album1 = Album(musicbrainz_id='id1')
        album2 = Album(musicbrainz_id='id2')
        self.assertNotEqual(album1, album2)
        self.assertNotEqual(hash(album1), hash(album2))

    def test_ne(self):
        album1 = Album(
            name='name1', uri='uri1', artists=[Artist(name='name1')],
            num_tracks=1, musicbrainz_id='id1')
        album2 = Album(
            name='name2', uri='uri2', artists=[Artist(name='name2')],
            num_tracks=2, musicbrainz_id='id2')
        self.assertNotEqual(album1, album2)
        self.assertNotEqual(hash(album1), hash(album2))

class TrackTest(unittest.TestCase):
    def test_uri(self):
        uri = 'an_uri'
        track = Track(uri=uri)
        self.assertEqual(track.uri, uri)
        self.assertRaises(AttributeError, setattr, track, 'uri', None)

    def test_name(self):
        name = 'a name'
        track = Track(name=name)
        self.assertEqual(track.name, name)
        self.assertRaises(AttributeError, setattr, track, 'name', None)

    def test_artists(self):
        artists = [Artist(name='name1'), Artist(name='name2')]
        track = Track(artists=artists)
        self.assertEqual(set(track.artists), set(artists))
        self.assertRaises(AttributeError, setattr, track, 'artists', None)

    def test_artists_none(self):
        self.assertEqual(set(), Track(artists=None).artists)

    def test_composers(self):
        artists = [Artist(name='name1'), Artist(name='name2')]
        track = Track(composers=artists)
        self.assertEqual(set(track.composers), set(artists))
        self.assertRaises(AttributeError, setattr, track, 'composers', None)

    def test_composers_none(self):
        self.assertEqual(set(), Track(composers=None).composers)

    def test_performers(self):
        artists = [Artist(name='name1'), Artist(name='name2')]
        track = Track(performers=artists)
        self.assertEqual(set(track.performers), set(artists))
        self.assertRaises(AttributeError, setattr, track, 'performers', None)

    def test_performers_none(self):
        self.assertEqual(set(), Track(performers=None).performers)

    def test_album(self):
        album = Album()
        track = Track(album=album)
        self.assertEqual(track.album, album)
        self.assertRaises(AttributeError, setattr, track, 'album', None)

    def test_track_no(self):
        track_no = 7
        track = Track(track_no=track_no)
        self.assertEqual(track.track_no, track_no)
        self.assertRaises(AttributeError, setattr, track, 'track_no', None)

    def test_disc_no(self):
        disc_no = 2
        track = Track(disc_no=disc_no)
        self.assertEqual(track.disc_no, disc_no)
        self.assertRaises(AttributeError, setattr, track, 'disc_no', None)

    def test_date(self):
        date = '1977-01-01'
        track = Track(date=date)
        self.assertEqual(track.date, date)
        self.assertRaises(AttributeError, setattr, track, 'date', None)

    def test_length(self):
        length = 137000
        track = Track(length=length)
        self.assertEqual(track.length, length)
        self.assertRaises(AttributeError, setattr, track, 'length', None)

    def test_bitrate(self):
        bitrate = 160
        track = Track(bitrate=bitrate)
        self.assertEqual(track.bitrate, bitrate)
        self.assertRaises(AttributeError, setattr, track, 'bitrate', None)

    def test_musicbrainz_id(self):
        mb_id = 'mb-id'
        track = Track(musicbrainz_id=mb_id)
        self.assertEqual(track.musicbrainz_id, mb_id)
        self.assertRaises(
            AttributeError, setattr, track, 'musicbrainz_id', None)

    def test_invalid_kwarg(self):
        test = lambda: Track(foo='baz')
        self.assertRaises(TypeError, test)

    def test_repr_without_artists(self):
        self.assertEquals(
            "Track(artists=[], composers=[], name=u'name', "
            "performers=[], uri=u'uri')",
            repr(Track(uri='uri', name='name')))

    def test_repr_with_artists(self):
        self.assertEquals(
            "Track(artists=[Artist(name=u'foo')], composers=[], name=u'name', "
            "performers=[], uri=u'uri')",
            repr(Track(uri='uri', name='name', artists=[Artist(name='foo')])))

    def test_serialize_without_artists(self):
        self.assertDictEqual(
            {'__model__': 'Track', 'uri': 'uri', 'name': 'name'},
            Track(uri='uri', name='name').serialize())

    def test_serialize_with_artists(self):
        artist = Artist(name='foo')
        self.assertDictEqual(
            {'__model__': 'Track', 'uri': 'uri', 'name': 'name',
                'artists': [artist.serialize()]},
            Track(uri='uri', name='name', artists=[artist]).serialize())

    def test_serialize_with_album(self):
        album = Album(name='foo')
        self.assertDictEqual(
            {'__model__': 'Track', 'uri': 'uri', 'name': 'name',
                'album': album.serialize()},
            Track(uri='uri', name='name', album=album).serialize())

    def test_to_json_and_back(self):
        track1 = Track(
            uri='uri', name='name', album=Album(name='foo'),
            artists=[Artist(name='foo')])
        serialized = json.dumps(track1, cls=ModelJSONEncoder)
        track2 = json.loads(serialized, object_hook=model_json_decoder)
        self.assertEqual(track1, track2)

    def test_eq_uri(self):
        track1 = Track(uri='uri1')
        track2 = Track(uri='uri1')
        self.assertEqual(track1, track2)
        self.assertEqual(hash(track1), hash(track2))

    def test_eq_name(self):
        track1 = Track(name='name1')
        track2 = Track(name='name1')
        self.assertEqual(track1, track2)
        self.assertEqual(hash(track1), hash(track2))

    def test_eq_artists(self):
        artists = [Artist()]
        track1 = Track(artists=artists)
        track2 = Track(artists=artists)
        self.assertEqual(track1, track2)
        self.assertEqual(hash(track1), hash(track2))

    def test_eq_artists_order(self):
        artist1 = Artist(name='name1')
        artist2 = Artist(name='name2')
        track1 = Track(artists=[artist1, artist2])
        track2 = Track(artists=[artist2, artist1])
        self.assertEqual(track1, track2)
        self.assertEqual(hash(track1), hash(track2))

    def test_eq_album(self):
        album = Album()
        track1 = Track(album=album)
        track2 = Track(album=album)
        self.assertEqual(track1, track2)
        self.assertEqual(hash(track1), hash(track2))

    def test_eq_track_no(self):
        track1 = Track(track_no=1)
        track2 = Track(track_no=1)
        self.assertEqual(track1, track2)
        self.assertEqual(hash(track1), hash(track2))

    def test_eq_date(self):
        date = '1977-01-01'
        track1 = Track(date=date)
        track2 = Track(date=date)
        self.assertEqual(track1, track2)
        self.assertEqual(hash(track1), hash(track2))

    def test_eq_length(self):
        track1 = Track(length=100)
        track2 = Track(length=100)
        self.assertEqual(track1, track2)
        self.assertEqual(hash(track1), hash(track2))

    def test_eq_bitrate(self):
        track1 = Track(bitrate=100)
        track2 = Track(bitrate=100)
        self.assertEqual(track1, track2)
        self.assertEqual(hash(track1), hash(track2))

    def test_eq_musibrainz_id(self):
        track1 = Track(musicbrainz_id='id')
        track2 = Track(musicbrainz_id='id')
        self.assertEqual(track1, track2)
        self.assertEqual(hash(track1), hash(track2))

    def test_eq(self):
        date = '1977-01-01'
        artists = [Artist()]
        album = Album()
        track1 = Track(
            uri='uri', name='name', artists=artists, album=album, track_no=1,
            date=date, length=100, bitrate=100, musicbrainz_id='id')
        track2 = Track(
            uri='uri', name='name', artists=artists, album=album, track_no=1,
            date=date, length=100, bitrate=100, musicbrainz_id='id')
        self.assertEqual(track1, track2)
        self.assertEqual(hash(track1), hash(track2))

    def test_eq_none(self):
        self.assertNotEqual(Track(), None)

    def test_eq_other(self):
        self.assertNotEqual(Track(), 'other')

    def test_ne_uri(self):
        track1 = Track(uri='uri1')
        track2 = Track(uri='uri2')
        self.assertNotEqual(track1, track2)
        self.assertNotEqual(hash(track1), hash(track2))

    def test_ne_name(self):
        track1 = Track(name='name1')
        track2 = Track(name='name2')
        self.assertNotEqual(track1, track2)
        self.assertNotEqual(hash(track1), hash(track2))

    def test_ne_artists(self):
        track1 = Track(artists=[Artist(name='name1')])
        track2 = Track(artists=[Artist(name='name2')])
        self.assertNotEqual(track1, track2)
        self.assertNotEqual(hash(track1), hash(track2))

    def test_ne_album(self):
        track1 = Track(album=Album(name='name1'))
        track2 = Track(album=Album(name='name2'))
        self.assertNotEqual(track1, track2)
        self.assertNotEqual(hash(track1), hash(track2))

    def test_ne_track_no(self):
        track1 = Track(track_no=1)
        track2 = Track(track_no=2)
        self.assertNotEqual(track1, track2)
        self.assertNotEqual(hash(track1), hash(track2))

    def test_ne_date(self):
        track1 = Track(date='1977-01-01')
        track2 = Track(date='1977-01-02')
        self.assertNotEqual(track1, track2)
        self.assertNotEqual(hash(track1), hash(track2))

    def test_ne_length(self):
        track1 = Track(length=100)
        track2 = Track(length=200)
        self.assertNotEqual(track1, track2)
        self.assertNotEqual(hash(track1), hash(track2))

    def test_ne_bitrate(self):
        track1 = Track(bitrate=100)
        track2 = Track(bitrate=200)
        self.assertNotEqual(track1, track2)
        self.assertNotEqual(hash(track1), hash(track2))

    def test_ne_musicbrainz_id(self):
        track1 = Track(musicbrainz_id='id1')
        track2 = Track(musicbrainz_id='id2')
        self.assertNotEqual(track1, track2)
        self.assertNotEqual(hash(track1), hash(track2))

    def test_ne(self):
        track1 = Track(
            uri='uri1', name='name1', artists=[Artist(name='name1')],
            album=Album(name='name1'), track_no=1, date='1977-01-01',
            length=100, bitrate=100, musicbrainz_id='id1')
        track2 = Track(
            uri='uri2', name='name2', artists=[Artist(name='name2')],
            album=Album(name='name2'), track_no=2, date='1977-01-02',
            length=200, bitrate=200, musicbrainz_id='id2')
        self.assertNotEqual(track1, track2)
        self.assertNotEqual(hash(track1), hash(track2))

class TlTrackTest(unittest.TestCase):
    def test_tlid(self):
        tlid = 123
        tl_track = TlTrack(tlid=tlid)
        self.assertEqual(tl_track.tlid, tlid)
        self.assertRaises(AttributeError, setattr, tl_track, 'tlid', None)

    def test_track(self):
        track = Track()
        tl_track = TlTrack(track=track)
        self.assertEqual(tl_track.track, track)
        self.assertRaises(AttributeError, setattr, tl_track, 'track', None)

    def test_invalid_kwarg(self):
        test = lambda: TlTrack(foo='baz')
        self.assertRaises(TypeError, test)

    def test_positional_args(self):
        tlid = 123
        track = Track()
        tl_track = TlTrack(tlid, track)
        self.assertEqual(tl_track.tlid, tlid)
        self.assertEqual(tl_track.track, track)

    def test_iteration(self):
        tlid = 123
        track = Track()
        tl_track = TlTrack(tlid, track)
        (tlid2, track2) = tl_track
        self.assertEqual(tlid2, tlid)
        self.assertEqual(track2, track)

    def test_repr(self):
        self.assertEquals(
            "TlTrack(tlid=123, track=Track(artists=[], composers=[], "
            "performers=[], uri=u'uri'))",
            repr(TlTrack(tlid=123, track=Track(uri='uri'))))

    def test_serialize(self):
        track = Track(uri='uri', name='name')
        self.assertDictEqual(
            {'__model__': 'TlTrack', 'tlid': 123, 'track': track.serialize()},
            TlTrack(tlid=123, track=track).serialize())

    def test_to_json_and_back(self):
        tl_track1 = TlTrack(tlid=123, track=Track(uri='uri', name='name'))
        serialized = json.dumps(tl_track1, cls=ModelJSONEncoder)
        tl_track2 = json.loads(serialized, object_hook=model_json_decoder)
        self.assertEqual(tl_track1, tl_track2)

    def test_eq(self):
        tlid = 123
        track = Track()
        tl_track1 = TlTrack(tlid=tlid, track=track)
        tl_track2 = TlTrack(tlid=tlid, track=track)
        self.assertEqual(tl_track1, tl_track2)
        self.assertEqual(hash(tl_track1), hash(tl_track2))

    def test_eq_none(self):
        self.assertNotEqual(TlTrack(), None)

    def test_eq_other(self):
        self.assertNotEqual(TlTrack(), 'other')

    def test_ne_tlid(self):
        tl_track1 = TlTrack(tlid=123)
        tl_track2 = TlTrack(tlid=321)
        self.assertNotEqual(tl_track1, tl_track2)
        self.assertNotEqual(hash(tl_track1), hash(tl_track2))

    def test_ne_track(self):
        tl_track1 = TlTrack(track=Track(uri='a'))
        tl_track2 = TlTrack(track=Track(uri='b'))
        self.assertNotEqual(tl_track1, tl_track2)
        self.assertNotEqual(hash(tl_track1), hash(tl_track2))

class PlaylistTest(unittest.TestCase):
    def test_uri(self):
        uri = 'an_uri'
        playlist = Playlist(uri=uri)
        self.assertEqual(playlist.uri, uri)
        self.assertRaises(AttributeError, setattr, playlist, 'uri', None)

    def test_name(self):
        name = 'a name'
        playlist = Playlist(name=name)
        self.assertEqual(playlist.name, name)
        self.assertRaises(AttributeError, setattr, playlist, 'name', None)

    def test_tracks(self):
        tracks = [Track(), Track(), Track()]
        playlist = Playlist(tracks=tracks)
        self.assertEqual(list(playlist.tracks), tracks)
        self.assertRaises(AttributeError, setattr, playlist, 'tracks', None)

    def test_length(self):
        tracks = [Track(), Track(), Track()]
        playlist = Playlist(tracks=tracks)
        self.assertEqual(playlist.length, 3)

    def test_last_modified(self):
        last_modified = 1390942873000
        playlist = Playlist(last_modified=last_modified)
        self.assertEqual(playlist.last_modified, last_modified)
        self.assertRaises(
            AttributeError, setattr, playlist, 'last_modified', None)

    def test_with_new_uri(self):
        tracks = [Track()]
        last_modified = 1390942873000
        playlist = Playlist(
            uri='an uri', name='a name', tracks=tracks,
            last_modified=last_modified)
        new_playlist = playlist.copy(uri='another uri')
        self.assertEqual(new_playlist.uri, 'another uri')
        self.assertEqual(new_playlist.name, 'a name')
        self.assertEqual(list(new_playlist.tracks), tracks)
        self.assertEqual(new_playlist.last_modified, last_modified)

    def test_with_new_name(self):
        tracks = [Track()]
        last_modified = 1390942873000
        playlist = Playlist(
            uri='an uri', name='a name', tracks=tracks,
            last_modified=last_modified)
        new_playlist = playlist.copy(name='another name')
        self.assertEqual(new_playlist.uri, 'an uri')
        self.assertEqual(new_playlist.name, 'another name')
        self.assertEqual(list(new_playlist.tracks), tracks)
        self.assertEqual(new_playlist.last_modified, last_modified)

    def test_with_new_tracks(self):
        tracks = [Track()]
        last_modified = 1390942873000
        playlist = Playlist(
            uri='an uri', name='a name', tracks=tracks,
            last_modified=last_modified)
        new_tracks = [Track(), Track()]
        new_playlist = playlist.copy(tracks=new_tracks)
        self.assertEqual(new_playlist.uri, 'an uri')
        self.assertEqual(new_playlist.name, 'a name')
        self.assertEqual(list(new_playlist.tracks), new_tracks)
        self.assertEqual(new_playlist.last_modified, last_modified)

    def test_with_new_last_modified(self):
        tracks = [Track()]
        last_modified = 1390942873000
        new_last_modified = last_modified + 1000
        playlist = Playlist(
            uri='an uri', name='a name', tracks=tracks,
            last_modified=last_modified)
        new_playlist = playlist.copy(last_modified=new_last_modified)
        self.assertEqual(new_playlist.uri, 'an uri')
        self.assertEqual(new_playlist.name, 'a name')
        self.assertEqual(list(new_playlist.tracks), tracks)
        self.assertEqual(new_playlist.last_modified, new_last_modified)

    def test_invalid_kwarg(self):
        test = lambda: Playlist(foo='baz')
        self.assertRaises(TypeError, test)

    def test_repr_without_tracks(self):
        self.assertEquals(
            "Playlist(name=u'name', tracks=[], uri=u'uri')",
            repr(Playlist(uri='uri', name='name')))

    def test_repr_with_tracks(self):
        self.assertEquals(
            "Playlist(name=u'name', tracks=[Track(artists=[], composers=[], "
            "name=u'foo', performers=[])], uri=u'uri')",
            repr(Playlist(uri='uri', name='name', tracks=[Track(name='foo')])))

    def test_serialize_without_tracks(self):
        self.assertDictEqual(
            {'__model__': 'Playlist', 'uri': 'uri', 'name': 'name'},
            Playlist(uri='uri', name='name').serialize())

    def test_serialize_with_tracks(self):
        track = Track(name='foo')
        self.assertDictEqual(
            {'__model__': 'Playlist', 'uri': 'uri', 'name': 'name',
                'tracks': [track.serialize()]},
            Playlist(uri='uri', name='name', tracks=[track]).serialize())

    def test_to_json_and_back(self):
        playlist1 = Playlist(uri='uri', name='name')
        serialized = json.dumps(playlist1, cls=ModelJSONEncoder)
        playlist2 = json.loads(serialized, object_hook=model_json_decoder)
        self.assertEqual(playlist1, playlist2)

    def test_eq_name(self):
        playlist1 = Playlist(name='name')
        playlist2 = Playlist(name='name')
        self.assertEqual(playlist1, playlist2)
        self.assertEqual(hash(playlist1), hash(playlist2))

    def test_eq_uri(self):
        playlist1 = Playlist(uri='uri')
        playlist2 = Playlist(uri='uri')
        self.assertEqual(playlist1, playlist2)
        self.assertEqual(hash(playlist1), hash(playlist2))

    def test_eq_tracks(self):
        tracks = [Track()]
        playlist1 = Playlist(tracks=tracks)
        playlist2 = Playlist(tracks=tracks)
        self.assertEqual(playlist1, playlist2)
        self.assertEqual(hash(playlist1), hash(playlist2))

    def test_eq_last_modified(self):
        playlist1 = Playlist(last_modified=1)
        playlist2 = Playlist(last_modified=1)
        self.assertEqual(playlist1, playlist2)
        self.assertEqual(hash(playlist1), hash(playlist2))

    def test_eq(self):
        tracks = [Track()]
        playlist1 = Playlist(
            uri='uri', name='name', tracks=tracks, last_modified=1)
        playlist2 = Playlist(
            uri='uri', name='name', tracks=tracks, last_modified=1)
        self.assertEqual(playlist1, playlist2)
        self.assertEqual(hash(playlist1), hash(playlist2))

    def test_eq_none(self):
        self.assertNotEqual(Playlist(), None)

    def test_eq_other(self):
        self.assertNotEqual(Playlist(), 'other')

    def test_ne_name(self):
        playlist1 = Playlist(name='name1')
        playlist2 = Playlist(name='name2')
        self.assertNotEqual(playlist1, playlist2)
        self.assertNotEqual(hash(playlist1), hash(playlist2))

    def test_ne_uri(self):
        playlist1 = Playlist(uri='uri1')
        playlist2 = Playlist(uri='uri2')
        self.assertNotEqual(playlist1, playlist2)
        self.assertNotEqual(hash(playlist1), hash(playlist2))

    def test_ne_tracks(self):
        playlist1 = Playlist(tracks=[Track(uri='uri1')])
        playlist2 = Playlist(tracks=[Track(uri='uri2')])
        self.assertNotEqual(playlist1, playlist2)
        self.assertNotEqual(hash(playlist1), hash(playlist2))

    def test_ne_last_modified(self):
        playlist1 = Playlist(last_modified=1)
        playlist2 = Playlist(last_modified=2)
        self.assertNotEqual(playlist1, playlist2)
        self.assertNotEqual(hash(playlist1), hash(playlist2))

    def test_ne(self):
        playlist1 = Playlist(
            uri='uri1', name='name1', tracks=[Track(uri='uri1')],
            last_modified=1)
        playlist2 = Playlist(
            uri='uri2', name='name2', tracks=[Track(uri='uri2')],
            last_modified=2)
        self.assertNotEqual(playlist1, playlist2)
        self.assertNotEqual(hash(playlist1), hash(playlist2))

class SearchResultTest(unittest.TestCase):
    def test_uri(self):
        uri = 'an_uri'
        result = SearchResult(uri=uri)
        self.assertEqual(result.uri, uri)
        self.assertRaises(AttributeError, setattr, result, 'uri', None)

    def test_tracks(self):
        tracks = [Track(), Track(), Track()]
        result = SearchResult(tracks=tracks)
        self.assertEqual(list(result.tracks), tracks)
        self.assertRaises(AttributeError, setattr, result, 'tracks', None)

    def test_artists(self):
        artists = [Artist(), Artist(), Artist()]
        result = SearchResult(artists=artists)
        self.assertEqual(list(result.artists), artists)
        self.assertRaises(AttributeError, setattr, result, 'artists', None)

    def test_albums(self):
        albums = [Album(), Album(), Album()]
        result = SearchResult(albums=albums)
        self.assertEqual(list(result.albums), albums)
        self.assertRaises(AttributeError, setattr, result, 'albums', None)

    def test_invalid_kwarg(self):
        test = lambda: SearchResult(foo='baz')
        self.assertRaises(TypeError, test)

    def test_repr_without_results(self):
        self.assertEquals(
            "SearchResult(albums=[], artists=[], tracks=[], uri=u'uri')",
            repr(SearchResult(uri='uri')))

    def test_serialize_without_results(self):
        self.assertDictEqual(
            {'__model__': 'SearchResult', 'uri': 'uri'},
            SearchResult(uri='uri').serialize())

    def test_to_json_and_back(self):
        result1 = SearchResult(uri='uri')
        serialized = json.dumps(result1, cls=ModelJSONEncoder)
        result2 = json.loads(serialized, object_hook=model_json_decoder)
        self.assertEqual(result1, result2)


## Author: Nguyen Tran
## Python version: 2.7

'''
Execute smtp-sauce commands just like smtp-source, but with more options
'''

# Python libraries
import os
import sys
import smtplib
from socket import *

# Modules
from options import display_options
from options import ipv_
from options import windowsize
import send_mail

USAGE = 'Usage: smtp-sauce -4 -6 -a file -A -c -C count -d -f from -F headerfile -l length -log -L -m msgcount -M myhostname -N -o -r recipientcount -R mintime maxtime -ra folder -rl minlength maxlength -s sessioncount -S subject -t to -tm -T windowsize -v -w interval host[:port]'

## Execute the command
## Params:	params - (array) a list of command's options
def smtp_sauce(params):

	# Options dictionary
	INITIAL = {'default_body': 'Text goes here.',
			'logfile': '',
			'-4' : False,
			'-6' : False,
			'-a' : '',
			'-A' : False,
			'-c' : False,
			'-C' : 0,
			'-d' : False,
			'-f' : 'foo',
			'-F' : '',
			'-l' : 0,
			'-log': False,
			'-L' : False,
			'-o' : False,
			'-ra': '',
			'-rl': [0, 0],
			'-R' : [0, 0],
			'-m' : 1,
			'-M' : '',
			'-N' : False,
			'-r' : 1,
			'-s' : 1,
			'-S' : '',
			'-t' : ['foo'],
			'-T' : 0,
			'-tm': False,
			'-v' : 0,
			'-w' : 0}

	DEFAULT = INITIAL	#Initialize default values
	COUNT = 0
	LOGFILE = "smtp.log"

	# Create 'from' address from the host
	hostname = gethostname()
	DEFAULT['-f'] = '%s@%s' % (DEFAULT['-f'], hostname)
	DEFAULT['-t'][0] = '%s@%s' % (DEFAULT['-t'][0], hostname)

	host, port = read_command(params, DEFAULT)
	old_val, syschange = windowsize.change_default(DEFAULT['-T'])	# Change TCP windowsize
	if DEFAULT['-log']:
		logpath = os.path.join(os.getcwd(), LOGFILE)
		DEFAULT['logfile'] = open(logpath, 'w')
	# Create and send mails
	if DEFAULT['-s'] > 1:
		COUNT, time_elapse = send_mail._parallel(DEFAULT, host, port)
	else:
		COUNT, time_elapse = send_mail._series(DEFAULT, host, port)

	windowsize.restore_default(DEFAULT['-T'], old_val, syschange)	# Restore TCP windowsize

	# Print counter and timer
	if (DEFAULT['-c']):
		os.system('echo %s' % COUNT)
	display_options.display_time(DEFAULT['-tm'], time_elapse)
	if DEFAULT['-log']:
		DEFAULT['logfile'].close()
	return 0

## Analyze the command, assign the values to DEFAULT after reading it
## Params:	params - (array) a list of options
##			DEFAULT - (dictionary) a dictionary of input options
## Return:	a full email message
def read_command(params, DEFAULT):
	if len(params) == 1:
		raise Exception('ERROR: %s' % USAGE )

	try:
		for i in range(1, len(params)):
			if params[i] == '-4':
				DEFAULT['-4'] = True

			elif params[i] == '-6':
				DEFAULT['-6'] = True

			elif params[i] == '-a':
				DEFAULT['-a'] = params[i+1]

			elif params[i] == '-A':
				DEFAULT['-A'] = True

			elif params[i] == '-c':
				DEFAULT['-c'] = True

			elif params[i] == '-C':
				DEFAULT['-C'] = int(params[i+1])

			elif params[i] == '-d':
				DEFAULT['-d'] = True

			elif params[i] == '-f':
				DEFAULT['-f'] = params[i+1]

			elif params[i] == '-F':
				DEFAULT['-F'] = params[i+1]

			elif params[i] == '-l':
				DEFAULT['-l'] = int(params[i+1])

			elif params[i] == '-log':
				DEFAULT['-log'] = True

			elif params[i] == '-L':
				DEFAULT['-L'] = True

			elif params[i] == '-m':
				DEFAULT['-m'] = int(params[i+1])

			elif params[i] == '-M':
				DEFAULT['-M'] = params[i+1]

			elif params[i] == '-N':
				DEFAULT['-N'] = True

			elif params[i] == '-o':
				DEFAULT['-o'] = True

			elif params[i] == '-r':
				DEFAULT['-r'] = int(params[i+1])

			elif params[i] == '-ra':
				DEFAULT['-ra'] = params[i+1]

			elif params[i] == '-rl':
				DEFAULT['-rl'][0] = int(params[i+1])
				DEFAULT['-rl'][1] = int(params[i+2])

			elif params[i] == '-R':
				DEFAULT['-R'][0] = int(params[i+1])
				DEFAULT['-R'][1] = int(params[i+2])

			elif params[i] == '-s':
				DEFAULT['-s'] = int(params[i+1])

			elif params[i] == '-S':
				DEFAULT['-S'] = params[i+1]

			elif params[i] == '-t':
				DEFAULT['-t'] = [params[i+1]]

			elif params[i] == '-T':
				DEFAULT['-T'] = params[i+1]

			elif params[i] == '-tm':
				DEFAULT['-tm'] = True

			elif params[i] == '-v':
				DEFAULT['-v'] = 1

			elif params[i] == '-w':
				DEFAULT['-w'] = int(params[i+1])

		# Check for valid host
		try:
			host, port = params[len(params) - 1].strip().split(':')
		except:
			host = params[len(params) -1]
			port = ''

		try:
			host, port = ipv_.connect_ip(DEFAULT['-4'], DEFAULT['-6'], host, port)
		except Exception as exc:
			raise ('FATAL: %s' % exc)

	except:
		raise Exception('ERROR: %s' % USAGE )

	return host, port


import io
import zipfile
from pathlib import Path

from django.http import FileResponse, HttpResponse, JsonResponse
from django.views.decorators.clickjacking import xframe_options_sameorigin
from django_analyses.filters.input.input import InputFilter
from django_analyses.models.input.input import Input
from django_analyses.models.input.types import FileInput, ListInput
from django_analyses.serializers.input.input import InputSerializer
from django_analyses.views.defaults import DefaultsMixin
from django_analyses.views.pagination import StandardResultsSetPagination
from django_analyses.views.utils import CONTENT_DISPOSITION, ZIP_CONTENT_TYPE
from rest_framework import viewsets
from rest_framework.decorators import action
from rest_framework.request import Request
from rest_framework.response import Response

class InputViewSet(DefaultsMixin, viewsets.ModelViewSet):
    filter_class = InputFilter
    pagination_class = StandardResultsSetPagination
    serializer_class = InputSerializer

    def get_queryset(self):
        return Input.objects.select_subclasses()

    @action(detail=True, methods=["GET"])
    def html_repr(
        self, request: Request, input_id: int = None, index: int = None
    ) -> Response:
        instance = Input.objects.get_subclass(id=input_id)
        content = "No preview available :("
        html_repr = False
        has_repr = hasattr(instance, "_repr_html_")
        has_getter = hasattr(instance, "get_html_repr")
        if index is None and has_repr:
            html_repr = instance._repr_html_()
        elif index is not None and has_getter:
            html_repr = instance.get_html_repr(index)
        content = html_repr if html_repr else content
        return JsonResponse({"content": content})

    @action(detail=True, methods=["GET"])
    @xframe_options_sameorigin
    def download(self, request: Request, pk: int = None) -> Response:
        instance = Input.objects.get_subclass(id=pk)
        is_file_list = (
            isinstance(instance, ListInput)
            and instance.definition.element_type == "FIL"
        )
        if isinstance(instance, FileInput):
            file_object = open(instance.value, "rb")
            return FileResponse(file_object, as_attachment=True)
        elif is_file_list:
            buffer = io.BytesIO()
            with zipfile.ZipFile(buffer, "w") as zip_file:
                for path in instance.value:
                    zip_file.write(path, Path(path).name)
            response = HttpResponse(
                buffer.getvalue(), content_type=ZIP_CONTENT_TYPE
            )
            content_disposition = CONTENT_DISPOSITION.format(
                name=instance.definition.key
            )
            response["Content-Disposition"] = content_disposition
            return response


from typing import Callable
from flask.testing import FlaskClient
from tests import utils

def test_get_all_user(forge_client: Callable[[str], FlaskClient]):
    count = 10
    # Add some users
    for _ in range(count):
        u = utils.user.Factory.student()
    client = forge_client(u.username)
    rv = client.get('/user')
    rv_json = rv.json
    assert rv.status_code == 200, rv_json
    assert len(rv_json['data']) == count


import json
import os
import pickle
from pathlib import Path

from selenium.common.exceptions import NoAlertPresentException
from selenium.webdriver.chrome import webdriver

from utilities.logger.test_logger.test_step import logger

def should_ignore_cookie(cookie: dict, ignores_keys_values: dict) -> bool:
    for key in ignores_keys_values.keys():
        if cookie[key] == ignores_keys_values[key]:
            return True
    return False

class DriverUtils:

    def __init__(self, driver: webdriver.WebDriver):
        self.driver = driver
        self.rootDir = str(Path(__file__).parent.parent)
        self.cookies_file = self.rootDir + "/credentials/cookies.pkl"

    def save_cookie_to_file(self):
        if os.path.exists(self.cookies_file) is False:
            pickle.dump(self.driver.get_cookies(), open(self.cookies_file, "wb"))

    def add_cookie_from_file(self, ignore_cookies_by_key_value: dict, delete_after_add: bool = False):
        if os.path.exists(self.cookies_file):
            for cookie in pickle.load(open(self.cookies_file, "rb")):
                if should_ignore_cookie(cookie, ignore_cookies_by_key_value) is False:
                    self.driver.add_cookie(cookie)
            if delete_after_add:
                os.remove(self.cookies_file)
        else:
            raise FileNotFoundError

    def add_cookie(self, cookies, ignore_cookies_by_key_value: dict):
        for cookie in cookies:
            if should_ignore_cookie(cookie, ignore_cookies_by_key_value) is False:
                self.driver.add_cookie(cookie)

    def get_cookie_value(self, cookie_name: str):
        try:
            return self.driver.get_cookie(cookie_name)["value"]
        except TypeError:
            return None

    def get_browser_events(self):
        def process_browser_log_entry(entry):
            response = json.loads(entry['message'])['message']
            return response

        if self.driver.name == "chrome":
            browser_log = self.driver.get_log('performance')
            events = [process_browser_log_entry(entry) for entry in browser_log]
            return [event for event in events if 'Network.response' in event['method']]
        else:
            raise Exception("Unable to get events cause driver type is not chromedriver")

    def dismiss_if_alert_is_present(self):
        try:
            self.driver.switch_to.alert.dismiss()
        except NoAlertPresentException:
            pass

    def get_console_logs(self) -> list:
        return self.driver.get_log('browser')

    @staticmethod
    def __parse_log(log: dict):
        level = log.get("level")
        message = log.get("message")
        source = log.get("source")
        return f"\n----------\nLEVEL: {level}\nMESSAGE: {message}\nSOURCE: {source}\n----------"

    def is_any_severe_console_log_occurred(self) -> bool:
        log: dict
        for log in self.get_console_logs():
            if log.get("level") == "SEVERE":
                logger.error(self.__parse_log(log))
                return True
        return False

    def is_severe_console_log_occurred(self, *logs_sources) -> bool:
        log: dict
        for log in self.get_console_logs():
            if log.get("level") == "SEVERE" and log.get("source") in logs_sources:
                logger.error(self.__parse_log(log))
                return True
        return False


import numpy as np
from tqdm import tqdm
import torch
import torch.nn as nn
from torch.nn import functional as F

class fair_classifier(torch.nn.Module):
    def __init__(self, config):
        super(fair_classifier, self).__init__()
        self.embedding_dim = config.embedding_dim * 4
        self.fc2_in_dim = config.first_fc_hidden_dim
        self.fc2_out_dim = config.num_gender

        self.fc1 = nn.Linear(self.fc2_in_dim // 2, self.fc2_in_dim // 2)
        self.fc2 = nn.Linear(self.fc2_in_dim // 2, self.fc2_out_dim)
        self.final_part = nn.Sequential(self.fc1, nn.ReLU(), self.fc2)
        self.loss = nn.CrossEntropyLoss()

    def forward(self, x, user_emb, training=True):
        gender_idx = x[:, 0]
        age_idx = x[:, 1]
        occupation_idx = x[:, 2]
        area_idx = x[:, 3]

        x = self.final_part(user_emb)
        loss = self.loss(x, gender_idx)

        return F.softmax(x, dim=1), gender_idx, loss

def get_user_embedding_adv(args, model, dataloader, user_index):
    user_embedding = np.zeros((len(user_index), args.first_fc_hidden_dim // 2))
    if args.train_adv:
        adv_now = model.task_adv[0]
        print(adv_now)
    else:
        adv_now = args.adv
    # only for inner_fc 1
    for weight in model.global_part.parameters():
        weight.fast = None
    for c, batch in tqdm(enumerate(dataloader)):
        x_spt = batch[0].cuda()  # Batch_size(1) x 交互物品个数 x features
        y_spt = batch[1].cuda()
        x_qry = batch[2].cuda()
        y_qry = batch[3].cuda()
        user_id = batch[4][0]
        index = int(np.argwhere(user_index == user_id))
        for i in range(x_spt.shape[0]):
            gender = x_qry[i].detach().cpu().numpy()[0, 21]
            if args.re_w:
                if args.dual:
                    if gender == 0:
                        adv = adv_now[0]
                    elif gender == 1:
                        adv = adv_now[1]
                else:
                    adv = adv_now
            else:
                if args.dual:
                    if gender == 0:
                        adv = adv_now[0]
                    elif gender == 1:
                        adv = adv_now[1]
                else:
                    adv = adv_now
            # -------------- inner update --------------
            fast_parameters = model.local_part.parameters()
            for weight in model.local_part.parameters():
                weight.fast = None
            # local max update
            fast_parameters_max = model.local_max_part.parameters()
            for weight in model.local_max_part.parameters():
                weight.fast = None
            for k in range(args.num_grad_steps_inner):
                output = model(x_spt[i], y_spt[i], [x_spt[i]], [y_spt[i]])
                logits, adv_loss = output[0], output[1]
                # local max update
                if args.loss == 1:
                    if args.disable_inner_max:
                        loss_max = F.cross_entropy(
                            logits, torch.unsqueeze(y_spt[i]).long() - 1
                        )
                    else:
                        loss_max = (
                            F.cross_entropy(
                                logits, torch.unsqueeze(y_spt[i]).long() - 1
                            )
                            - adv
                            * adv_loss**args.adv_loss_power
                            / args.adv_loss_power
                        )
                else:
                    if args.disable_inner_max:
                        loss_max = F.mse_loss(logits, y_spt[i])
                    else:
                        loss_max = (
                            F.mse_loss(logits, y_spt[i])
                            - adv
                            * adv_loss**args.adv_loss_power
                            / args.adv_loss_power
                        )
                grad_max = torch.autograd.grad(
                    loss_max, fast_parameters_max, create_graph=True
                )
                fast_parameters_max = []
                for k, weight in enumerate(model.local_max_part.parameters()):
                    if weight.fast is None:
                        weight.fast = (
                            weight - args.lr_inner * grad_max[k]
                        )  # create weight.fast
                    else:
                        weight.fast = weight.fast - args.lr_inner * grad_max[k]
                    fast_parameters_max.append(weight.fast)
            gender_idx = x_spt[0][:, 21]
            age_idx = x_spt[0][:, 20]
            occupation_idx = x_spt[0][:, 22]
            area_idx = x_spt[0][:, 23]
            # number of interactions x dim
            user_emb = (
                F.relu(
                    model.fc_user(
                        model.user_emb(gender_idx, age_idx, occupation_idx, area_idx)
                    )
                )
                .detach()
                .cpu()
                .numpy()
            )
            user_embedding[index] = user_emb[0, :]
    return user_embedding

def get_user_embedding(args, model, dataloader, user_index):
    user_embedding = np.zeros((len(user_index), args.first_fc_hidden_dim // 2))
    for c, batch in tqdm(enumerate(dataloader)):
        x_spt = batch[0].cuda()  # Batch_size(1) x 交互物品个数 x features
        y_spt = batch[1].cuda()
        x_qry = batch[2].cuda()
        y_qry = batch[3].cuda()
        user_id = batch[4][0]
        index = int(np.argwhere(user_index == user_id))
        for i in range(x_spt.shape[0]):
            # -------------- inner update --------------
            fast_parameters = model.final_part.parameters()
            for weight in model.final_part.parameters():
                weight.fast = None
            for k in range(args.num_grad_steps_inner):
                # if args.adv:
                #     logits, adv_loss = model(x_spt[i])
                # else:
                output = model(x_spt[i], y_spt[i], [x_spt[i]], [y_spt[i]])
                logits = output[0]
                if args.loss == 1:
                    loss = F.cross_entropy(logits, torch.unsqueeze(y_spt[i]).long() - 1)
                else:
                    loss = F.mse_loss(logits, y_spt[i])
                grad = torch.autograd.grad(loss, fast_parameters, create_graph=True)
                fast_parameters = []
                for k, weight in enumerate(model.final_part.parameters()):
                    if weight.fast is None:
                        weight.fast = (
                            weight - args.lr_inner * grad[k]
                        )  # create weight.fast
                    else:
                        weight.fast = weight.fast - args.lr_inner * grad[k]
                    fast_parameters.append(weight.fast)
            gender_idx = x_spt[0][:, 21]
            age_idx = x_spt[0][:, 20]
            occupation_idx = x_spt[0][:, 22]
            area_idx = x_spt[0][:, 23]
            # number of interactions x dim
            user_emb = (
                F.relu(
                    model.fc_user(
                        model.user_emb(gender_idx, age_idx, occupation_idx, area_idx)
                    )
                )
                .detach()
                .cpu()
                .numpy()
            )
            user_embedding[index] = user_emb[0, :]
    return user_embedding


import random
from tournament_game import TournamentGame
from button import Button
import sys

sys.path.insert(0, '../game_platform')
from player import Player, Human, Computer

class Tournament:
	"""
	Tournament encapsulates a number of players and handles the tournament mode of the game.
	"""
	def __init__(self, ui, players):
		"""
		Construct a new Tournament object.
		:param self: A reference to the Tournament object itself
		:param ui: A reference to the GameUI object
		:param players: a list containing names of players in the tournament
		:return: returns nothing
		"""
		self.currentGame = 0
		self.ui = ui
		self.players = []
		self.ontothenext = []
		self.matches = []
		if len(players) > 4:
			self.maxrows = 4
		else:
			self.maxrows = 2
		# Check names are not blank
		for n in range(len(players)):
			if len(players[n]) > 0:
				self.players.append(Human(players[n]))
		c = 1
		while 1:
			if len(self.players) % 4 == 0:
				break
			level = 0
			while(level not in [1,2,3]):
				try:
					level = int(self.ui.askfornames.ask("AI level: (1, 2, 3)"))
				except ValueError:
					pass
			if level == 1:
				l = "easy"
			elif level == 2:
				l = "normal"
			else:
				l = "hard"
			self.players.append(Computer("Computer " + str(c), l))
			c = c + 1
		random.shuffle(self.players)
		self.makeMatches()
	def debug(self):
		"""
		Prints out variables belonging to the Tournament object.
		:param self: A reference to the Tournament object itself
		:return: returns nothing
		"""
		print(self.players)
		print(self.matches)
		print(self.ontothenext)
	def getMatches(self):
		"""
		Returns the number of matches belonging to the Tournament object.
		:param self: A reference to the Tournament object itself
		:return: returns the matches belonging to the Tournament object
		"""
		return self.matches
	def getNextMatch(self):
		"""
		Fetches the next match to be played in the tournament.
		:param self: A reference to the Tournament object itself
		:return: returns the players to play in the next match and the number of times those players have met in a row, including the next match
		"""
		mem = self.currentGame
		if mem < len(self.matches):
			self.currentGame = self.currentGame + 1
			return 2,self.matches[mem]
		else:
			return 1,self.players
	def getCurrentMatch(self):
		"""
		Fetches the current match.
		:param self: A reference to the Tournament object itself
		:return: returns the players to play in the current match and the number of times those players have met in a row, including the current match
		"""
		mem = self.currentGame-1
		if mem < len(self.matches):
			return 2,self.matches[mem]
		else:
			return 1, self.players
	def drawBracket(self):
		"""
		Draws the bracket of the tournament.
		:param self: A reference to the Tournament object itself
		:return: retuerns nothing
		"""
		if len(self.players) >= 2:
			self.makeMatches()
		xoffset = 240
		yoffset = 50
		xstart = 300
		ystart = 10
		x = xstart
		y = ystart
		rows = 0
		cols = 1
		nextpicked = None
		maxrows = self.maxrows
		for match in self.matches:
			if nextpicked == None and match.winner == None:
				self.drawMatch(match, x, y, True)
				nextpicked = True
			else:
				self.drawMatch(match, x, y)
			rows = rows + 1
			if rows == maxrows:
				maxrows = maxrows - 1
				cols = cols + 1
				rows = 1
				x = x + xoffset
				if cols == 3:
					yoffset = (yoffset * cols)
				else:
					yoffset = (yoffset * cols)/2
				y = ystart + yoffset
			else:
				if cols == 2:
					y = y + yoffset*4
				elif cols == 1:
					y = y + yoffset*2
				else:
					y = y + yoffset*2
	def drawMatch(self, match, x, y, is_next = False):
		"""
		Draws a match in the tournament bracket.

		:param self: A reference to the Tournament object itself
		:param match: A reference to the match to be drawn
		:param x: Horizontal coordinate for where to begin to draw the next match
		:param y: Vertical coordinate for where to begin to draw the next match
		:param is_next: A boolean deciding whether the given match is the next to be played
		:return: returns nothing
		"""
		width = 200
		height = 40

		player1color = self.ui.color_menu
		player2color = self.ui.color_menu
		if match.winner == 1:
			player2color = self.ui.color_lighttext
		elif match.winner == 2:
			player1color = self.ui.color_lighttext
		elif is_next == True:
			player1color = self.ui.color_highlight
			player2color = self.ui.color_highlight

		self.ui.visiblebuttons.append(
			Button(self.ui.pygame, self.ui.mainArea).create(
				player1color,
				self.ui.color_darktext,
				self.ui.color_border,
				x,
				y,
				width,
				height,
				match.player1.name,
				self.drawBracket
			)
		)

		self.ui.visiblebuttons.append(
			Button(self.ui.pygame, self.ui.mainArea).create(
				player2color,
				self.ui.color_darktext,
				self.ui.color_border,
				x,
				y+height+5,
				width,
				height,
				match.player2.name,
				self.drawBracket
			)
		)

	def makeMatches(self):
		"""
		Appends a match to the Tournament object for each player belonging to the Tournament object.

		:param self: A reference to the Tournament object itself
		:return: returns nothing
		"""

		while len(self.players) > 1:
			self.matches.append(TournamentGame(self.players.pop(), self.players.pop()))

	def setWinner(self, player):
		"""
		Appends the current winners to a list belonging to the Tournament object which contains the players advancing to the next round.

		:param self: A reference to the Tournament object itself
		:param player: A reference to the player to be appended to the list of winners
		:return: returns nothing
		"""

		self.matches[self.currentGame-1].setWinner(player)
		if player == 1:
			self.players.append(self.matches[self.currentGame-1].player1)
		else:
			self.players.append(self.matches[self.currentGame-1].player2)

		print("We have a winner...")
		print(self.players)

	def drawTournamentWinScreen(self, winTuple):
		"""
		Draws the tournament win screen

		:param self: A reference to the Tournament object itself
		:param winTuple: A touple containing the winning player and the rest
		:return: returns nothing
		"""
		crapp, winningplayer = winTuple
		print("Should now draw the winner of the tournament")
		self.ui.visiblebuttons = []
		buttonHalfWidth = 150
		buttonHeight = 50
		self.ui.mainArea.fill(self.ui.color_background)
		self.ui.visiblebuttons.append(
			Button(self.ui.pygame, self.ui.mainArea).create(
				self.ui.color_menu,
				self.ui.color_darktext,
				self.ui.color_border,
				100,
				450,
				buttonHalfWidth*2,
				buttonHeight,
				"Back",
				self.ui.displayMainMenu
			)
		)

		coords1 = 400, 170
		coords2 = 400, 220
		coords3 = 400, 270
		coords4 = 400, 320
		font1 = self.ui.pygame.font.SysFont("sans", 52)
		font2 = self.ui.pygame.font.SysFont("sans", 40)
		font3 = self.ui.pygame.font.SysFont("sans", 40)

		row1 = font1.render("And", True, self.ui.color_darktext)
		row2 = font2.render("the", True, self.ui.color_darktext)
		row3 = font3.render("winner is", True, self.ui.color_darktext)
		row4 = font1.render(winningplayer[0].name, True, self.ui.color_darktext)

		self.ui.mainArea.blit(row1, coords1)
		self.ui.mainArea.blit(row2, coords2)
		self.ui.mainArea.blit(row3, coords3)
		self.ui.mainArea.blit(row4, coords4)


import numpy as np
import cv2
from os import listdir
import matplotlib.pyplot as plt
import statistics

from docx import Document
from docx.oxml.ns import qn
from docx.shared import Pt,RGBColor
from docx.enum.text import WD_ALIGN_PARAGRAPH

def smooth(x,window_len=10,window='flat'):
    return np.convolve(x, np.ones(window_len)/window_len, mode='valid')

def get_hist(bin_img, type="binary_sum"):
    hist = []
    if type == "binary_sum":
        hist = np.sum(bin_img, axis=0)
        hist = smooth(hist)
    elif type == "connected_comp":
        for row in bin_img.T:
            num_labels, labels_im = cv2.connectedComponents(row)
            hist.append(num_labels)
    return hist

def extract_rois(horizontal_hist, THRESHOLD = 1):
    ROIs_idx = []
    idxs = []

    for idx, ele in enumerate(horizontal_hist):

        if ele <= THRESHOLD and idx != len(horizontal_hist) - 1:
            idxs.append(idx)
        else:
            if idxs:
                ROIs_idx.append(idxs)
                idxs = []

    return ROIs_idx

def whitespace_deletion(image):
    up_bound = 0
    low_bound = len(image)
    left_bound = 0
    right_bound = len(image[0])
    #vertical crop
    for idx in range(0, len(image[0])):
        if np.any(image[:, idx]):
            left_bound = idx
            break
    for idx in range(len(image[0]) - 1, -1, -1):
        if np.any(image[:, idx]):
            right_bound = idx
            break

    #horizontal crop
    for idx in range(0, len(image)):
        if np.any(image[idx, :]):
            up_bound = idx
            break
    for idx in range(len(image) - 1, -1, -1):
        if np.any(image[idx, :]):
            low_bound = idx
            break
    return image[up_bound:low_bound, left_bound:right_bound]

def preprocess_image(image):
    imgray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    filteredImg = cv2.medianBlur(imgray, ksize=11)
    ret, thresh1 = cv2.threshold(filteredImg,127,255,cv2.THRESH_BINARY)
    return thresh1

def extract_characters(image, ROIs, line_nr, name):
    characters = []

    for idx in range(0, len(ROIs) - 1):
        segmentation_left = int(ROIs[idx][-1])
        segmentation_right = int(ROIs[idx+1][0])
        char = image[:, segmentation_left:segmentation_right]
        cropped_char = whitespace_deletion(char)
        count = np.sum(cropped_char == 255)
        if count > 0:
            characters.append(cropped_char)
            #cv2.rectangle(image, (segmentation_left, 0), (segmentation_right, len(image)), (255,0,0), 2)
    #cv2.imwrite("results/" + str(name) + "_" + str(line_nr) + "_.jpg", image)
    return characters

'''
file_name = "P632-Fg002-R-C01-R01-binarized_line_"
for line in range(0,8):
    sentence_img = cv2.imread("results/" + file_name + str(line) + ".jpg")

    thresh1 = preprocess_image(sentence_img)

    horizontal_hist = get_hist(thresh1, type="connected_comp")
    ROIs = extract_rois(horizontal_hist)

    chars = extract_characters(thresh1, ROIs)

    for idx, char in enumerate(chars):
        cv2.imwrite("chars/" + str(idx) + "_" + str(line) + ".jpg", char)
'''
def output_doc(texts, name):
    '''
    texts: the text list. e.g. [[ab],[cd]]. [ab] is the first line
    name: the name of the img without format (e.g. '.jpg').
    '''
    document = Document()
    document.styles['Normal'].font.name = u'Habbakuk'
    document.styles['Normal'].font.size = Pt(12)
    document.styles['Normal'].font.color.rgb = RGBColor(0,0,0)
    for i in range(len(texts)):
        line=texts[i]
        if line==['#']:
            doc_line=document.add_paragraph('')
        else:
            doc_line=document.add_paragraph(line)
        doc_line.paragraph_format.alignment= WD_ALIGN_PARAGRAPH.RIGHT
    document.save(name+'.docx')
    print(name+'.docx'+" generated!!!")

def output_txt(texts, name):
    '''
    texts: the text list. e.g. [[ab],[cd]]. [ab] is the first line
    name: the name of the img without format (e.g. '.jpg').
    '''
    with open(name+'.txt','wb') as f:
        for i in range(len(texts)):
            line=texts[i][0]
            if line=='#':
                f.write(str('\n').encode(encoding='utf-8'))
            else:
                f.write(str(line + '\n').encode(encoding='utf-8'))
    f.close()
    print(name+'.txt'+" generated!!!")


# Proceedgeral Oriented Program

a=12
b=34

print("The Sum of a and b is", a+b)

# Object Oriented Program

class Number:
    def sum(self):
        return self.c + self.d
num=Number()
num.c = 10
num.d = 34
s=num.sum()
print(s)

'''
EmployeeName -->PascalCase
isNumeric, isFloatOrInt -->camelcase
'''


#!/usr/bin/python

import os
import gzip
import logging
from collections import defaultdict
from exec_helpers import run_cmds

def parse_table_to_json(fp, sep="\t", nrows=0):
    """Parse a TSV into JSON format."""
    output = []

    if fp.endswith(".gz"):
        with gzip.open(fp, "rt") as f:
            header = f.readline()
            header = header.rstrip("\n").split(sep)

        f = gzip.open(fp, "rt")
    else:
        with open(fp, "rt") as f:
            header = f.readline()
            header = header.rstrip("\n").split(sep)

        f = open(fp, "rt")

    for ix, values in enumerate(f):
        # Skip the header line
        if ix == 0:
            continue
        if nrows > 0 and ix == nrows:
            break
        # Parse the line
        values = values.rstrip("\n").split(sep)
        # Add to the output
        if len(values) == len(header):
            output.append(set_variable_type(header, values))

    f.close()

    return output

def set_variable_type(
    header,
    values,
    types={
        "species_id": str,
        "relative_abundance": float,
        "count_reads": int,
        "coverage": float,
        "copy_number": float,
        "pangenome_size": int,
        "covered_genes": int,
        "fraction_covered": float,
        "mean_coverage": float,
        "marker_coverage": float,
        "aligned_reads": int,
        "mapped_reads": int,
        "covered_bases": int,
        "genome_length": int,
        "count_a": int,
        "count_t": int,
        "count_c": int,
        "count_g": int,
        "depth": int,
        "ref_pos": int,
    }
):
    """Make a dict, but set the variable type as appropriate."""
    return {
        k: types.get(k, str)(v)
        for k, v in zip(header, values)
    }

def run_midas(
    read_fp,               # FASTQ file path
    db_fp,                 # Local path to DB
    temp_folder,           # Folder for results
    threads=1
):
    logging.info("Running MIDAS on {}".format(read_fp))
    logging.info("Reference database: {}".format(db_fp))
    logging.info("Threads: {}".format(threads))

    assert os.path.exists(read_fp)

    # Make the output folder in the temp folder, based on the read name
    output_folder = os.path.join(
        temp_folder,
        "{}.midas".format(read_fp.split('/')[-1])
    )

    # Run the species abundance summary
    logging.info("Running species summary")
    run_cmds([
        "run_midas.py",
        "species",
        output_folder,
        "-1", read_fp,
        "-t", str(threads),
        "--remove_temp",
        "-d", db_fp
    ])
    assert os.path.exists(
        os.path.join(output_folder, "species")
    )

    # Run the gene abundance summary
    logging.info("Running gene summary")
    run_cmds([
        "run_midas.py",
        "genes",
        output_folder,
        "-1", read_fp,
        "-t", str(threads),
        "--remove_temp",
        "-d", db_fp
    ],
        # Tolerate failure of this command because it may fail if
        # there are no species meeting the indicated depth threshold
        catchExcept=True
    )

    logging.info("Done running MIDAS")

    return output_folder

def annotate_gene_results(gene_results, species_name, ref_db):
    """Annotate a set of gene results."""
    pan_genome_file = os.path.join(
        ref_db, "pan_genomes", species_name, "centroid_functions.txt.gz"
    )

    annotations = {
        d["gene_id"]: defaultdict(list)
        for d in gene_results
    }

    if os.path.exists(pan_genome_file):
        with gzip.open(pan_genome_file) as f:
            for line in f:
                line = line.rstrip("\n").split("\t")
                if len(line) != 3:
                    continue
                if line[0] in annotations:
                    annotations[line[0]][line[2]].append(line[1])

    for d in gene_results:
        d["annot"] = annotations[d["gene_id"]]

    return gene_results

def parse_midas_output(output_folder, ref_db=None):
    """Parse the output from MIDAS."""

    # Make sure the input exists
    assert os.path.exists(output_folder)

    output = {}

    # Parse the species information
    logging.info("Parsing the species abundance information")
    species_fp = os.path.join(output_folder, "species", "species_profile.txt")
    assert os.path.exists(species_fp)
    output["species"] = parse_table_to_json(species_fp)

    # Filter down to the species with >0 reads
    output["species"] = [d for d in output["species"] if d["count_reads"] > 0]

    # Read in the genes results, if present
    genes_folder = os.path.join(output_folder, "genes")
    gene_summary_fp = os.path.join(genes_folder, "summary.txt")
    if os.path.exists(gene_summary_fp):

        output["genes"] = parse_table_to_json(
            gene_summary_fp
        )

        for species in output["genes"]:
            species_details_fp = os.path.join(
                genes_folder,
                "output",
                species["species_id"] + ".genes.gz"
            )

            if os.path.exists(species_details_fp):
                logging.info(
                    "Parsing gene output for {}".format(species["species_id"])
                )

                # Read in the genes that were detected
                gene_results = parse_table_to_json(
                    os.path.join(species_details_fp)
                )

                # Filter to the genes with >0 count_reads
                gene_results = [
                    d
                    for d in gene_results
                    if d["count_reads"] > 0
                ]

                # Annotate the gene results with the gene functions
                if ref_db is not None:
                    logging.info("Adding gene annotations")
                    gene_results = annotate_gene_results(
                        gene_results,
                        species["species_id"],
                        ref_db
                    )

                species["genes"] = gene_results
    else:
        logging.info("No gene abundance information found")

    return output


# HOW TO BIND TRACKBAR TO OPENCV WINDOWS EXAMPLE 1
# TRACKBAR IS USED WHENEVER YOU WANT TO CHANGE SOME VALUE IN YOUR IMAGE DYNAMICALLY AT RUNTIME.
import numpy as np
import cv2 as cv

def nothing(x):
    print(x)

# create a black image in a window
img=np.zeros((300,512,3),np.uint8)

cv.namedWindow('image')

# This trackbar will change the BGR value of the image
cv.createTrackbar('B','image',0,255,nothing)
cv.createTrackbar('G','image',0,255,nothing)
cv.createTrackbar('R','image',0,255,nothing)

# Adding switch using a trackbar
switch='0 : OFF\n 1 : ON'
cv.createTrackbar(switch,'image',0,1,nothing)
while(1):
    cv.imshow('image',img)
    k=cv.waitKey(1) & 0xFF

    if k==27 :
        break

    # To get the current position of trackbar
    b=cv.getTrackbarPos('B','image')
    g = cv.getTrackbarPos('G', 'image')
    r = cv.getTrackbarPos('R', 'image')
    s=  cv.getTrackbarPos(switch, 'image')

    if s==0:
        img[:]=0
    else:
        # Set these value to our image
        img[:]=[b,g,r]

cv.destroyAllWindows()


# settings_component.py
import streamlit as st

def settings_sidebar():
    st.sidebar.markdown("## Settings")

    # Text size adjustment
    text_size = st.sidebar.slider("Adjust Text Size", min_value=12, max_value=36, value=16)
    st.markdown(f"<style>body{{font-size:{text_size}px;}}</style>", unsafe_allow_html=True)

    # Theme selection
    theme_options = ["Light", "Dark"]
    selected_theme = st.sidebar.selectbox("Select Theme", theme_options)

    if selected_theme == "Dark":
        st.markdown("<link rel='stylesheet' href='styles.css' class='dark-theme'>", unsafe_allow_html=True)
    else:
        st.markdown("<link rel='stylesheet' href='styles.css' class='light-theme'>", unsafe_allow_html=True)

    # Other settings can be added here

    #zoom settings
    zoom_settings = st.sidebar.slider("Adjust zoom ", min_value=12, max_value=360, value=16)


from django.db import models

class PlotManager(models.Manager):
    def seasons_order(self, *args, **kwargs):
        """Sort patterns by preferred order of Y then -- then N"""
        qs = self.get_queryset().filter(*args, **kwargs)
        qs = qs.annotate( custom_order=
            models.Case(
                models.When(pref='Y', then=models.Value(0)),
                models.When(pref='--', then=models.Value(1)),
                models.When(pref='N', then=models.Value(2)),
                default=models.Value(3),
                output_field=models.IntegerField(), )
            ).order_by('custom_order'
        )
        return qs


#!/usr/bin/python
from rollingdice.fudge import fudge
from rollingdice.main import dice

from os import path, listdir, getenv
from sys import platform
from random import choice
import xml.etree.ElementTree as ET
import gettext

gettext.install('charfly', '/home/none/prj/charfly/locale')

split_words = lambda s: s.capitalize().translate(str.maketrans('_', ' '))

def get_data():
    if path.isdir('data'):
        return 'data'
    elif platform.startswith('linux'):
        d = getenv('XDG_DATA_HOME')
        if d: return path.join(d, 'charfly')
        else: return path.join(getenv('HOME'),'.local/share/charfly')

def check_full(files, nat):
    if files.count(nat) < 3:
        return False
    else:
        return True

def get_allnat():
    files = listdir(path.join(get_data(), 'jang'))
    nats = set()
    checklist = []
    for f in files:
        f = f.split('_')[0]
        nats.add(f)
        checklist.append(f)
    nats = list(nat for nat in nats if check_full(checklist, nat))
    return nats

def xml2opt(path):
    result = []

    tree = ET.parse(path)
    root = tree.getroot()

    for type_ in root:
        tag = split_words(_(type_.tag))
        txt = _(choice(list(type_)).text)
        result.append((tag, txt))

    emph = choice(result)
    result.remove(emph)

    return (emph, result)

def get_age(mid):
    # mid + 10 * (4df) + d10
    age = 0
    while age <= 0:
        age = mid + 10 * fudge(fancy = False) + dice(10)
    return age

def get_first_reaction():
    tree = ET.parse(path.join(get_data(), 'first-reactions.xml'))
    root = tree.getroot()

    reaction = root.find('*[@numeric="{}"]'.format(fudge(fancy = False)))
    tag = split_words(_(reaction.tag))
    description = _(reaction.text).strip()
    return (tag, description)

def create(nations, genders, mid_age, count = 1, datapath = get_data()):
    from jang import single_name

    result = []

    for i in range(count):
        nation = choice(nations)
        gender = choice(genders)
        age = get_age(mid_age)

        name = single_name(nation, gender,
            datapath = path.join(get_data(), 'jang'))

        mannerism, m_other = xml2opt(
            path.join(datapath, 'mannerisms.xml')
        )
        first_impression, f_other = xml2opt(
            path.join(datapath, 'first-impressions.xml')
        )
        first_reaction = get_first_reaction()

        result.append((name, age, nation, gender,
            mannerism, first_impression,
            m_other, f_other,
            first_reaction))
    return result

def decorate(chars, full = True):
    result = []
    for char in chars:
        if not full:
            result.append((
                '{0[0]} ({0[1]})\n'
                '{1}: {0[2]}, {2}: {0[3]}\n\n'
                '{3}: '
                '{0[4][1]} ({0[4][0]})\n'
                '{4}: '
                '{0[5][1]} ({0[5][0]})\n'
                '{5}: '
                '{0[8][0]}'
                ).format(
                    char,
                    _('Nation'),
                    _('gender'),
                    _('Mannerism'),
                    _('First impression'),
                    _('First reaction')
                    )
            )
        else:
            result.append((
                '{0[0]} ({0[1]})\n\n'
                '{3}: {0[2]}, {4}: {0[3]}\n\n'
                '{0[4][0]}: {0[4][1]}\n'
                '{5}:\n    '
                '{1}\n\n'
                '{0[5][0]}: {0[5][1]}\n'
                '{5}:\n    '
                '{2}\n\n'
                '{6}: '
                '{0[8][0]}\n    {0[8][1]}'
                ).format(
                    char,
                    '\n    '.join('{0[0]}: {0[1]}'.format(t) for t in char[6]),
                    '\n    '.join('{0[0]}: {0[1]}'.format(t) for t in char[7]),
                    _('Nation'),
                    _('gender'),
                    _('Other'),
                    _('First reaction')
                    )
            )
    return '\n\n-----\n\n'.join(result)

def main ():
    character = create('eng', 'male', 30, '/home/none/prj/charfly')
    print(decorate(character))

if __name__ == '__main__':
    main()


import  pandas as pd
import requests
from bs4 import BeautifulSoup

# if u want to check than copy below link and browse it
page = requests.get('https://economictimes.indiatimes.com/indices/sensex_30_companies?sortby=companyname&sortorder=asc')
soup = BeautifulSoup(page.content, 'html.parser')
# print(soup)

shares = soup.find(class_='data_display')
company = shares.find_all(class_='dataList')
company_name = [name.find('a').get_text() for name in company]
current_price = [price.find(class_='ltp').get_text() for price in company]
current_change = [change.find(class_='change').get_text() for change in company]
# print(company_name)
# print(current_price)
# print(current_change)

# making table using pandas library
live_stock = pd.DataFrame({
    'Company Name': company_name,
    'Current Price': current_price,
    'Change(Rs)': current_change
})

print(live_stock)


#!/usr/bin/python

# Version 20181106
# Purpose: Use leave-one-out analysis and the change of AUC-ROC to evaluate importance of each feature.
# Usage = "QTG_feature_importance.py input_feature_list species_abbreviation"
# feature list: use Arabidopsis_features_v4.csv for Arabidopsis; use rice_features_v2.csv for rice
# species_abbreviation: "AT" for Arabidopsis; "OS" for rice
# Usage example: QTG_feature_importance.py Arabidopsis_features_v4.csv 'AT'

import numpy as np
import random
import pandas as pd
from sklearn import cross_validation
from sklearn.cross_validation import KFold
from sklearn import svm
from sklearn import metrics
from sklearn import preprocessing
from sklearn import ensemble
from sklearn.metrics import roc_curve, auc, precision_recall_curve, average_precision_score
import sys
from scipy.interpolate import interp1d
import time

start_time = time.time()

def train_qtg_metrics_LOO(df, train_set,out):
    if sys.argv[2]=='AT':
        mol_para=[9,20]# parameters for Arabidopsis
    if sys.argv[2]=='OS':
        mol_para=[9,5]# parameters for Arabidopsis
    clf = ensemble.RandomForestClassifier(n_estimators=100,min_samples_split=2,max_features=mol_para[0]) # Random forest parameters
    k_numb_iter=50 #  interations for randomly re-spliting causal gene list
    all_auc = []

    if  k_numb_iter > 1 : # re-shuffle on or off based on k_iter
        shuffle_switch=True
    else:
        shuffle_switch=False

    neg_numb_iter=50 #interrations for randomly selecting negatives from genome and re-training models
    for n in range(0, k_numb_iter):
        skf=KFold(len(train_set), n_folds=5,shuffle=shuffle_switch) # five fold cross-validatoin
        roc_auc_mean=[]
        for m, (train_cv, test_cv) in enumerate(skf):
            fold_mean_tpr = np.linspace(1, 0, 101)
            for i in range(0, neg_numb_iter): # terate for randomly selecting negatives.
                train_data = train_set.iloc[train_cv]
                test_data = train_set.iloc[test_cv]
                training_negative = random.sample(list(df[df['class']==0].index), int(len(train_data)*mol_para[1]))
                testing_negatives = random.sample(list(df[df['class']==0].index), len(test_cv)*200) #
                train_data=train_data.append(df.iloc[training_negative])
                test_data=test_data.append(df.iloc[testing_negatives])
                train_feature=train_data.drop(['class'], axis=1)
                test_feature=test_data.drop(['class'], axis=1)
                train_feature_L=train_feature.drop(out, axis=1, inplace=False) # leave one feature out
                test_feature_L=test_feature.drop(out, axis=1, inplace=False) # leave one feature out

                probas_=clf.fit(train_feature, train_data['class']).predict_proba(test_feature) # the predictions of full model
                probas_L=clf.fit(train_feature_L, train_data['class']).predict_proba(test_feature_L) # the predictions of leave-one-out model

                fpr, tpr1, thresholds1 = roc_curve(test_data['class'], probas_[:, 1]) # export precision, recall,  associated threshhold of the full model
                fpr_L, tpr1_L, thresholds1_L = roc_curve(test_data['class'], probas_L[:, 1]) # export precision, recall,  associated threshhold of the leave-one-out model
                roc_auc_mean.append(auc(fpr_L, tpr1_L)-auc(fpr,tpr1)) #calculate the change of AUC-ROC (delta AUC-ROC)

        all_auc.append(np.mean(roc_auc_mean))

    return ([out,np.mean(all_auc), np.std(all_auc)])# average and standarad deviation of delta AUC-ROC for each feature
    print ('AUC-ROC averge %f ; SD is %f' % (np.mean(all_auc), np.std(all_auc))  )

dt = sys.argv[1]
df = pd.read_csv(dt)
df = df.drop(['ID'], axis=1)
df=df.dropna(axis=1,how='all')
df['network_weight'] = preprocessing.scale(df['network_weight'])
train_set = df[df['class']==1]

for i in df.columns[:-1]:
    with open(sys.argv[2]+'_'+'LOO_AUC_reduction.txt','a') as outfile:  #appending mode, so delete file before a new run
        a=train_qtg_metrics_LOO(df, train_set,i)
        outfile.write ('{0}\t{1}\t{2}\n'.format(a[0],a[1],a[2]) ) # output feature importance results

print("--- %s Hrs ---" % round( ((time.time() - start_time)/3600),2) )


"Test model methods."

import json

from mock import patch

from .base import BaseReportTestCase
from email_reports.models import SchedulableReport

class SendHTMLReportTestCase(BaseReportTestCase):
    "Send HTML email by parsing view reponse HTML."

    def setUp(self):
        self.report = self.create_report(view_name='test-report', report_type=SchedulableReport.TYPE_HTML)
        self.subscription = self.create_report_subscription(report=self.report)
        self.user = self.create_user()
        self.subscription.users.add(self.user)

    def test_send_single_email(self):
        "Parse email body to send to the users."
        with patch('email_reports.models.send_HTML_email') as send_email:
            self.subscription.send()
            self.assertEqual(send_email.call_count, 1)
            args, kwargs = send_email.call_args
            title, email, body = args
            self.assertEqual(email, self.user.email)

    def test_send_multiple_emails(self):
        "Parse email body to send to the all users."
        other_user = self.create_user()
        self.subscription.users.add(other_user)
        with patch('email_reports.models.send_HTML_email') as send_email:
            self.subscription.send()
            self.assertEqual(send_email.call_count, 2)

    def test_email_subject(self):
        "Title is generated from report display name."
        with patch('email_reports.models.send_HTML_email') as send_email:
            self.subscription.send()
            args, kwargs = send_email.call_args
            title, email, body = args
            self.assertTrue(self.report.display_name in title)

    def test_email_body(self):
        "Body should be parsed from view content."
        with patch('email_reports.models.send_HTML_email') as send_email:
            self.subscription.send()
            args, kwargs = send_email.call_args
            title, email, body = args
            # Default body content
            self.assertTrue('Bar' in body)

    def test_view_args(self):
        "Subscription can be saved with serialized arguments for the view."
        self.report.view_name = 'test-report-id'
        self.report.save()
        args = {'report_id': 100}
        self.subscription._view_args = json.dumps(args)
        self.subscription.save()
        with patch('email_reports.models.send_HTML_email') as send_email:
            self.subscription.send()
            args, kwargs = send_email.call_args
            title, email, body = args
            self.assertTrue('Report ID: 100' in body)

    def test_email_subject_parsed(self):
        "Subject can be optionally parsed from the HTML. New lines are removed."
        self.report.view_name = 'test-report-subject'
        self.report.save()
        with patch('email_reports.models.send_HTML_email') as send_email:
            self.subscription.send()
            args, kwargs = send_email.call_args
            title, email, body = args
            self.assertEqual(title, "Custom Subject")


import datetime
import pandas as pd
from dateutil.relativedelta import relativedelta
from collections import Iterable

ALLOWED_TIME_COLUMN_TYPES = [
    pd.Timestamp,
    pd.DatetimeIndex,
    datetime.datetime,
    datetime.date,
]

def is_datetime_like(x):
    """Function that checks if a data frame column x is of a datetime type."""
    return any(isinstance(x, col_type) for col_type in ALLOWED_TIME_COLUMN_TYPES)

def get_datetime_col(df, datetime_colname):
    """
    Helper function for extracting the datetime column as datetime type from
    a data frame.

    Args:
        df: pandas DataFrame containing the column to convert
        datetime_colname: name of the column to be converted

    Returns:
        pandas.Series: converted column

    Raises:
        Exception: if datetime_colname does not exist in the dateframe df.
        Exception: if datetime_colname cannot be converted to datetime type.
    """
    if datetime_colname in df.index.names:
        datetime_col = df.index.get_level_values(datetime_colname)
    elif datetime_colname in df.columns:
        datetime_col = df[datetime_colname]
    else:
        raise Exception("Column or index {0} does not exist in the data " "frame".format(datetime_colname))

    if not is_datetime_like(datetime_col):
        datetime_col = pd.to_datetime(df[datetime_colname])
    return datetime_col

def get_month_day_range(date):
    """
    Returns the first date and last date of the month of the given date.
    """
    # Replace the date in the original timestamp with day 1
    first_day = date + relativedelta(day=1)
    # Replace the date in the original timestamp with day 1
    # Add a month to get to the first day of the next month
    # Subtract one day to get the last day of the current month
    last_day = date + relativedelta(day=1, months=1, days=-1, hours=23)
    return first_day, last_day

def split_train_validation(df, fct_horizon, datetime_colname):
    """
    Splits the input dataframe into train and validate folds based on the
    forecast creation time (fct) and forecast horizon specified by fct_horizon.

    Args:
        df: The input data frame to split.
        fct_horizon: list of tuples in the format of
            (fct, (forecast_horizon_start, forecast_horizon_end))
        datetime_colname: name of the datetime column

    Note: df[datetime_colname] needs to be a datetime type.
    """
    i_round = 0
    for fct, horizon in fct_horizon:
        i_round += 1
        train = df.loc[df[datetime_colname] < fct].copy()
        validation = df.loc[(df[datetime_colname] >= horizon[0]) & (df[datetime_colname] <= horizon[1]),].copy()

        yield i_round, train, validation

def add_datetime(input_datetime, unit, add_count):
    """
    Function to add a specified units of time (years, months, weeks, days,
    hours, or minutes) to the input datetime.

    Args:
        input_datetime: datatime to be added to
        unit: unit of time, valid values: 'year', 'month', 'week',
            'day', 'hour', 'minute'.
        add_count: number of units to add

    Returns:
        New datetime after adding the time difference to input datetime.

    Raises:
        Exception: if invalid unit is provided. Valid units are:
            'year', 'month', 'week', 'day', 'hour', 'minute'.
    """
    if unit == "Y":
        new_datetime = input_datetime + relativedelta(years=add_count)
    elif unit == "M":
        new_datetime = input_datetime + relativedelta(months=add_count)
    elif unit == "W":
        new_datetime = input_datetime + relativedelta(weeks=add_count)
    elif unit == "D":
        new_datetime = input_datetime + relativedelta(days=add_count)
    elif unit == "h":
        new_datetime = input_datetime + relativedelta(hours=add_count)
    elif unit == "m":
        new_datetime = input_datetime + relativedelta(minutes=add_count)
    else:
        raise Exception(
            "Invalid backtest step unit, {}, provided. Valid " "step units are Y, M, W, D, h, " "and m".format(unit)
        )
    return new_datetime

def convert_to_tsdf(input_df, time_col_name, time_format):
    """
    Convert a time column in a data frame to monotonically increasing time
    index.
    Args:
        input_df(pandas.DataFrame): Input data frame to convert.
        time_col_name(str): Name of the time column to use as index.
        time_format(str): Format of the time column.

    Returns:
        pandas.DataFrame: A new data frame with the time column of the input
            data frame set as monotonically increasing index.
    """
    output_df = input_df.copy()
    if not is_datetime_like(output_df[time_col_name]):
        output_df[time_col_name] = pd.to_datetime(output_df[time_col_name], format=time_format)

    output_df.set_index(time_col_name, inplace=True)

    if not output_df.index.is_monotonic:
        output_df.sort_index(inplace=True)

    return output_df

def is_iterable_but_not_string(obj):
    """
    Determine if an object has iterable, list-like properties.
    Importantly, this functions *does not* consider a string
    to be list-like, even though Python strings are iterable.

    """
    return isinstance(obj, Iterable) and not isinstance(obj, str)

def get_offset_by_frequency(frequency):
    frequency_to_offset_map = {
        "B": pd.offsets.BDay(),
        "C": pd.offsets.CDay(),
        "W": pd.offsets.Week(),
        "WOM": pd.offsets.WeekOfMonth(),
        "LWOM": pd.offsets.LastWeekOfMonth(),
        "M": pd.offsets.MonthEnd(),
        "MS": pd.offsets.MonthBegin(),
        "BM": pd.offsets.BMonthEnd(),
        "BMS": pd.offsets.BMonthBegin(),
        "CBM": pd.offsets.CBMonthEnd(),
        "CBMS": pd.offsets.CBMonthBegin(),
        "SM": pd.offsets.SemiMonthEnd(),
        "SMS": pd.offsets.SemiMonthBegin(),
        "Q": pd.offsets.QuarterEnd(),
        "QS": pd.offsets.QuarterBegin(),
        "BQ": pd.offsets.BQuarterEnd(),
        "BQS": pd.offsets.BQuarterBegin(),
        "REQ": pd.offsets.FY5253Quarter(),
        "A": pd.offsets.YearEnd(),
        "AS": pd.offsets.YearBegin(),
        "BYS": pd.offsets.YearBegin(),
        "BA": pd.offsets.BYearEnd(),
        "BAS": pd.offsets.BYearBegin(),
        "RE": pd.offsets.FY5253(),
        "BH": pd.offsets.BusinessHour(),
        "CBH": pd.offsets.CustomBusinessHour(),
        "D": pd.offsets.Day(),
        "H": pd.offsets.Hour(),
        "T": pd.offsets.Minute(),
        "min": pd.offsets.Minute(),
        "S": pd.offsets.Second(),
        "L": pd.offsets.Milli(),
        "ms": pd.offsets.Milli(),
        "U": pd.offsets.Micro(),
        "us": pd.offsets.Micro(),
        "N": pd.offsets.Nano(),
    }

    return frequency_to_offset_map[frequency]


# -*- coding:UTF-8 -*-

# author:sommuni
# contact: test@test.com
# datetime:2022/12/8 21:52
# software: PyCharm

"""
文件说明：Response封装

"""
import json

def _response(code=200,status="failed", msg="", error_msg="",data=None, **kwargs):
    response = {
        "code": code,
        "status":status
    }
    if msg:
        response['msg'] = msg
    if error_msg:
        response['error_msg'] = error_msg
    if data:
        response['data'] = data

    response.update(kwargs)
    return response


import os
path = 'C:\\Users\\LenovoPc\\Desktop\\CSV Book_Details\\'

join = os.path.join(csv_path, 'books.txt')
make = os.makedirs(join)

def csv_book_details(book_name, book_author, book_path, csv_path):#this is what I mean by argument, and passing stuff through it
    if not os.path.exists(csv_path):

        f = open(make, "a")

        f.write('Book name: ' + book_name)
        f.write('\n')

        f.write('Author name:', book_author)
        f.write('\n')

        f.write('Book path:', book_path)
        f.write('\n')

        f.close()

    if os.path.exists(make):
        with open(make) as file:
            contents = file.read()
            search_word = input("enter a word you want to search in file: ")
            if search_word in contents:
                print ('word found')
            else:
                print ('word not found')

if __name__ == "__main__":
    csv_book_details('BOOK NAME', 'BOOK AUTHOR', 'PATH', 'CSV_PATH') # here is a test case, we'll replace these arbitrary values with something useful later on, but the main usage is for anther script, that will pass these details.