筛选一个工作簿中的所有工作表数据

筛选一个工作簿中的所有工作表数据

import xlwings as xw
import pandas as pd
app = xw.App(visible=False,add_book=False) # 启动excel
workbook = app.books.open(r’d:\python_file\采购表.xlsx’) # 打开要处理的工作簿
worksheet = workbook.sheets # 列出工作簿中的所有工作表
table = pd.DataFrame() # 创建一个空DataFrame
for i, j in enumerate(worksheet): # 遍历工作簿中的工作表
values = j.range(‘a1′).options(pd.DataFrame,header=1,index=False,expand=’table’).value # 读取当前工作表数据
data = values.reindex(columns=[‘采购物品’,’采购日期’,’采购数量’,’采购金额’]) # 调整列的顺序,将”采购物品”移到第1列
table = table.append(data,ignore_index=True) # 将调整列顺序后的数据合并到前面创建的DataFrame中
table = table.groupby(‘采购物品’) # 根据采购物品列筛选数据
new_workbook = xw.books.add() # 新建一个工作簿
for idx, group in table: # 遍历筛选好的数据,其中idx对应物品名称, group对应该物品的所有明细数据
new_worksheet = new_workbook.sheets.add(idx) # 在新工作簿中新增工作表,以物品名称作为工作表名
new_worksheet[‘a1’].options(index=False).value = group # 在新工作表中写入当前物品的所有明细数据
last_cell = new_worksheet[‘a1’].expand(‘table’).last_cell # 获取当前工作表数据区域右下角的单元格
last_row = last_cell.row # 获取数据区域*后一行行号
last_column = last_cell.column # 获取数据区域*后一列的列号
last_column_letter = chr(64 + last_column) # 将数据区域*后一列的列号(数字)转换为该列的列标(字母)
sum_cell_name = ‘{}{}’.format(last_column_letter,last_row+1) # 获取数据区域右下角单元格下方的单元格位置
sum_last_row_name = ‘{}{}’.format(last_column_letter,last_row) # 获取数据区域右下角单元格位置
formula = ‘=SUM({}2:{})’.format(last_column_letter,sum_last_row_name) # 根据前面获取的单元格位置构造excel公式,对采购金额求和
new_worksheet[sum_cell_name].formula = formula # 将求和公式写入数据区域右下解单元格下方的单元格中
new_worksheet.autofit() # 根据单元格中的数据内容自动调整工作表的行高和列宽
new_workbook.save(r’d:\python_file\采购分类表.xlsx’) # 保存新建的工作簿并命名为 “采购分类表.xlsx”
workbook.close()
app.quit()

字节面试中遇到的一道代码题

字节面试中遇到的一道代码题

题目:编写递归算法求*长连续重复的单个字符(如果是找*长重复子串的话,可以参考leetcode 1044: *长重复子串),比如”aaabbcc”的*大重复字串为”aaa”,“aab”*大重复字串为”aa”, 而类似”aba”这种则返回a,b均可,并编写测试用例。

class Solution:
def repeatTimes(self, s):
n = len(s)
if n == 0:
return None

c = {}
for i in range(n):
if s[i] not in c.keys():
c[s[i]] = 1
else:
c[s[i]] += 1
cmax = max(c.values())
for k, v in c.items():
if v == cmax:
res = k
break
return res * cmax

tests = [”, ‘a’, ‘aa’, ‘abc’, ‘aab’, ‘aba’, ‘aabb’, ‘aabbb’, ‘abcdc’]
a = Solution()
for test in tests:
b = a.repeatTimes(test)
print(b)

 

批量排序多个工作簿中的数据

批量排序多个工作簿中的数据

import time as tm
t1 = tm.time()
import os
import xlwings as xw
import pandas as pd
app = xw.App(visible=False,add_book=False)
file_path = r’d:\python_file\产品销售统计表’
file_list = os.listdir(file_path)
for i in file_list:
if os.path.splitext(i)[1] == ‘.xlsx’:
workbook = app.books.open(file_path + ‘\\’ + i)
worksheet = workbook.sheets
for j in worksheet:
values = j.range(‘A1’).expand(‘table’).options(pd.DataFrame).value
result = values.sort_values(by=’销售利润’)
j.range(‘A1’).value = result
workbook.save()
workbook.close()
app.quit()
t2 = tm.time()
print(“==========total take {0}”.format(t2 – t1,0.00))

长度为n的数组,求连续k个*大值,输出开始的下标

长度为n的数组,求连续k个*大值,输出开始的下标

阿里面试题
有n盒糖果,每盒糖果数量为a[i]。这n盒糖果从1到n的顺序顺时针方向摆成圆圈,索引为n的糖果顺时针方向下一个糖果盒索引为1,你可以选择任意一盒糖果,然后从它开始顺时针拿走连续k盒糖果,问从哪盒糖果开始拿可以拿*多的糖果,输出索引。
输入描述:
*行 两个整数 n,k(1<=k<=nM=100000)
第二行 n个整数a[i]
输出
一行一个整数,索引

##长度为n的数组,求连续k个*大值,输出开始的下标。

// An highlighted block
`import sys
x = sys.stdin.readline().strip()
m = list(map(int,x.split()))
n = m[0]
k = m[1]
x = sys.stdin.readline().strip()
m = list(map(int,x.split()))
maxtg = 0
for j in range(n):
temp = 0
for i in range(j, j+k):
z = i
if i>=n:
z=z-n
temp += m[z]
a = maxtg
maxtg = max(temp,maxtg)
if a != maxtg:
b = i
if b-k+1<0:
print(n+b-k+2)
else:
print(b-k+2)`

国内常用NTP服务器地址及IP

210.72.145.44 (国家授时中心服务器IP地址)

133.100.11.8 日本 福冈大学
time-a.nist.gov 129.6.15.28 NIST, Gaithersburg, Maryland
time-b.nist.gov 129.6.15.29 NIST, Gaithersburg, Maryland
time-a.timefreq.bldrdoc.gov 132.163.4.101 NIST, Boulder, Colorado
time-b.timefreq.bldrdoc.gov 132.163.4.102 NIST, Boulder, Colorado
time-c.timefreq.bldrdoc.gov 132.163.4.103 NIST, Boulder, Colorado
utcnist.colorado.edu 128.138.140.44 University of Colorado, Boulder
time.nist.gov 192.43.244.18 NCAR, Boulder, Colorado
time-nw.nist.gov 131.107.1.10 Microsoft, Redmond, Washington
nist1.symmetricom.com 69.25.96.13 Symmetricom, San Jose, California
nist1-dc.glassey.com 216.200.93.8 Abovenet, Virginia
nist1-ny.glassey.com 208.184.49.9 Abovenet, New York City
nist1-sj.glassey.com 207.126.98.204 Abovenet, San Jose, California
nist1.aol-ca.truetime.com 207.200.81.113 TrueTime, AOL facility, Sunnyvale, California
nist1.aol-va.truetime.com 64.236.96.53 TrueTime, AOL facility, Virginia
————————————————————————————————————
ntp.sjtu.edu.cn 202.120.2.101 (上海交通大学网络中心NTP服务器地址)
s1a.time.edu.cn 北京邮电大学
s1b.time.edu.cn 清华大学
s1c.time.edu.cn 北京大学
s1d.time.edu.cn 东南大学
s1e.time.edu.cn 清华大学
s2a.time.edu.cn 清华大学
s2b.time.edu.cn 清华大学
s2c.time.edu.cn 北京邮电大学
s2d.time.edu.cn 西南地区网络中心
s2e.time.edu.cn 西北地区网络中心
s2f.time.edu.cn 东北地区网络中心
s2g.time.edu.cn 华东南地区网络中心
s2h.time.edu.cn 四川大学网络管理中心
s2j.time.edu.cn 大连理工大学网络中心
s2k.time.edu.cn CERNET桂林主节点
s2m.time.edu.cn 北京大学

质因子分解 Python

质因子分解 Python

质因子分解 P y t h o n Python Python
要做质因子分解,首先需要明白什么是质数,以及如何快速判断质数。

质数
质数,也称素数,是只能被1和其本身整除的数,规定1不是质数。

质数的判断可以详见我另一篇博客 判断质数 Python Java C++

def isPrime(n: int) -> bool:
if n <= 3:
return n >= 2
if (n + 1) % 6 != 0 and (n – 1) % 6 != 0:
return False
for i in range(2, int(n ** 0.5) + 1):
if n % i == 0:
return False
return True

质因子分解
质因子分解,故名思意,将一个数分解成所有因子都是质数。

首先判断待分解这个数本身是不是质数,如果他本身就是一个质数的话,那他的质因子就是他自己,因为1不是质数。

如果不是质数,就从2开始,往上一个个质数除。如果可以整除这个质数,那么这个质数就是其一个因子。保存这个质数到一个列表中,再将待分解的数整除这个质数,继续分解即可。

质数列表,可以用列表生成式[i for i in range(2, 10) if isPrime(i)]生成一个质数列表,这个刚开始生成几个就够了,如果数量不够的话,再补充。如果刚开始数量就大的话,复杂度会比较大,大部分数不需要这么大,真用到了,后边再补充就行

if i >= len(primes) – 1:
primes += [i for i in range(i + 1, i + 1000) if isPrime(i)]

完整代码
# 判断是否是质数
def isPrime(n: int) -> bool:
if n <= 3:
return n >= 2
if (n + 1) % 6 != 0 and (n – 1) % 6 != 0:
return False
for i in range(2, int(n ** 0.5) + 1):
if n % i == 0:
return False
return True

# 质因子分解
def factor(n: int) -> list[int]:
ans = []
if isPrime(n): # 判断本身是否是质数
ans.append(n)
return ans
primes = [i for i in range(2, 10) if isPrime(i)] # 生成待循环整除的质数列表
i = 0 # 初始化下标
while not isPrime(n):
if n % primes[i] == 0: # 判断待分解的数是否可以整除这个质数,若能,则这个质数是其一个因子
ans.append(primes[i]) # 保存质因子到列表中
n //= primes[i] # 待分解数整除该质数
i = 0 # 重置质数列表下标(重新从2,3,5…开始判断整除)
else:
i += 1 # 如果不能整除,则下标后移,判断下一个质数是否能整除
if i >= len(primes) – 1: # 如果质数列表的长度不够,就扩充一部分,如果遇到数组超限,就加大1000这个判断区间值
primes += [i for i in range(i + 1, i + 1000) if isPrime(i)]
ans.append(n) # 保存n,由于while循环判断,此时n是*后一个质数
return ans

print(factor(2021041820210418)) #输入待分解的数,即可输出质因子列表

ntp服务器是什么,有什么用?

ntp服务器隶属于小众时间频率行业,对于初次接触者和未涉猎此行业的人群来说,就会有很大的疑问:ntp服务器能做什么,为什么会需要ntp服务器?

本文主要通过这两个问题,对ntp服务器进行分总式的说明,希望更多的人能认识ntp服务器,了解ntp服务器,并意识到随着科学技术发展ntp服务器对人文生活,科技发展的重要性和不可或缺性。

ntp服务器是什么,有什么用?

1、什么是ntp服务器?

ntp服务器,对大多数人来说是一个一穷二白的陌生词汇,但是要理解ntp服务器必须先了解什么是ntp和什么是服务器?

1)什么是ntp?

NTP全名“Network TimeProtocol”,即网络时间协议,是由RFC 1305定义的时间同步协议,用来在分布式时间服务器和客户端之间进行时间同步。

NTP基于UDP报文进行传输,使用的UDP端口号为123。使用NTP的目的是对网络内所有具有时钟的设备进行时钟同步,使网络内所有设备的时钟保持一致,从而使设备能够提供基于统一时间的多种应用。对于运行NTP的本地系统,既可以接收来自其他时钟源的同步,又可以作为时钟源同步其他的时钟,并且可以和其他设备互相同步。

2)什么是服务器?

服务器,英文名“server”也称伺服器,是提供计算服务的设备。由于服务器需要响应服务请求,并进行处理,因此一般来说服务器应具备承担服务并且保障服务的能力。

服务器的构成包括处理器、硬盘、内存、系统总线等,和通用的计算机架构类似,但是由于需要提供高可靠的服务,因此在处理能力、稳定性、可靠性、安全性、可扩展性、可管理性等方面要求较高。

在网络环境下,根据服务器提供的服务类型不同,分为文件服务器,数据库服务器,应用程序服务器,WEB服务器等。

3)什么是NTP服务器?

前面我们分别了解到了NTP和服务器,那到底是什么NTP服务器呢?根据表面意思理解NTP服务器,即基于NTP协议的服务器,用来在分布式时间服务器和客户端之间进行时间同步。

NTP服务器在应用于时间同步中分为客户端NTP服务器和服务端NTP服务器两种。客户端主要应用于现有NTP网络环境中,获取前端NTP服务器,主要是利用已经存在的网络环境,搭建时间同步系统,实现的是一个从时钟的功能。服务端NTP服务器主要是指用于后端网络环境中设备的时间同步,为网络中的服务器,计算机等网络设备提供一个时间统一的功能,实现主时钟的同步功能。

2、ntp服务器能做什么?

前面,我们很自然的了解到了什么是ntp,也有了一个大概的认识,那么ntp服务器是做什么的,它到底能做什么,这也是我们对于ntp服务器这个名称属性放在这里,我们*需要传达的东西。

NTP服务器主要用来同步网络中各个计算机的时间的协议。它的用途是把计算机的时钟同步到世界协调时UTC,其精度在局域网内可达0.1ms,在互联网上*大多数的地方其精度可以达到1-50ms。它可以使计算机对其服务器或时钟源(如石英钟,GPS等等)进行时间同步,它可以提供高精准度的时间校正,而且可以使用加密确认的方式来防止病毒的协议攻击。

很多人可能会说,我的计算机每天自己走时,为何还需要用一个ntp服务器再同步时间呢?这主要是因为在计算机中芯片本身通常并不具备时钟信号源,因此须由专门的时钟电路提供时钟信号,石英晶体振荡器(Quartz Crystal OSC)就是一种*常用的时钟信号振荡源。石英晶片之所以能当为振荡器使用,是基于它的压电效应:在晶片的两个*上加一电场,会使晶体产生机械变形;在石英晶片上加上交变电压,晶体就会产生机械振动,同时机械变形振动又会产生交变电场。虽然这种交变电场的电压*其微弱,但其振动频率是十分稳定的。

从PC诞生至今,主板上一直都使用一颗14.318MHz的石英晶体振荡器作为基准频率源。主板上除了这颗14.318MHz的晶振,还能找到一颗频率为32.768MHz的晶振,它被用于实时时钟(RTC)电路中,显示精确的时间和日期。初始化后以每秒约18.2次发出脉冲,这些脉冲经过操作系统计算形成BIOS日时钟计数。通过由BIOS电池供电,关机后它仍然正常运行。这也就是为啥我们关了电源,第二天开机依然会显示正确时间的原因。

每个计算机各自有了时钟,但是一旦它们联网后,又出现一个问题:各自运行的计算机时钟,彼此之间日积月累的累计误差如何解决。这就出现了网络时间协议NTP,它是用于互联网中时间同步的标准之一,它的用途是把计算机的时钟同步到世界协调时UTC,并满足于用户环境中的计算机(服务器同理)设备的时间同步。

3、为什么要使用ntp服务器?

对大多数人来说可能会很疑问,我的计算机时间已经够我用了啊,我为何需要单独的ntp服务器。那么问题来了,一个系统里整体运行的所有计算机服务器,如果都独立运行那整个系统工作是否都乱套了?

我们举几个简单的例子:如果公共大楼遇到突发事情每个监控装置时间不一,后期事故调查取证监控时间参差不齐无法还原本质,责任谁来担当?医院系统各个科室职能兼受,若时间相互差开,病人数据记录与实际时间前后出入,若出现分歧责任甩给设备原因,设备是否能够出面来协调?电力电厂系统中有很多需要互相协调合作的设备,若出现各个系统设备之间时间紊乱,就会导致运行机制无法协调合作,那整个电厂的运行失调,所造成的损失无法估量。

所以,ntp服务器在各行各业系统发挥协调作用的同时,已经成为了不可或缺的必备系统,是各个系统稳定运行基于安全因素中必须存在的重要设备。ntp服务器服务器应用于不同行业系统中,为网络内设备提供标准的时间基准,使得各个独立又相互关联的设备有了可参考的维度标准。

随着科技电子产业的发展,ntp服务器在社会国家发展中具有必然存在的重要性。在不同行业,不同领域中由于系统环境的要求对ntp服务器的配置也不尽相同。

Android技术迭代更新,到底什么是AndroidX?

Android技术迭代更新很快,各种新出的技术和名词也是层出不穷。不知从什么时候开始,总是会时不时听到AndroidX这个名词,这难道又是什么新出技术吗?相信有很多朋友也会存在这样的疑惑,那么今天我就来写一篇科普文章,向大家介绍AndroidX的前世今生。

%title插图%num
Android系统在刚刚面世的时候,可能连它的设计者也没有想到它会如此成功,因此也不可能在一开始的时候就将它的API考虑的非常周全。随着Android系统版本不断地迭代更新,每个版本中都会加入很多新的API进去,但是新增的API在老版系统中并不存在,因此这就出现了一个向下兼容的问题。

举个例子,当Android系统发布到3.0版本的时候,突然意识到了平板电脑的重要性,因此为了让Android可以更好地兼容平板,Android团队在3.0系统(API 11)中加入了Fragment功能。但是Fragment的作用并不只局限于平板,以前的老系统中也想使用这个功能该怎么办?于是Android团队推出了一个鼎鼎大名的Android Support Library,用于提供向下兼容的功能。比如我们每个人都熟知的support-v4库,appcompat-v7库都是属于Android Support Library的,这两个库相信任何做过Android开发的人都使用过。

但是可能很多人并没有考虑过support-v4库的名字到底是什么意思,这里跟大家解释一下。4在这里指的是Android API版本号,对应的系统版本是1.6。那么support-v4的意思就是这个库中提供的API会向下兼容到Android 1.6系统。它对应的包名如下:

%title插图%num
类似地,appcompat-v7指的是将库中提供的API向下兼容至API 7,也就是Android 2.1系统。它对应的包名如下:

%title插图%num
可以发现,Android Support Library中提供的库,它们的包名都是以android.support.*开头的。

但是慢慢随着时间的推移,什么1.6、2.1系统早就已经被淘汰了,现在Android官方支持的*低系统版本已经是4.0.1,对应的API版本号是15。support-v4、appcompat-v7库也不再支持那么久远的系统了,但是它们的名字却一直保留了下来,虽然它们现在的实际作用已经对不上当初命名的原因了。

那么很明显,Android团队也意识到这种命名已经非常不合适了,于是对这些API的架构进行了一次重新的划分,推出了AndroidX。因此,AndroidX本质上其实就是对Android Support Library进行的一次升级,升级内容主要在于以下两个方面。

*,包名。之前Android Support Library中的API,它们的包名都是在android.support.*下面的,而AndroidX库中所有API的包名都变成了在androidx.*下面。这是一个很大的变化,意味着以后凡是android.*包下面的API都是随着Android操作系统发布的,而androidx.*包下面的API都是随着扩展库发布的,这些API基本不会依赖于操作系统的具体版本。

第二,命名规则。吸取了之前命名规则的弊端,AndroidX所有库的命名规则里都不会再包含具体操作系统API的版本号了。比如,像appcompat-v7库,在AndroidX中就变成了appcompat库。

一个AndroidX完整的依赖库格式如下所示:

implementation ‘androidx.appcompat:appcompat:1.0.2’
1
了解了AndroidX是什么之后,现在你应该放轻松了吧?它其实并不是什么全新的东西,而是对Android Support Library的一次升级。因此,AndroidX上手起来也没有任何困难的地方,比如之前你经常使用的RecyclerView、ViewPager等等库,在AndroidX中都会有一个对应的版本,只要改一下包名就可以完全无缝使用,用法方面基本上都没有任何的变化。

但是有一点需要注意,AndroidX和Android Support Library中的库是非常不建议混合在一起使用的,因为它们可能会产生很多不兼容的问题。*好的做法是,要么全部使用AndroidX中的库,要么全部使用Android Support Library中的库。

而现在Android团队官方的态度也很明确,未来都会为AndroidX为主,Android Support Library已经不再建议使用,并会慢慢停止维护。另外,从Android Studio 3.4.2开始,我发现新建的项目已经强制勾选使用AndroidX架构了。

%title插图%num
那么对于老项目的迁移应该怎么办呢?由于涉及到了包名的改动,如果从Android Support Library升级到AndroidX需要手动去改每一个文件的包名,那可真得要改死了。为此,Android Studio提供了一个一键迁移的功能,只需要对着你的项目名右击 → Refactor → Migrate to AndroidX,就会弹出如下图所示的窗口。

%title插图%num
这里点击Migrate,Android Studio就会自动检查你项目中所有使用Android Support Library的地方,并将它们全部改成AndroidX中对应的库。另外Android Studio还会将你原来的项目备份成一个zip文件,这样即使迁移之后的代码出现了问题你还可以随时还原回之前的代码。

好了,关于AndroidX的内容就讲到这里,相信也是解决了不少朋友心中的疑惑。由于这段时间以来一直在努力赶《*行代码 第3版》的进度,所以原创文章的数量偏少了一些,也请大家见谅。