给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。
如果你最多只允许完成一笔交易(即买入和卖出一支股票),设计一个算法来计算你所能获取的最大利润。
注意你不能在买入股票前卖出股票。
示例 1:
输入: [7,1,5,3,6,4]
输出: 5
解释: 在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。
注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格。
示例 2:
输入: [7,6,4,3,1]
输出: 0
解释: 在这种情况下, 没有交易完成, 所以最大利润为 0。
# @author:leacoder
# @des: 动态规划 买卖股票的最佳时机 II (通用型)
class Solution:
def maxProfit(self, prices: List[int]) -> int:
if not prices: return 0
result = 0
# 二维数组
# profit[i][0] 第i天 一直没有股票 的利润
# profit[i][1] 第i天 当前有股票( 前面有股票今天不卖 + 前面没股票 今天买入 ) 的利润
# profit[i][2] 第i天 之前买入现在卖了 (前面有股票 今天卖出 ) 的利润
profit = [[0 for _ in range(3)] for _ in range(len(prices))]
# 第一天利润初始
profit[0][0],profit[0][1],profit[0][2] = 0, - prices[0] , 0
for i in range(1,len(prices)):
profit[i][0] = profit[i - 1][0]
profit[i][1] = max(profit[i - 1][1],profit[i - 1][0] - prices[i] )
profit[i][2] = profit[i - 1][1] + prices[i]
result = max(result,profit[i][0],profit[i][1],profit[i][2])
return result
# @author:leacoder
# @des: 一次遍历 买卖股票的最佳时机 II
# 由于一次交易操作 故可以通过记录最小价格 计算最大利润的方式
class Solution:
def maxProfit(self, prices: List[int]) -> int:
if not prices: return 0
minprice,maxprofit = float("inf"),0
for i in range(len(prices)):
minprice = min(minprice,prices[i]) # 记录当前最小
maxprofit = max(maxprofit,prices[i] - minprice) # 计算 当前最大利润(之前最大利润 与 当前价格与之前最小价格之差 的最大值)
return maxprofit
GitHub链接: https://github.com/lichangke/LeetCode
个人Blog: https://lichangke.github.io/
欢迎大家来一起交流学习
开发系统: Ubuntu 16.0.4 LTS 开发IDE: Visual Studio Code 版本: 1.32.3 Python版本: Python3 依赖: Django 2.2
链接:https://pan.baidu.com/s/1USkqvL2dLU3Q9XplVaGQJg 提取码:zoyc
https://github.com/lichangke/Python3_Project/tree/master/learning_log
https://www.jianshu.com/p/b3267d16c245
Web应用程序的核心是让任何用户都能够注册账户并能够使用它。将创建一些表单, 让用户能够添加主题和条目, 以及编辑既有的条目。
然后, 将实现一个用户身份验证系统。 你将创建一个注册页面, 供用户创建账户, 并让有些页面只能供已登录的用户访问。 接下来, 将修改一些视图函数,使得用户只能看到自己的数据。
阶段代码:GitHub [learning_log_2.1让用户能够输入数据](https://github.com/lichangke/Python3_Project/tree/master/learning_log/learning_log_2.1%E8%AE%A9%E7%94%A8%E6%88%B7%E8%83%BD%E5%A4%9F%E8%BE%93%E5%85%A5%E6%95%B0%E6%8D%AE)
不包括虚拟环境ll_env文件夹下文件
建立用于创建用户账户的身份验证系统之前, 先来添加几个页面, 让用户能够输入数据。 将让用户能够添加新主题、 添加新条目以及编辑既有条目。
urls -> views -> html
首先来让用户能够添加新主题。 创建基于表单的页面的方法几乎与前面创建网页一样: 定义一个URL, 编写一个视图函数并编写一个模板。 一个主要差别是, 需要导入包含表单的模块forms.py。
1. 用于添加主题的表单
让用户输入并提交信息的页面都是表单, 那怕它看起来不像表单。 用户输入信息时, 需要进行验证, 确认提供的信息是正确的数据类型。然后, 再对这些有效信息进行处理, 并将其保存到数据库的合适地方。 这些工作很多都是由Django自动完成的。
创建一个名为forms.py的文件, 将其存储到models.py所在的目录中
models.py
from django import forms
from .models import Topic
# 让用户输入并提交信息的页面都是表单, 那怕它看起来不像表单。
# 创建表单的最简单方式是使用ModelForm, 它根据在模型中的信息自动创建表单。
class TopicForm(forms.ModelForm): # 定义了一个名为TopicForm 的类, 它继承了forms.ModelForm 。
class Meta:
model = Topic # 根据模型Topic 创建一个表单
fields = ['text'] # 该表单只包含字段text
labels = {'text': ''} # 让Django不要为字段text 生成标签。
2. URL模式new_topic
这个新网页的URL应简短而具有描述性, 因此当用户要添加新主题时, 将切换到http://localhost:8000/new_topic/。 下面是网页new_topic 的URL模式, 将其添加到learning_logs/urls.py中:
urls.py
--snip--
urlpatterns = [
--snip--
# 用于添加新主题的网页
url(r'^new_topic/$', views.new_topic, name='new_topic'),
]
这个URL模式将请求交给视图函数new_topic() , 接下来将编写这个函数。
3. 视图函数new_topic()
函数new_topic() 需要处理两种情形: 刚进入new_topic 网页(在这种情况下, 它应显示一个空表单) ; 对提交的表单数据进行处理, 并将用户重定向到网页topics
views.py
from django.shortcuts import render
from django.http import HttpResponseRedirect
from .models import Topic
from .forms import TopicForm
from django.urls import reverse
# from django.core.urlresolvers import reverse
'''
https://stackoverflow.com/questions/43139081/importerror-no-module-named-django-core-urlresolvers
Django 2.0 removes the django.core.urlresolvers module, which was moved to django.urls in version 1.10.
You should change any import to use django.urls instead, like this:
from django.urls import reverse
'''
--snip--
# 函数new_topic() 需要处理两种情形: 刚进入new_topic 网页(在这种情况下, 它应显示一个空表单) ; 对提交的表单数据进行处理, 并将用户重定向到网页topics
def new_topic(request):
"""添加新主题"""
if request.method != 'POST':
# 未提交数据: 创建一个新表单
form = TopicForm() # 如果请求方法不是POST, 请求就可能是GET, 因此我们需要返回一个空表单
else:
if form.is_valid(): # 必须先通过检查确定它们是有效的
form.save() # 表单中的数据写入数据库
# 函数reverse() 根据指定的URL模型确定URL, 这意味着Django将在页面被请求时生成URL。
# 调用HttpResponseRedirect() 将用户重定向到显示新增条目所属主题的页面
return HttpResponseRedirect(reverse('learning_logs:topics'))
context = {'form': form}
return render(request, 'learning_logs/new_topic.html', context)
'''
创建Web应用程序时, 将用到的两种主要请求类型是GET请求和POST请求。 对于只是从服务器读取数据的页面, 使用GET请求; 在用户需要通过表单提交信息时, 通常使用POST
请求。 处理所有表单时, 我们都将指定使用POST方法。 还有一些其他类型的请求, 但这个项目没有使用。
函数new_topic() 将请求对象作为参数。 用户初次请求该网页时, 其浏览器将发送GET请求; 用户填写并提交表单时, 其浏览器将发送POST请求。 根据请求的类型, 我们可以
确定用户请求的是空表单(GET请求) 还是要求对填写好的表单进行处理(POST请求) 。
'''
4. 模板new_topic
创建新模板new_topic.html, 用于显示刚创建的表单
new_topic.html
\{\% extends "learning_logs/base.html" \%\}
\{\% block content \%\}
<p>Add a new topic:</p>
<!--定义了一个HTML表单-->
<!--实参action 告诉服务器将提交的表单数据发送到哪里, 这里我们将它发回给视图函数new_topic() 。 实参method 让浏览器以POST请求的方式提交数据。-->
<form action="\{\% url 'learning_logs:new_topic' \%\}" method='post'>
\{\% csrf_token \%\} <!--防止攻击者利用表单来获得对服务器未经授权的访问-->
<!--显示表单修饰符as_p 让Django以段落格式渲染所有表单元素, 这是一种整洁地显示表单的简单方式-->
<button name="submit">add topic</button> <!--Django不会为表单创建提交按钮, 因此定义了一个这样的按钮-->
</form>
\{\% endblock content \%\}
5. 链接到页面new_topic
在页面topics 中添加一个到页面new_topic 的链接:
topics.html
\{\% extends "learning_logs/base.html" \%\}
\{\% block content \%\}
<p>Topics</p>
<ul>
\{\% for topic in topics \%\}
<li>
<a href="\{\% url 'learning_logs:topic' topic.id \%\}"></a>
</li>
\{\% empty \%\}
<li>No topics have been added yet.</li>
\{\% endfor \%\}
</ul>
<a href="\{\% url 'learning_logs:new_topic' \%\}">Add a new topic:</a>
\{\% endblock content \%\}
链接放在了既有主题列表的后面。 下图显示了生成的表单。
urls -> views -> html 添加网页步骤
用户可以添加新主题了, 但他们还想添加新条目。 将再次定义URL, 编写视图函数和模板, 并链接到添加新条目的网页。 但在此之前, 需要在forms.py中再添加一个类。
1. 用于添加新条目的表单
创建一个与模型Entry 相关联的表单
forms.py
from django import forms
from .models import Topic, Entry
class TopicForm(forms.ModelForm):
--snip--
class EntryForm(forms.ModelForm):
class Meta:
model = Entry
fields = ['text']
labels = {'text': ''}
widgets = {'text': forms.Textarea(attrs={'cols': 80})}
'''
定义了属性widgets 。 小部件 (widget) 是一个HTML表单元素, 如单行文本框、 多行文本区域或下拉列表。 通过设置属性widgets , 可覆盖Django选择的默认小
部件。 通过让Django使用forms.Textarea , 我们定制了字段'text' 的输入小部件, 将文本区域的宽度设置为80列, 而不是默认的40列。 这给用户提供了足够的空间, 可以
编写有意义的条目。
'''
2. URL模式new_entry
添加新条目的页面的URL模式中, 需要包含实参topic_id , 因为条目必须与特定的主题相关联。 该URL模式如下, 将它添加到了learning_logs/urls.py中
urls.py
--snip--
urlpatterns = [
--snip--
# 用于添加新条目的页面
re_path(r'^new_entry/(?P<topic_id>\d+)/$', views.new_entry, name='new_entry'),
]
3. 视图函数new_entry()
views.py
--snip--
from .models import Topic
from .forms import TopicForm,EntryForm
from django.urls import reverse
--snip--
def new_entry(request, topic_id):
"""在特定的主题中添加新条目"""
topic = Topic.objects.get(id=topic_id)
if request.method != 'POST':
# 未提交数据,创建一个空表单
form = EntryForm()
else:
# POST提交的数据,对数据进行处理
form = EntryForm(data=request.POST)
if form.is_valid():
# 调用save() 时, 传递了实参commit=False , 让Django创建一个新的条目对象, 并将其存储到new_entry 中, 但不将它保存到数据库中。
new_entry = form.save(commit=False)
new_entry.topic = topic # 将new_entry的属性topic 设置为在这个函数开头从数据库中获取的主题
new_entry.save() # 调用save() , 且不指定任何实参。 这将把条目保存到数据库, 并将其与正确的主题相关联。
return HttpResponseRedirect(reverse('learning_logs:topic',args=[topic_id]))
context = {'topic': topic, 'form': form}
return render(request, 'learning_logs/new_entry.html', context)
4. 模板new_entry
new_entry.html
\{\% extends "learning_logs/base.html" \%\}
\{\% block content \%\}
<p><a href="\{\% url 'learning_logs:topic' topic.id \%\}"></a></p>
<p>Add a new entry:</p>
<form action="\{\% url 'learning_logs:new_entry' topic.id \%\}" method='post'>
\{\% csrf_token \%\}
<button name='submit'>add entry</button>
</form>
\{\% endblock content \%\}
5. 链接到页面new_entry
在显示特定主题的页面中添加到页面new_entry 的链接
topic.html
\{\% extends 'learning_logs/base.html' \%\}
\{\% block content \%\}
<p>Topic: </p>
<p>Entries:</p>
<p>
<a href="\{\% url 'learning_logs:new_entry' topic.id \%\}">add new entry</a>
</p>
<ul>
--snip—
</ul>
\{\% endblock content \%\}
下图显示了页面new_entry
urls -> views -> html 添加网页步骤
创建一个页面, 让用户能够编辑既有的条目。
1. URL模式edit_entry
这个页面的URL需要传递要编辑的条目的ID。 修改后的learning_logs/urls.py如下
urls.py
--snip--
# https://docs.djangoproject.com/en/2.2/ref/urls/#module-django.urls.conf
urlpatterns = [
# 主页
path('', views.index, name='index'), # Django将在文件views.py中查找函数index()
# 显示所有的主题
path('topics/',views.topics,name = 'topics'),
# 特定主题的详细页面
# use a regular expression, you can use re_path(). https://stackoverflow.com/questions/47661536/django-2-0-path-error-2-0-w001-has-a-route-that-contains-p-begins-wit
re_path(r'^topics/(?P<topic_id>\d+)/$', views.topic, name='topic'), # ?P<topic_id> 将匹配的值存储到topic_id 中; 而表达式\d+ 与包含在两个斜杆内的任何数字都匹配, 不管这个数字为多少位。
# 用于添加新主题的网页
path('new_topic/', views.new_topic, name = 'new_topic'),
# 用于添加新条目的页面
re_path(r'^new_entry/(?P<topic_id>\d+)/$', views.new_entry, name='new_entry'),
# 用于编辑条目的页面
re_path(r'^edit_entry/(?P<entry_id>\d+)/$',views.edit_entry,name='edit_entry')
]
在URL(如http://localhost:8000/edit_entry/1/) 中传递的ID存储在形参entry_id 中。 这个URL模式将预期匹配的请求发送给视图函数edit_entry()
2. 视图函数edit_entry()
页面edit_entry 收到GET请求时, edit_entry() 将返回一个表单, 让用户能够对条目进行编辑。 该页面收到POST请求(条目文本经过修订) 时, 它将修改后的文本保存到数据库中:
views.py
--snip--
from .models import Topic, Entry
from .forms import TopicForm, EntryForm
--snip--
def edit_entry(request, entry_id):
"""编辑既有条目"""
entry = Entry.objects.get(id=entry_id)
topic = entry.topic
if request.method != 'POST':
# 初次请求, 使用当前条目填充表单
form = EntryForm(instance=entry)
else:
# POST提交的数据, 对数据进行处理
# 让Django根据既有条目对象创建一个表单实例, 并根据request.POST 中的相关数据对其进行修改
form = EntryForm(instance=entry, data=request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect(reverse('learning_logs:topic',args=[topic.id]))
context = {'entry': entry, 'topic': topic, 'form': form}
return render(request, 'learning_logs/edit_entry.html', context)
3. 模板edit_entry
edit_entry.html
\{\% extends "learning_logs/base.html" \%\}
\{\% block content \%\}
<p><a href="\{\% url 'learning_logs:topic' topic.id \%\}"></a></p>
<p>Edit entry:</p>
<form action="\{\% url 'learning_logs:edit_entry' entry.id \%\}" method='post'> <!--实参action 将表单发回给函数edit_entry() 进行处理-->
\{\% csrf_token \%\}
<button name="submit">save changes</button>
</form>
\{\% endblock content \%\}
4. 链接到页面edit_entry
在显示特定主题的页面中, 需要给每个条目添加到页面edit_entry 的链接:
topic.html
--snip--
\{\% for entry in entries \%\}
<li>
<p></p>
<p></p>
<p>
<a href="\{\% url 'learning_logs:edit_entry' entry.id \%\}">edit entry</a>
</p>
</li>
--snip--
下图显示了包含这些链接时, 显示特定主题的页面是什么样的
阶段代码:GitHub [learning_log_2.2创建用户账户](https://github.com/lichangke/Python3_Project/tree/master/learning_log/learning_log_2.2%E5%88%9B%E5%BB%BA%E7%94%A8%E6%88%B7%E8%B4%A6%E6%88%B7)
不包括虚拟环境ll_env文件夹下文件
将建立一个用户注册和身份验证系统, 让用户能够注册账户, 进而登录和注销。 将创建一个新的应用程序, 其中包含与处理用户账户相关的所有功能。 还将对模型Topic 稍做修改, 让每个主题都归属于特定用户。
开发系统: Ubuntu 16.0.4 LTS 开发IDE: Visual Studio Code 版本: 1.32.3 Python版本: Python3 依赖: Django 2.2
链接:https://pan.baidu.com/s/1USkqvL2dLU3Q9XplVaGQJg 提取码:zoyc
https://github.com/lichangke/Python3_Project/tree/master/learning_log
开发系统: Ubuntu 16.0.4 LTS
开发IDE: Visual Studio Code 版本: 1.32.3
Python版本: Python3
依赖库: requests 、 pygal
链接:https://pan.baidu.com/s/1USkqvL2dLU3Q9XplVaGQJg 提取码:zoyc
https://github.com/lichangke/Python3_Project/tree/master/web_api
requests :https://2.python-requests.org/zh_CN/latest/
pip install –user requests
pygal:http://www.pygal.org/en/stable/
pip install –user pygal
使用GitHub的API来请求有关该网站中Python项目的信息, 然后使用Pygal生成交互式 可视化, 以呈现这些项目的受欢迎程度。
# | 文件名 | 内容 |
---|---|---|
- | .vscode | VSCode 配置 |
- | bar_descriptions.py | pygal生成条形图测试 |
- | python_repos.py | 通过Web API接口获取数据,使用pygal可视化 |
- | python_repos.svg | 生成的界面 |
- | urlresult.json | 使用GitHub的API获取的当前数据 |
import pygal
from pygal.style import LightColorizedStyle as LCS, LightenStyle as LS
my_style = LS('#333366', base_style=LCS)
chart = pygal.Bar(style=my_style, x_label_rotation=45, show_legend=False)
chart.title = 'Python Projects'
chart.x_labels = ['httpie', 'django', 'flask']
plot_dicts = [
{'value': 16101, 'label': 'Description of httpie.'},
{'value': 15028, 'label': 'Description of django.'},
{'value': 14798, 'label': 'Description of flask.'},
]
chart.add('', plot_dicts)
chart.render_to_file('bar_descriptions.svg')
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
'''
@File : python_repos.py
@Time : 2019/04/26 23:01:12
@Author : leacoder
@Version : 1.0
@Contact : leacock1991@gmail.com
@License :
@Desc : None
'''
# here put the import lib
from pygal.style import LightColorizedStyle as LCS, LightenStyle as LS
import pygal
import requests
# 执行API调用并存储响应
url = 'https://api.github.com/search/repositories?q=language:python&sort=stars'
result = requests.get(url)
print("Status code:", result.status_code)
# 将API响应存储在一个变量中
response_dict = result.json()
print("Total repositories:", response_dict['total_count'])
# 探索有关仓库的信息
repo_dicts = response_dict['items']
print("Repositories returned:", len(repo_dicts))
print("\nSelected information about first repository:")
names, stars, plot_dicts = [], [], []
# 遍历仓库提取数据
for repo_dict in repo_dicts:
names.append(repo_dict['name'])
print('\nName:', repo_dict['name'])
print('Owner:', repo_dict['owner']['login'])
stars.append(repo_dict['stargazers_count'])
print('Stars:', repo_dict['stargazers_count'])
print('Repository:', repo_dict['html_url'])
print('Description:', repo_dict['description'])
# 规避 由于网络原因部分未获取到时,plot_dict 为 None,导致 chart.render_to_file('python_repos.svg') 报错 AttributeError: 'NoneType' object has no attribute 'decode'
if not repo_dict['stargazers_count']:
repo_dict['stargazers_count'] = "None"
breakpoint() # 注 此内置函数 New in version 3.7.+
if not repo_dict['description'] :
repo_dict['description'] = "None"
breakpoint()
if not repo_dict['html_url']:
repo_dict['html_url'] = "None"
breakpoint()
plot_dict = {
'value': repo_dict['stargazers_count'],
'label': repo_dict['description'],
'xlink': repo_dict['html_url'],
} # 注意最后有 逗号
plot_dicts.append(plot_dict)
# 可视化
mystyle = LS('#333366', base_style=LCS)
my_config = pygal.Config()
my_config.x_label_rotation = 45
my_config.show_legend = False
my_config.title_font_size = 24
my_config.label_font_size = 14
my_config.major_label_font_size = 18
my_config.truncate_label = 15
my_config.show_y_guides = False
my_config.width = 1000
chart = pygal.Bar(my_config, style=mystyle)
chart.title = 'Most-Starred Python Projects on GitHub'
chart.x_labels = names # x 轴数据
chart.add('', plot_dicts) #
chart.render_to_file('python_repos.svg')
GitHub链接: https://github.com/lichangke/LeetCode
个人Blog: https://lichangke.github.io/
欢迎大家来一起交流学习
152. 乘积最大子序列
给定一个整数数组 nums ,找出一个序列中乘积最大的连续子序列(该序列至少包含一个数)。
示例 1:
输入: [2,3,-2,4]
输出: 6
解释: 子数组 [2,3] 有最大乘积 6。
示例 2:
输入: [-2,0,-1]
输出: 0
解释: 结果不能为 2, 因为 [-2,-1] 不是子数组。
#@author:leacoder
#@des: 暴力求解 乘积最大子序列
# leetcode 超时
class Solution:
def maxProduct(self, nums: List[int]) -> int:
maxnum = float("-inf")
for i in range(0,len(nums)):
tmp = nums[i]
for j in range(i+1,len(nums)):
tmp *= nums[j]
maxnum = max(maxnum,tmp)
maxnum = max(maxnum,nums[i])
return maxnum
#@author:leacoder
#@des: 动态规划 乘积最大子序列
class Solution:
def maxProduct(self, nums: List[int]) -> int:
if nums is None : return 0
imax = [0,0]
imin = [0,0]
imax[0], imin[0],res= nums[0],nums[0],nums[0]
for i in range(1,len(nums)):
x,y=i%2,(i-1)%2 # x 表示当前最大或最小下标 y 表示前面最大或最小下标
imax[x] = max( imax[y] * nums[i], imin[y] * nums[i], nums[i] )
# nums[i]可能为负数,若为负数 前面最小 * nums[i]变为最大,前面最大 * nums[i]变为最小
imin[x] = min( imax[y] * nums[i], imin[y] * nums[i], nums[i] )
res = max(res,imax[x])
return res
#@author:leacoder
#@des: 动态规划 乘积最大子序列
class Solution:
def maxProduct(self, nums: List[int]) -> int:
if nums is None : return 0
res , curMax, curMin = nums[0],nums[0],nums[0]
for i in range(1,len(nums)):
num = nums[i]
curMax, curMin = curMax * num, curMin * num
# 由于 num可能为负数 上面结果可能刚好反了, curMax * 负数变为 curMin 顾需要下面语句处理
curMax,curMin = max(curMax,curMin,num),min(curMax,curMin,num)
res = max(curMax,res)
return res
#@author:leacoder
#@des: 动态规划 乘积最大子序列
class Solution:
def maxProduct(self, nums: List[int]) -> int:
if nums is None : return 0
res , curMax, curMin = nums[0],nums[0],nums[0]
for i in range(1,len(nums)):
num = nums[i]
if num < 0 :
curMax, curMin = curMin, curMax # 由于 num为负数 导致最大的变最小的,最小的变最大的,因此交换两个的值
curMax = max(curMax*num,num)
curMin = min(curMin*num,num)
res = max(curMax,res)
return res
GitHub链接: https://github.com/lichangke/LeetCode
个人Blog: https://lichangke.github.io/
欢迎大家来一起交流学习
Python Standard Library based on Python 3.7.3 https://docs.python.org/3/library/
Python标准库 - 内置异常
Link: [https://docs.python.org/3/library/exceptions.html#built-in-exceptions
说明 print 后的 # 注释为输出和相关说明,包含所有 Python3.7.3 官方文档中的内置异常
部分异常未代码实现测试
异常基本操作 可参考 http://www.runoob.com/python3/python3-errors-execptions.html
GitHub Code : Built-in Exceptions.py