The Interesting Times of Skipper

Programmers never be slaves !!!!

OOCRR 用户协议

09/06/20

OOCRR 用户协议

OOCRR 用户协议

任何单位或个人在使用OOCRR App服务之前(以下简称“OOCRR”),均应仔细阅读本条款,如不同意本条款可停止使用OOCRR的服务,一旦使用,即被视为对本条款全部内容的认可和接受。 一、任何单位或个人通过OOCRR使用到的图片/图像文件包括生成的临时URL链接,均系该用户或所有者制作提供(以下简称“第三方文件”)。本应用只根据图片提供OCR文字识别能力,并不是也不反映OOCRR之任何意见和主张,也不表示OOCRR同意或支持该等第三方文件的任何内容、主张或立场。本应用对第三方文件中内容之合法性、准确性、真实性、适用性、安全性等概不负责,也无法负责。 二、OOCRR所提供的识别图片提取文字能力是基于服务器的识别,需要首先将图片上传到服务器识别然后将识别结果展示在App中,之后就会删除图片,不会在OOCRR的服务器上进行存储。 三、任何单位或个人不得利用OOCRR上传、读取、下载、复制、发布、传播或者转载如下内容: 1、反对宪法所确定的基本原则的; 2、危害国家安全,泄露国家秘密,颠覆国家政权,破坏国家统一的; 3、损害国家荣誉和利益的; 4、煽动民族仇恨、民族歧视,破坏民族团结的; 5、破坏国家宗教政策,宣扬邪教和封建迷信的; 6、散布谣言,扰乱社会秩序,破坏社会稳定的; 7、散布淫秽、色情、赌博、暴力、凶杀、恐怖或者教唆犯罪的; 8、侮辱或者诽谤他人,侵害他人合法权益的; 9、含有法律、行政法规禁止的其他内容的信息。 四、任何单位或个人如需要第三方文件中的内容(包括图片、音频、视频、文档、链接等),并欲据此进行交易或其他行为前,应慎重辨别这些内容的合法性、准确性、真实性、实用性和安全性(包括下载第三方文件中内容是否会感染电脑病毒),并采取谨慎的预防措施。如您不确定这些内容是否合法、准确、真实、实用和安全,OOCRR建议您先咨询专业人士。 五、任何单位或者个人因相信、使用第三方文件中信息、服务、产品等内容,或据此进行交易等行为,而引致的人身伤亡、财产毁损(包括因下载而感染电脑病毒)、名誉或商誉诽谤、版权或知识产权等权利的侵犯等事件,及因该等事件所造成的损害后果,OOCRR概不负责,亦不会也不能承担任何法律责任,而应由第三方文件的所有者承担。无论何种原因,OOCRR不对任何非与OOCRR 直接发生的交易和行为承担任何直接、间接、附带或衍生的损失和责任。 六、任何单位或个人如认为通过OOCRR服务所得的第三方文件中内容可能涉嫌侵害其合法著作权,应按照《信息网络传播权保护条例》的规定,以书面的形式及时向OOCRR反应,并提供相应身份证明、权属证明及详细的侵权情况证明,OOCRR在收到上述文件后,会尽快断开对该内容的相关服务的链接。如果该等被断开链接的第三方文件所有者认为被提出权利主张的OOCRR 结果并未侵害他人合法著作权的,亦有权按照《信息网络传播权保护条例》的规定,向OOCRR 发出关于被断开链接不违反《信息网络传播权保护条例》的反通知。OOCRR提醒您注意:如您的主张侵权或主张不侵权的陈述失实,您将按照《信息网络传播权保护条例》的规定,承担相关法律责任。 七、每一个注册的OOCRR账号最多在5台设备上登录,如果超出5台,会采取限制登录的方式禁止继续登录。注册OOCRR账号之后,请合法使用账号所拥有的权限,任何通过违法手段破解功能及影响OOCRR服务的账号,OOCRR有权对账号实施封禁。 八、OOCRR可根据国家法律法规变化及维护用户权益需要,不时修改本条款,变更后的条款将通过法定程序在本条款中标明最后更新日期。

更新日期:2020年06月10日

OOCRR 隐私政策

09/06/20

OOCRR 隐私政策

OOCRR隐私保护政策

前言

欢迎使用OOCRR提供的服务!OOCRR深知个人信息对您的重要性,我们一向庄严承诺保护使用我们的产品和服务OOCRR之用户(以下统称“用户”或“您”)的个人信息及隐私安全。您在使用OOCRR时,我们可能会收集和使用您的相关个人信息。我们希望通过《OOCRR隐私保护政策》向您说明我们在收集和使用您相关个人信息时对应的处理规则等相关事宜,以便更好的保障您的权益。

以下是《OOCRR隐私保护政策》的要点说明:

为帮助您注册并使用OOCRR产品或服务,我们可能收集与提供服务相关的个人信息,您有权拒绝或撤回授权;

您可以访问、更正、删除您的个人信息,改变您授权同意的范围,注销您的帐号,我们为您提供了行使这些权利的途径。

我们采取了互联网业内标准的技术措施和数据安全措施来保护您的个人信息安全。

一、引言

本政策适用于OOCRRApp软件。

【特别提示】 请您在使用我们的各项产品和/或服务前,仔细阋读并充分理解本政策。一旦您使用或继续使用OOCRR产品/服务,即表示您同意我们按照本政策处理您的相关信息。如对本政策有任何疑问,您可以通过OOCRRApp中的联系我们进行反馈。

我们可能会不时对《OOCRR隐私保护政策》进行修订。当《OOCRR隐私保护政策》发生变更时,我们会在版本更新后以推送通知、弹窗等形式向您展示变更后的内容。

二、OOCRR处理个人信息的法律依据

如果您是中华人民共和国大陆地区的用户,我们将依据《中华人民共和国网络安全法》、《信息安全技术个人信息安全规范》(GB/T35273-2017)以及其他相关法律法规收集和使用您的个人信息,为您提供OOCRR产品和/或服务。我们通常只会在征得您同意的情况下收集您的个人信息。在某些情况下,我们可能还会基于法律义务或者履行合同之必需向您收集个人信息,或者可能需要个人信息来保护您的重要利益或其他人的利益。

三、我们如何收集和使用您的个人信息

我们会遵循正当、合法、必要的原则,出于本政策所述的以下目的,收集和使用您在使用服务过程中主动提供或因使用OOCRR产品和/或服务而产生的个人信息。如果我们要将您的个人信息用于本政策未载明的其它用途,或基于特定目的将收集而来的信息用于其他目的,我们将以合理的方式向您告知,并在使用前再次征得您的同意。

3.1 帮助您成为我们的在线用户

您注册并登录OOCRR帐号时,需要向我们提供以下信息:帐号名称、头像(如有)和手机号码(用于实名认证)。提供上述信息并同意《OOCRR用户协议》和本政策后,您可以使用OOCRR的全部核心业务功能。

3.2 向您提供产品和/或服务

为实现OOCRR的核心业务功能,我们可能需要向您收集个人信息。以下将详细列出OOCRR的核心业务功能及为实现该功能所需收集的个人信息,若您拒绝收集,则无法使用该服务。

在使用 OCR 文字识别与表格识别功能时,我们会先将您的图片上传到服务器进行识别,之后为您返回结果,此功能仅仅是将图片传输并进行识别,识别之后服务器会删除相关图片。

在您注册用户时以及进行普通网络请求时,我们会收集您的手机型号、系统版本、IP信息,以便于统计我们的用户分布情况。

3.3 我们可能从第三方间接获取您的个人信息

您使用第三方帐号(微信、Apple)登录OOCRR时,可选择授权OOCRR在符合相关法律法规要求的前提下读取并获得您在该第三方平台上登记、公布、记录的公开信息(包括昵称、头像),如果不再需要,您可以通过OOCRR的个人资料页面,删除绑定。

3.4 OOCRR向用户所请求隐私权限的具体用途

A. 读取/修改手机存储权限

用户从手机相册中选择图片进行图像处理时,需要访问您的存储权限才能获取图片;用户保存图片和保存OOCRR生成的文件时,需要访问存储权限才能正常保存。

B. 访问用户位置(通过GPS和网络定位)

OOCRR有 WiFi 识别功能,就是手机和电脑连接一个局域网,电脑浏览器与手机建立连接,可以将电脑上的图片直接在浏览器中进行识别。这个局域网连接,需要使用位置服务,以便发现周围相同的 Wifi名称进行连接。并不是必须,可以不允许。

C. 访问相机,拍摄照片或录制视频

OOCRR可以拍照后进行文字识别或其他处理,所以需要访问相机。

D. 读取设备通话状态或识别码

获取该权限用于确定设备的唯一性,用以辅助OOCRR反垃圾与数据统计系统,同时保护用户账号安全。

四、您管理个人信息的权利

我们非常重视您对个人信息的关注,并尽全力保护您对于自己个人信息访问、更正、删除以及撤回同意的权利,以使您拥有充分的能力保障您的隐私和安全。您的权利包括

4.1 访问和更正您的个人信息

A.除法律法规规定外,您有权随时访问和更正您的个人信息,具体包括: 您可通过【设置→个人信息】修改您的信息。

B.如果您需要查阅您在使用OOCRR过程中产生的其他个人信息,在合理要求下,我们会向您提供。若您无法通过上述方式访问或者更正您的个人信息的,可以通过发送邮件至phoenixtomax@gmail.com联系我们。我们会在15日回复您的访问请求。

4.2 删除您的个人信息

如果您需要注销您的个人账号,可以发送邮件到 phoenixtomax@gmail.com, 说明您的账号与昵称,我们会在5和工作日内完成注销。

4.3 设备权限调用

我们在提供服务的过程中,可能需要您开通一些设备权限,例如通知、相册、相机、定位等访问权限。您也可以在设备的【设置】功能中随时选择关闭部分或者全部权限,从而拒绝我们收集您相应的个人信息。在不同设备中,权限显示方式及关闭方式可能有所不同,具体请参考设备及系统开发方说明或政策。

五、我们发出的通知

我们可在我们认为必需时(例如当我们暂停OOCRR服务进行维修时)不时向您发出一些与服务有关的公告。

六、您个人信息的存储

我们所有获得的信息都存放于中华人民共和国境内。

七、如何更新与修改本政策

我们可能适时修改本政策的条款,该等修改构成本政策的一部分。我们会在OOCRR内,发出本《隐私政策》的更新版本或以其他适当方式提醒您相关内容的更新。

八、如何联系我们

当您对本政策有任何疑问,可以发送邮件至 phoenixtomax@gmail.com 咨询,我们将及时解决您的问题。一般情况下,我们将在5天内回复。

Emoji

03/04/18

(>﹏<)

( ̄o ̄)

→_→

(〜 ̄▽ ̄)〜

(^_^)

(●—●)

(☆_☆)

( ̄▽ ̄)

(づ ●─● )づ

~( ̄▽ ̄~)

( ̄ε(# ̄)

≥﹏≤

( ̄へ ̄)

⊙_⊙

o(≧v≦)o

(・●・)

( ̄o ̄).zZ

LRU in Python

29/03/18

LRU in Python

class LRUCache:
    def __init__(self, capacity):
        self.capacity = capacity
        self.tm = 0
        self.cache = {}
        self.lru = {}

    def get(self, key):
        if key in self.cache:
            self.lru[key] = self.tm
            self.tm += 1
            return self.cache[key]

        return -1

    def set(self, key, value):
        if len(self.cache) >= self.capacity:
            # find the LRU entry
            old_key = min(self.lru.keys(), key = lambda k:self.lru[k])
            self.cache.pop(old_key)
            self.lru.pop(old_key)
        self.cache[key] = value
        self.lru[key] = self.tm
        self.tm += 1

Here tm is the count for access (get success /set). It guarantees that the latest entry isn’t easily removed and the entry already added but seldem accessed is removed when set happens.

Profile:

LRU cache took 1.440 sec

import collections

class LRUCache:
    def __init__(self, capacity):
        self.capacity = capacity
        self.cache = collections.OrderedDict()

    def get(self, key):
        try:
            value = self.cache.pop(key)
            self.cache[key] = value
            return value
        except KeyError:
            return -1

    def set(self, key, value):
        try:
            self.cache.pop(key)
        except KeyError:
            if len(self.cache) >= self.capacity:
                self.cache.popitem(last=False)
        self.cache[key] = value

The least-used-item is in the head of OrderedDict, which is updated in get().

If there is no key when new key is during set(), firstly we check the capacity. If capacity is reached, the head of OrderedDict is poped, then the head is empty for new key.

Profile:

LRU cache took 0.096 sec

Refs: https://www.kunxi.org/blog/2014/05/lru-cache-in-python/

Python Learning

30/03/18

Python Learning

The modification of this post is still ongoing.

Class

init, open, new, del and exit

class Vehicle:
    def __init__(self):
        print "Vehicle init"
        pass

    def __open__(self):
        print "Vehicle open"
        pass

    def __new__(cls, *args, **kwargs):
        print "Vehicle new"
        return super(Vehicle, cls).__new__(cls)

    def __enter__(self):
        print "Vehicle enter"
        pass

    def __del__(self):
        print "Vehicle delete"
        pass

    def __exit__(self, exc_type, exc_val, exc_tb):
        print "Vehicle exit"
        pass

Vehicle()

if __name__ == "__main__":

    v = Vehicle()

    with Vehicle() as vv:
       pass

Outputs:

Vehicle init Vehicle delete Vehicle init Vehicle init Vehicle enter Vehicle exit Vehicle delete Vehicle delete

Iteration

enumeration

my_list = ['apple', 'banana', 'grapes', 'pear']
>>> for c, value in enumerate(my_list, 2): print(c, value)
... 
(2, 'apple')
(3, 'banana')
(4, 'grapes')
(5, 'pear')
>>> for c, value in enumerate(my_list, -1): print(c, value)
... 
(-1, 'apple')
(0, 'banana')
(1, 'grapes')
(2, 'pear')

Enumerate elements with specified index 2, -1.

Generator

def fib(max):
    n, a, b = 0, 0, 1
    while n < max:
        yield b
        a, b = b, a + b
        n = n + 1
>>> f = fib(6)
>>> f
<generator object fib at 0x104feaaa0>

Yield

def odd():
    print('step 1')
    yield 1
    print('step 2')
    yield(3)
    print('step 3')
    yield(5)
>>> o = odd()
>>> next(o)
step 1
1
>>> next(o)
step 2
3
>>> next(o)
step 3
5
>>> next(o)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration

Filter

def is_palindrome(n):
    n=str(n)
    m=n[::-1]
    return n==m

output = filter(is_palindrome, range(1, 1000))
print('1~1000:', list(output))
if list(filter(is_palindrome, range(1, 200))) == [1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 22, 33, 44, 55, 66, 77, 88, 99, 101, 111, 121, 131, 141, 151, 161, 171, 181, 191]:
    print('测试成功!')
else:
    print('测试失败!')

Python Unit Test

02/04/18

Python Unit Test

##Basic Unit Test

Test Class

  1 class Widget:
  2     name_ = "Default"
  3     size_ = set([0, 0])
  4
  5     def __init__(self, name):
  6         self.name_ = name
  7
  8     def size(self):
  9         return self.size_
 10
 11     def resize(self, height, width):
 12         self.size_ = ([height, width])
 13
 14     def dispose(self):
 15         self.name_ = "Default"
 16         self.size_ = None

Test Case

  1 import unittest
  2
  3
  4 class MyTestCase(unittest.TestCase):
  5
  6     def test_upper(self):
  7         self.assertEqual('foo'.upper(), 'FOO')
  8
  9     def test_isupper(self):
 10         self.assertTrue('FOO'.isupper())
 11         self.assertFalse('Foo'.isupper())
 12
 13     def test_split(self):
 14         s = 'hello world'
 15         self.assertEqual(s.split(), ['hello', 'world'])
 16
 17         with self.assertRaises(TypeError): # Exception
 18             s.split(2)                     # It should be exception here
 19
 20 if __name__ == '__main__':
 21     # unittest.main()
 22
 23     suite = unittest.TestLoader().loadTestsFromTestCase(MyTestCase)
 24     unittest.TextTestRunner(verbosity=2).run(suite)

Advanced Unit Test

  1 import unittest
  2 import sys
  3 import Widget
  4
  5 class WidgetTestCase(unittest.TestCase):
  6     @classmethod
  7     def setUpClass(cls):
  8         pass
  9
 10     @classmethod
 11     def tearDownClass(cls):
 12         pass
 13
 14     def setUp(self):
 15         self.widget = Widget.Widget("The widget")
 16
 17     def tearDown(self):
 18         self.widget.dispose()
 19         self.widget = None
 20
 21     def test_default_size(self):
 22         self.assertEqual(self.widget.size(), ([50, 50]),
 23                          'incorrect default size')
 24
 25     def test_resize(self):
 26         self.widget.resize(100, 150)
 27         self.assertEqual(self.widget.size(), ([100, 150]),
 28                          'wrong size after resize')
 29
 30     @unittest.skip("demostrating skipping")
 31     def test_nothing(self):
 32         pass
 33
 34     @unittest.skipUnless(sys.platform.startswith("win"), "requires Windows")
 35     def test_windows_support(self):
 36         # windows specific testing code
 37         pass
 38
 39     @unittest.expectedFailure
 40     def test_fail(self):
 41         self.assertEqual(1, 0, "broken")
 42
 43 if __name__ == '__main__':
 44
 45     """ No.1 Method """
 46     """
 47     widgetTestSuite = unittest.TestSuite()
 48     defaultSizeTestCase = WidgetTestCase('test_default_size')
 49     resizeTestCase = WidgetTestCase('test_resize')
 50
 51     widgetTestSuite.addTest(defaultSizeTestCase)
 52     widgetTestSuite.addTest(resizeTestCase)
 53     """
 54
 55     """ No.2 Method """
 56     widgetTestSuite = unittest.TestLoader().loadTestsFromTestCase(WidgetTestCase)
 57
 58     unittest.TextTestRunner(verbosity=2).run(widgetTestSuite)
 59     # unittest.main()

Made with by Álvaro