如果每次打开终端都提示:
The default interactive shell is now zsh.
To update your account to use zsh, please run chsh -s /bin/zsh
.
原因是原本使用的是bash风格,提示语告知现在新系统的shell已经更换为zsh,请用此 chsh -s /bin/zsh
命令切换。
解决办法:
(1) 不使用bash,切换zsh,chsh -s /bin/zsh
命令切换即可。
(2) 继续使用bash,但又不想出现提示语,则打开文件:
.bash_profile文件最下方加上:
macOS Catalina
然后保存退出
一、根据步骤,当运行source .bash_profile 报错:
/usr/bin/python: No module named virtualenvwrapper
virtualenvwrapper.sh: There was a problem running the initialization hooks.
If Python could not import the module virtualenvwrapper.hook_loader,
check that virtualenvwrapper has been installed for
VIRTUALENVWRAPPER_PYTHON=/usr/bin/python and that PATH is
set properly.
错误原因:Mac安装了2.7和3.x两个版本的python,在安装时使用的是sudo pip3 install virtualenvwrapper
运行的时候默认使用的是python2.x,但在python2.x中不存在对应的模块。(virtualenvwrapper.sh文件内容如下:):
当不存在VIRTUALENVWRAPPER_PYTHON环境时,会默认选择使用which python(我这里默认是python2),
所以需要将which python 改为 which python3 环境:
二、首先讲一下问题原因:zsh的配置文件.zshrc 没有配置相关环境变量设置
没有这个文件可以创建一个出来
1、需要将bash 中.bash_profile 环境变量加入zshrc
2、添加
3、执行下面命令后,问题解决。
Original: https://blog.51cto.com/u_15722381/5483117
Author: ch3nnn
Title: 解决Mac更新安装zsh后出现Python虚拟环境的问题
相关阅读1
Title: Tkinter制作股票数据抓取小程序,有点秀!
在前面的文章中,我们一起学习了如何通过 Python 抓取东方财富网的实时股票数据,链接如下
今天我们就在这个基础上,实现一个 Tkinter GUI 程序,完成无代码股票抓取!
首先对于 Tkinter 相信大家都是比较了解的,如果有小伙伴对于 Tkinter 的相关用法不是特别熟悉的话,可以看如下文章
首先我们先看一下 GUI 程序的最终效果
该程序共分三个区域:
- 个股查询:用于查询某只股票的数据,可以查询1天或者多天数据
- 批量查询:查询某个交易所所有股票的数据
- 日志区域:打印抓取信息
下面我们就来看看该如何从头完成这个 GUI 程序
程序布局
首先就是程序布局,这里我们使用了 ​ttkbootstrap​
库来美化整体程序
程序初始化部分
import ttkbootstrap as ttkfrom ttkbootstrap.constants import *import tkinter.messagebox as messboxclass MainCreator(ttk.Window): def __init__(self): super().__init__("股票抓取工具", themename="solar", resizable=(False, False)) self.configure_frame = ttk.Frame(self, padding=(10, 10, 5, 10)) self.configure_frame.pack(side=LEFT, fill=BOTH, expand=YES) self.demo_frame = ttk.Frame(self, padding=(5, 10, 10, 10)) self.demo_frame.pack(side=LEFT, fill=BOTH, expand=YES)
程序布局部分
def create_frame(self): """Create all the frame widgets""" container = ttk.Frame(self) container.pack(side=LEFT, fill=BOTH, expand=YES, padx=5) color_group = ttk.Labelframe( master=container, text="个股查询", padding=10 ) color_group.pack(fill=X, side=TOP) en_command = super().register(self.en_validate) self.en0 = ttk.Entry(color_group, width=5, text='', bootstyle='warning', validate='key', validatecommand=(en_command, '%P')) self.en0.insert('0', 1) self.en0.config(state=DISABLED) ...
总体上来说,我们所有的组件都是从 ttk 当中实例化的,也就是直接复用了库 ​ttkbootstrap​
的相关美化功能,使得我们的程序看起来更加高级美观
抓取与保存功能
下面我们编写股票抓取代码和对应的保存代码
股票抓取
def get_A_mins(code): if code.startswith("3") or code.startswith("0"): url = shang_A_url.replace("%s", code) elif code.startswith("6"): url = shen_A_url.replace("%s", code) else: return False res = requests.get(url) result = res.text.split("cb_1659146437934_51841953")[1].split("(")[1].split(");")[0] result_json = json.loads(result) stock_data = result_json['data'] return stock_datadef get_A_days(code): if code.startswith("3") or code.startswith("0"): url = shang_A_days.replace("%s", code) elif code.startswith("6"): url = shen_A_days.replace("%s", code) else: return False res = requests.get(url) result = res.text.split("cb_1659171393020_15037673")[1].split("(")[1].split(");")[0] result_json = json.loads(result) stock_data = result_json['data'] return stock_datadef get_hsj(date): total_data = [] try: for i in range(1, 5): res = requests.get(hsj_url.replace("%s", str(i))) result = res.text.split("jQuery112402508937289440778_1658838703304")[1].split("(")[1].split(");")[0] result_json = json.loads(result) stock_data = result_json['data'] if stock_data: total_data.append(stock_data) saveFunc.save_data_hsj(stock_data['diff'], date) else: return total_data return total_data except Exception as e: return Falsedef get_Center(): total_data = [] for i in range(1, 20): res = requests.get(center_url.replace("%s", str(i))) result = res.text.split("jQuery112404177389105264733_1659176039486")[1].split("(")[1].split(");")[0] result_json = json.loads(result) center_data = result_json['data'] if center_data: total_data.append(center_data) else: return total_datadef get_shang_A(): passdef get_shen_A(): passdef get_bei_A(): pass
股票代码分为上交所,深交所和北交所以及大盘行情数据,所以我们分别编写函数进行处理
数据保存
import osdef save_data_mins(data, date): Code = data['code'] Name = data['name'] if not os.path.exists(r"stock_data_%s_%s_%s_mins.csv" % (Code, Name, date)): with open("stock_data_%s_%s_%s_mins.csv" % (Code, Name, date), "a+", encoding='utf-8') as f: f.write("时间,最新价,成交量(手),成交额\n") for i in data['trends']: i_list = i.split(",") time = i_list[0] price = i_list[2] mount = i_list[5] count = i_list[6] row = '{},{},{},{}'.format( time,price,mount,count) f.write(row) f.write('\n') else: ...def save_data_days(data, days): print(days) Code = data['code'] Name = data['name'] if not os.path.exists(r"stock_data_%s_%s_days.csv" % (Code, Name)): with open("stock_data_%s_%s_days.csv" % (Code, Name), "a+", encoding='utf-8') as f: f.write("时间,开盘价,收盘价,最高价,最低价,成交量(手),成交额,振幅,涨跌幅,涨跌额,换手率\n") for i in data["klines"][::-1][:int(days)]: i_list = i.split(",") time = i_list[0] Open = i_list[1] close = i_list[2] heigh = i_list[3] low = i_list[4] mount = i_list[5] count = i_list[6] amplitude = i_list[7] changePercent = i_list[8] change = i_list[9] turnoverRate = i_list[10] row = '{},{},{},{},{},{},{},{},{},{},{}'.format( time,Open,close,heigh,low,mount,count,amplitude,changePercent,change,turnoverRate) f.write(row) f.write('\n') else: ...def save_data_hsj(data, date): if not os.path.exists(r'stock_data_%s.csv' % date): with open("stock_data_%s.csv" % date, "a+", encoding='utf-8') as f: f.write("股票代码,股票名称,最新价,涨跌幅,涨跌额,成交量(手),成交额,振幅,换手率,市盈率,量比,最高,最低,今开,昨收,市净率\n") for i in data: Code = i["f12"] Name = i["f14"] Close = i['f2'] ChangePercent = i["f3"] Change = i['f4'] Volume = i['f5'] Amount = i['f6'] Amplitude = i['f7'] TurnoverRate = i['f8'] PERation = i['f9'] VolumeRate = i['f10'] Hign = i['f15'] Low = i['f16'] Open = i['f17'] PreviousClose = i['f18'] PB = i['f22'] row = '{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{}'.format( Code,Name,Close,ChangePercent,Change,Volume,Amount,Amplitude, TurnoverRate,PERation,VolumeRate,Hign,Low,Open,PreviousClose,PB) f.write(row) f.write('\n') else: ...def save_data_center(): passdef save_data_shang_A(): pass
添加功能
接下来就是为布局好的 GUI 程序添加各种响应功能
个股查询按钮
为个股查询的 ​抓取​
按钮绑定方法 ​catch​
self.bt = ttk.Button(color_group, text='抓取', bootstyle='success', command=self.catch)
方法 ​catch​
的定义如下
def catch(self): self.txt.yview_moveto(1) now = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') day = datetime.datetime.now().strftime('%Y-%m-%d') if self.cbvar.get() == 1: catch_day = self.en0.get() if self.en.get(): code = self.en.get() result = catchFunc.get_A_days(code) if result: saveFunc.save_data_days(result, catch_day) self.txt.insert(ttk.INSERT, "抓取股票%s成功 %s" % (code, now)) self.txt.insert(ttk.INSERT, "\n") self.txt.update() self.txt.yview_moveto(1) else: print("股票代码错误") messbox.showerror("股票代码错误", "请输入正确的股票代码!") else: print("请输入股票代码") messbox.showerror("股票代码为空", "请输入股票代码!") else: ...
批量查询开关
对于批量查询,我们是通过一个多选框开关控制的
self.cb_batch = ttk.Checkbutton(cr_group, text="开启批量", variable=self.cbvar1, command=self.cb_button)
绑定的方法如下
def cb_button(self): if self.cbvar1.get() == 1: self.bt_batch.config(state=NORMAL) else: self.bt_batch.config(state=DISABLED)
以上就是程序的部分代码,让我们看一下整体效果吧
好了,以上就是今天分享的全部内容,喜欢就点个赞吧~
文章点赞+在看,私聊获取完整代码
Original: https://blog.51cto.com/u_10487107/5559087
Author: 周萝卜123
Title: Tkinter制作股票数据抓取小程序,有点秀!
相关阅读2
Title: 刚刚发现的可视化动态图库ipyvizzu,太好看了
ipyvizzu生成的可视化图形是动态的,以前我们生成的可视化图形都是静态不动的。
它是python中的非标准库ipyvizzu,因此使用pip的方式额外安装一下。
pip install ipyvizzu
1、小试牛刀
首先,导入绘图相关的库ipyvizzu,以及pandas用来做数据导入操作。
import pandas as pd
from ipyvizzu import Chart, Data, Config
将csv文件中的数据读取出来,返回的数据格式是DataFrame数据。
data_frame = pd.read_csv("titanic.csv")
导入数据以后,就使用ipyvizzu提供的Data数据模块加载当前的数据。
data = Data()
data.add_data_frame(data_frame)
实例化ipyvizzu的图表对象,使用图表对象加载data对象中的数据作为图表数据。
chart = Chart()
chart.animate(data)
接下来我们开始绘制图表,需要指定好的是图表的一些属性,例如直方图的话就是X轴Y轴该放置什么样的数据,颜色选择是默认的还是需要另外指定的,以及标题等等。
chart.animate(Config({"x": "Count", "y": "Sex", "label": "Count","title":"Passengers of the Titanic"}))
看一下的图片的效果演示,此时,一张静态的数据可视化图就制作完成了。
2、大开眼界
根据第一个步骤中绘制的可视化图形,发现上面绘制的图形它是一个静态的数据图。我们既然说ipyvizzu是一个动态的可视化数据展示,那是怎么整的呢?
动态可视化,他主要是依赖于chart.animate函数来实现的,这个时候改变了x轴/y轴/标题等属性,每个chart.animate函数都生成一张静态图片,生成多个静态图片之间的转换自然就形成了动态的效果。
比如在上述的第一个小试牛刀的部分在加上下面的代码块就相当于又生成了一张静态的数据图片。
chart.animate(Config({"x": ["Count","Survived"], "label": ["Count","Survived"], "color": "Survived"}))
整合在一起就有动态可视化图形的效果,可以看一下下面的可视化图形。
3、渐入佳境
根据上述代码块得出的经验,只需要控制chart.animate函数生成静态图片的个数,那么就能控制动动态可视化图形的动态转化次数。
将这个过程整合一下就是下面的代码块,效果是不是杠杠的。
import pandas as pd
from ipyvizzu import Chart, Data, Config
data_frame = pd.read_csv("titanic.csv")
data = Data()
data.add_data_frame(data_frame)
chart = Chart()
chart.animate(data)
chart.animate(Config({"x": "Count", "y": "Sex", "label": "Count","title":"Passengers of the Titanic"}))
chart.animate(Config({"x": ["Count","Survived"], "label": ["Count","Survived"], "color": "Survived"}))
chart.animate(Config({"x": "Count", "y": ["Sex","Survived"]}))
使用chart.animate函数总共变换了三次数据坐标及属性的设置,下面看看效果吧!
最后,备注一下官网的地址,里面的例子example数不胜数,有兴趣的大佬可以了解一下啦~
https://vizzuhq.github.io/ipyvizzu/examples/examples.html
感谢各位看官老爷的捧场,今天的看点就到这里啦,下期再会!
【往期精选】
记住这些windows网络操作命令,轻松搞定自己的电脑网络!
word文档样式批量处理,久违了!
python 如何在多层循环中使用break/continue!
用python为心爱的人制作520照片墙,已成功做出效果图!
两个库搞定python中引用javascript代码块/文件...
Original: https://www.cnblogs.com/lwsbc/p/16344414.html
Author: Python集中营
Title: 刚刚发现的可视化动态图库ipyvizzu,太好看了
相关阅读3
Title: 打造一体化制氢项目,阳光氢能以时序数据库实现生产流程的实时监控
::: hljs-center
:::
小 T 导读:为了更好地支持阳光氢能 PEM 绿电制氢系统,本文作者所在的部门需要寻找一套满足业务和性能需求、而且具有国产知识产权的时序数据库,来替代原本使用的 InfluxDB。本文分享了他们将 InfluxDB 替换为 TDengine 的具体原因,以及相关的实践思路。
企业简介
阳光电源成立于 1997 年,专注于逆变器的自主研发与制造。经过二十多年的技术积累,集团逐渐确立在光伏逆变器领域的龙头地位,打造了风、光、储、氢的新能源完整格局,做到传统业务和创新业务双管齐下、协同发展。
项目介绍
在碳中和这个大背景下,氢能是新能源领域中与油气行业现有业务结合最紧密的一类,也是帮助油气行业早日实现碳达峰、碳中和的最佳路径之一。2022 年 7 月 16 日,阳光氢能 200Nm³/h PEM 绿电制氢系统启运发货。该套系统采用国内领先的 PEM 电解水制氢技术和 IGBT 制氢电源,工艺复杂,涉及多项国内专利技术。为了更好地监测整体生产流程数据,我们需要寻找一套满足业务和性能需求,而且具有国产知识产权的时序数据库(Time Series Database),以响应国家信创号召。图片
时序数据库选型之 InfluxDB vs TDengine
在 InfluxDB 和 TDengine 之间,之所以选择 TDengine ,其实我很早之前就写过一篇文章,题目是《从 InfluxDB 到 TDengine,我们为什么会做出这个选择》,在其中表述的比较清楚了。这里可以再简单总结一下:
第一,TDengine 超级表和普通表的概念非常契合我们项目的业务场景。此前我们的项目是一个站点一个单元对应多个测点,现在利用超级表-普通表的模型,业务模型会更加清晰。
第二,查询更具有优势。在使用老版 InfluxDB 的历史数据查询功能时,只要操作稍微频繁一点(比如选择一个时间段之后,曲线很久还没有渲染出来,又去换了一个时间段),就会导致页面卡死,取不到数据,这时候需要重启浏览器,极度影响客户体验。 ::: hljs-center
::: 但是在使用 TDengine 之后,不论是大批量拉取范围数据,还是使用函数计算,查询再也没有出现过浏览器卡死的情况。TDengine 拉取单设备大范围时间数据查询的 SQL 以及耗时情况,如以下截图如下: ::: hljs-center
::: ::: hljs-center
::: 不得不说,这些查询的性能都十分出色,完全满足我们的应用场景。
第三,搭建集群的成本更低廉。众所周知,InfluxDB 集群功能是闭源的,如果后续业务发展需要用到集群时会带来很大的不便。然而 TDengine 的集群功能是开源的,且扩展方便,因此可以显著降低运维成本。
最后,从用户支持的角度来说,选用国外的 Database 有很大的不确定性,但在使用 TDengine 时如果需要支持,就可以直接通过微信/邮箱等工具随时和技术人员进行交流,更加有效方便。如果对产品性能功能、业务保障要求高的话,就可以随时升级到企业级的服务。
TDengine 落地实践
在我们的这套系统中应用的 TDengine 版本为 2.4.0.0,主要用于存储大量设备产生的时序数据,我们整个项目的智能化都是基于这些数据展开。采集设备主要为碱液循环泵、脱氧塔、纯水机、电解槽等制氢设备。
该套制氢系统除 PEM 制氢优势外,还具有智能化程度高的特点,采用的智能控制算法与可再生能源波动、间歇性特点相契合,兼具高效、经济、安全、智能等优势,适用于制、储、加一体化制氢项目。在这个过程中,我们会对 TDengine 存储的设备数据进行分析计算,最后通过大屏展示以达到实时监控、分析等需求。 ::: hljs-center
::: 整个业务架构大致如下:以我们自己编写的 mosbusTCP 驱动,结合数采硬件设备采集设备数据,然后通过 JDBC-RESTful 的方式将数据写入 TDengine。数据采集点总共有 9000 多个,频率为大概每秒写入一次。 ::: hljs-center
::: 目前单列模型下,最大的超级表已经保留了几百亿行的的数据,当前磁盘占用 55GB 左右的空间,压缩比大概在 10-15% 之间。 ::: hljs-center
::: ::: hljs-center
:::
经验分享
值得一提的是,TDengine 是根据表来做数据分片的,vnode 就是最小单位,在这种情况下,保证数据量均衡的前提是写入量均匀,否则如果某些设备过热,某些设备过冷,就会出现某个 vnode 极大,某个 vnode 极小的情况。
这一点在建表之初是需要考虑的,防止时间过久后,数据过于倾斜。具体调整方式可以参考这篇文章。比如,如果初期的设备热度比较高的话,就可以调小 minTablesPerVnode,在第一波建表时便把表均匀开到不同 vnode 里,这样可以针对性地利用起每个 vnode 有独立写入线程的特点,充分利用计算资源。(上文中的 vnode 截图并不是我的写入不均匀,只是单纯的新建表不久还没有写入太多数据。)
此外,在我们的使用过程中,也有遇到过一些问题。比如使用超级表的 select * 查询时,时间跨度比较久的数据返回会有些慢,这跟当前版本的架构有关,一个该类查询会生成多个子查询,每个 vnode 的子查询是在服务端串形处理的,即在一个 vnode 中检索查询完毕后再查下一个,最后汇总。解决方案是把时间段拆开成多段,使用多线程来查询。根据 TDengine 的规划,在后续的 3.x 版本中,此类查询将会和聚合查询一样变成并行处理,查询效率会大大提升。而其他问题多为配置部署相关,仔细阅读文档,都可以得到很好的解决。
对于 TDengine 在现有业务体系下的表现,我们还比较满意,后面也会尝试探索更多的合作可能,不断为客户创造价值,以技术驱动绿氢产业发展。
Original: https://blog.51cto.com/tdengine/5625277
Author: TDengine
Title: 打造一体化制氢项目,阳光氢能以时序数据库实现生产流程的实时监控