python新手代码问题?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python新手代码问题?相关的知识,希望对你有一定的参考价值。
亲爱的大佬们:如图,,,,,,图1的第40行代码接着图2的第41行代码:我是一个小白,这是我自己写的外贸运费计算器...模拟之后没有什么问题..正常运行..问题一: 国家名太多导致很乱,,,有没有办法使用集合或者列表[]来统一国家名?例如:a=["美国","加拿大","澳大利亚".........]b=["西班牙","葡萄牙","意大利".........]然后input()列表中任意一个国家就能判断是a还是b? 因为a b c.....代表了不同分区的国家,运费不一样. 我尝试以后总是失败,可能是逻辑和语法不对.问题二: 我是个典型新手.如果想把写好的代码做成一个带有简易图形界面的EXE程序...然后发给同事们用..我接下来应该学习哪一个软件?
判断元素与集合归属关系可以直接用in,python内建的循环会帮你处理比较:
国家="中国"
a = ["美国","加拿大","澳大利亚"]
b = ["中国","日本","印度"]
if 国家 in a:
print("a")
elif 国家 in b:
print("b")
else:
print("ERROR")
用python做图形界面,然后还要发布为应用程序的话,有很多框架,比如Qt for Python,也就是常说的PyQt。比较推荐这个,因为算是目前比较流行的,而且不难入门,具体可以在百度上搜Qt或者PyQt,到官网去下载框架。
PyQt下载:https://riverbankcomputing.com
一些教程:
http://code.py40.com/1948.html(这个是翻译的)
http://zetcode.com/gui/pyqt5/(这个是源教程)
当然还有很多,网上搜PyQt教程就可以。
参考技术A最小的改动是,将每个区做成一个列表,然后if 的条件就可以简化。
group_1 = ['香港', '澳门']
...
if 国家 in group_1:
...
然后,还有可以进一步优化的空间。
因为除了首重和运费基数不同外,计算公式是不变的,不需要用一组if...elif。
在python中有高阶函数可以对列表进行高阶运算,包括对列表所有元素进行同样运算的map(),以及对列表进行过滤的filter()。
因此,将一组国家做成一个字典,包含国家列表,基础运费,运费基数信息,将所有分组放到一个列表,然后只需要使用filter()对列表过滤来找到相应的分组,将基础运费和运费基数代入固定公式计算即可。
汇率 = 7
地区分组 = [
....'国家':['香港', '澳门'], '基础运费':78, '运费基数':18,
....
....]
for 地区 in filter(lambda _:国家 in _['国家'], 地区分组):
....运费 = 地区['基础运费']
....if 重量>0.5:
........运费 += 地区['运费基数'] * (重量-0.5) * 2
....print(运费 // 汇率)
这样,整个计算部分就只有5行(for之前的都是数据)
再进一步的优化,就是对公式进行优化。这个if并不是必需的。
对计算公式的理解,应该是可以换成另一种等价的表述:
不同地区运费的计算是起运费用+重量费用,重量不足0.5公斤的按0.5公斤计算。
然后,把公斤换成斤,就不需要考虑小数了;
以及,使用math.ceil()进行向上取整,配合max(),就不需要if了,那么,可以用一个map来进行列表计算:
from math import ceil
汇率 = 7
地区分组 = [
....'国家':['香港', '澳门'], '基础运费':60, '运费基数':18,
....
....]
for 地区 in filter(lambda _:国家 in _['国家'], 地区分组):
....运费 = 地区['基础运费'] + max(ceil(重量), 1) * 地区['运费基数']
....print(运费 // 汇率)
就这样,只需要三行,就完事了。
如果想要极限,可以用map()来处理filter的结果,那就只需要一行代码,但是难看点:
...
print(list(map(lambda 地区: (地区['基础运费'] + max(ceil(重量), 1) * 地区['运费基数'])//汇率,filter(lambda 地区:国家 in 地区['国家'], 地区分组)))[0])
追问大佬您好.方便留个邮箱吗?
我仔细阅读您的回答.虽然不太懂.但是受益匪浅.其中很多函数和语法我还没有学过.
50行的代码缩短为1行,这让我很震惊也很兴奋.
我计划在未来几天内争取做到把它们缩减到1行.我会仔细分析和理解你写的最后一行.
但是一定会遇到很多难点和错误.如果您能留下邮箱的话.我可以随时向您请教.
print("谢谢")
"""
Created on Mon Aug 31 10:38:03 2020
@author: Roy
"""
from tkinter import*
#分区
Group_list = [
'Country':['香港', '澳门'], 'freight':78, 'base':18,#一区
'Country':['韩国', '台湾'], 'freight':108, 'base':24,#二区
'Country':['马来西亚', '菲律宾','新加坡','泰国','越南','印度尼西亚'], 'freight':114, 'base':27,
'Country':['日本'], 'freight':126, 'base':33,
'Country':['澳大利亚', '新西兰'], 'freight':126, 'base':33,
'Country':['加拿大', '美国'], 'freight':168,'base':38,
'Country':['荷兰', '英国','比利时','德国'], 'freight':168, 'base':38,
'Country':['奥地利', '卢森堡','挪威','丹麦','芬兰','法国','爱尔兰','意大利','葡萄牙','西班牙','瑞典','瑞士'], 'freight':168, 'base':38,
'Country':['保加利亚','拉托维尔','立陶宛','爱沙尼亚','匈牙利','波兰','罗马尼亚','斯洛伐克','斯洛文尼亚','土耳其','希腊'], 'freight':273, 'base':72,
'Country':['波斯尼亚和黑山','塞尔维亚','俄罗斯','格陵兰岛','列支敦士登'], 'freight':273, 'base':72,
'Country':['阿联酋','巴林','以色列','沙特阿拉伯'], 'freight':201, 'base':60,
'Country':['南非', '也门','埃及','伊拉克','伊朗','约旦','科威特','黎巴嫩','阿曼','巴勒斯坦','卡塔尔','叙利亚'], 'freight':273, 'base':72,
'Country':['孟加拉', '印度','斯里兰卡','尼泊尔','巴基斯坦'], 'freight':180, 'base':48,
'Country':['阿根廷', '巴西','智利','哥伦比亚'], 'freight':201, 'base':60
]
def gen():
country = entry.get()
weight = entry2.get()
for location in filter(lambda group:country in group['Country'],Group_list):
if int(weight) > 0.5:
sum_price = float(location['freight']) + float(location['base']) *(float(weight)-0.5)
exchange_price = sum_price//7
else:
sum_price = float(location['freight']) + float(location['base']) *float(weight)
exchange_price = sum_price//7
label_str.set('RMB:' + str(sum_price) + ' $:'+ str(exchange_price))
#界面
tk =Tk()
entry_var =StringVar()
entry_var2 =StringVar()
label_str =StringVar()
tk.title('外貌运费计算器')
winWidth = 360
winHeight = 200
# 获取屏幕分辨率
screenWidth = tk.winfo_screenwidth()
screenHeight = tk.winfo_screenheight()
x = int((screenWidth - winWidth) / 2)
y = int((screenHeight - winHeight) / 2)
# 设置窗口初始位置在屏幕居中
tk.geometry("%sx%s+%s+%s" % (winWidth, winHeight, x, y))
frame1 = Frame(tk)
frame1.pack(anchor = W,padx =3,pady=3)
label =Label(frame1,text ='国家:')
label.pack(side=LEFT,padx =3,pady=3)
entry = Entry(frame1,textvariable = entry_var,width = 20)
entry.pack(side=LEFT,padx =3,pady=3)
frame3 = Frame(tk)
frame3.pack(anchor = W,padx =3,pady=3)
label =Label(frame3,text ='重量:')
label.pack(side=LEFT,padx =3,pady=3)
entry2 = Entry(frame3,textvariable = entry_var2,width = 20)
entry2.pack(side=LEFT,padx =3,pady=3)
frame2 = Frame(tk)
frame2.pack(anchor = W,padx =3,pady=3)
button =Button(frame2,text ='生成',command=gen)
button.pack(side=LEFT,padx =3,pady=3)
label =Label(frame2,textvariable = label_str,bg='lightyellow',width =20)
label.pack(side=LEFT,padx =3,pady=3)
frame4 = Frame(tk)
frame4.pack(anchor = 'center',padx =3,pady=3)
label =Label(frame4,text='1.请输入完整中文国家名\n2.请输入包裹重量,输入为0.5kg的整数倍,不足0.5kg按0.5kg算')
label.pack(side=LEFT,padx =3,pady=3)
tk.mainloop()
带窗口小程序,缩进自己改改吧,界面凑合看。 参考技术C 作为一个比你稍老一点的新手,给你几点建议:
1、变量名不要使用中文;
2、注意控制程序的复杂度,可以将程序的多个步骤分别封装到相应的函数;
比如,你的这个程序可以写成两个函数,一个通过国家名获取相应运费数据;另一个用来处理实际运费计算。当然如果你要写一个实际可用的程序的话,需要考虑的问题会更多一些;比如你需要考虑用户输入的问题,这时你就可以考虑将输入单独重写成一个函数,独立处理从而可以减少程序的复杂度。
3、就你的这个程序,我建议将国家按照分区存放于列表类似于`[["香港", "澳门"], ["韩国", "台湾"], ...]`,得到列表的下标就得到了国家相应的分区,然后将分区对应的运费做成一个列表,通过上面得到的分区信息去获得对应的运费信息,最后根据具体的重量计算就ok啦。
4、最后你想把程序做成界面程序供他人使用,其他回答也提到了用tkinter和pyinstaller这两个第三方库;希望你能得偿所愿。。 参考技术D 第一个问题,就是个逻辑判断,存在与否就可以了,就是写业务。
第二个问题,你是想写一个exe。你也许不太理解啥是exe。不过我可以给你说有个包py2exe 可以把程序打包成window下的运行主入口。还有你想的是写个软件。其实大多时候我们都是要写后台程序提供web界面的。你可以了解下flask、django、web包
将一个文件的代码应用于多个文件python(新手问题)
【中文标题】将一个文件的代码应用于多个文件python(新手问题)【英文标题】:Applying code for one file to multiple files python (Newbie Question) 【发布时间】:2020-12-01 11:46:35 【问题描述】:我编写了以下代码,它从 csv 文件中获取一列,然后将其转换为整数并将它们全部相加。我只为一个文件做了这个,我有大约 80 个文件可以应用相同的代码。
import csv
from collections import defaultdict
columns = defaultdict(list)
with open('Team11BoM.csv') as f:
reader = csv.DictReader(f)
for row in reader:
for (k,v) in row.items():
if k not in columns:
columns[k] = list()
columns[k].append(v)
import pandas as pd
df = pd.read_csv("Team11BoM.csv")
b = list(df['Reported Price'])
a = list(df['Actual Price'])
for i in range(0, len(a)):
a[i] = int(float(a[i]))
v = sum(a)
print("the total actual cost(s) for team 11 is:", v)
for i in range(0, len(b)):
b[i] = int(float(b[i]))
h = sum(b)
print("the total reported price for team 11 is:", h)
它打印出以下内容:
the total actual cost(s) for team 11 is: 945
the total reported price for team 11 is: 707
我希望它打印出来:
the total actual cost(s) for *filename* is: *Total cost of that team*
the total reported price for *filename* is: *Total reported price of that team*
有什么简单的方法吗?
谢谢, 伊尔凡 S.
【问题讨论】:
我为您的问题添加了答案。 【参考方案1】:import os
import csv
import pandas as pd
from collections import defaultdict
files_dir = 'csv'
csv_files = os.listdir(files_dir)
print(csv_files)
def convert_to_int(file_name):
file_name = f'files_dir/file_name'
columns = defaultdict(list)
with open(file_name) as f:
reader = csv.DictReader(f)
for row in reader:
for (k,v) in row.items():
if k not in columns:
columns[k] = list()
columns[k].append(v)
df = pd.read_csv(file_name)
b = list(df['Reported Price'])
a = list(df['Actual Price'])
for i in range(0, len(a)):
a[i] = int(float(a[i]))
v = sum(a)
print("the total actual cost(s) for team 11 is:", v)
for i in range(0, len(b)):
b[i] = int(float(b[i]))
h = sum(b)
print("the total reported price for team 11 is:", h)
for file in csv_files:
convert_to_int(file)
【讨论】:
对不起,迟到的问题,但我用文件名替换了 FOLDER_PATH,但它也给了我一个TypeError: listdir: path should be string, bytes, os.PathLike, integer or None, not module
,我在代码中放了不带引号的文件名,还有更多我需要更改/添加?谢谢!
不,你应该只配置文件夹路径,控制台在哪一行显示错误?
完全错误是:Traceback (most recent call last): File "location of file", line 6, in <module> csv_files = os.listdir(csv) TypeError: listdir: path should be string, bytes, os.PathLike, integer or None, not module
我把文件名放到代码中像这样csv_files = os.listdir(csv)
os.listdir() 将文件夹名称作为字符串,因此如果您的文件夹名称为 csv,您应该像 os.listdir('csv') 那样进行操作。
即使在文件夹 csv (csv_files = os.listdir('csv')
) 周围加上引号,它也会给出两个错误:Traceback (most recent call last): File "file location", line 37, in <module> convert_to_int(file)
和 File "file location", line 11, in convert_to_int with open(file_name) as f: FileNotFoundError: [Errno 2] No such file or directory: 'Team41BoM.csv'
【参考方案2】:
首先,您应该定义一个可重复使用的函数以避免代码重复。
import csv
from collections import defaultdict
def process_file(file_name):
columns = defaultdict(list)
with open(file_namename) as f:
reader = csv.DictReader(f)
for row in reader:
for (k,v) in row.items():
if k not in columns:
columns[k] = list()
columns[k].append(v)
import pandas as pd
df = pd.read_csv(file_name)
b = list(df['Reported Price'])
a = list(df['Actual Price'])
for i in range(0, len(a)):
a[i] = int(float(a[i]))
v = sum(a)
print(f"the total actual cost(s) for file_name 11 is:", v)
for i in range(0, len(b)):
b[i] = int(float(b[i]))
h = sum(b)
print(f"the total reported price for file_name 11 is:", h)
其次,调用这个函数并遍历文件列表:
# assuming all of this files are in the current directory
list_of_files = [f for f in os.listdir('.') if os.path.isfile(f)]
for file_name in list_of_files:
process_file(file_name)
【讨论】:
对于文件列表,我应该把所有的 csvs 放到一个文件夹中吗? @IrfanS,假设所有文件都在同一个目录中,您可以使用files = [f for f in os.listdir('.') if os.path.isfile(f)]
来获取要迭代的文件列表。【参考方案3】:
如何将 csvs 放在一个目录中并像这样执行循环:
import pandas as pd
def summer(f):
name = f.split('.')[0]
df = pd.read_csv(f)
b = list(df['Reported Price'])
a = list(df['Actual Price'])
for i in range(0, len(a)):
a[i] = int(float(a[i]))
v = sum(a)
print(f"the total actual cost(s) for name is:", v)
for i in range(0, len(b)):
b[i] = int(float(b[i]))
h = sum(b)
print("the total reported price for name is:", h)
path = 'path/to/csv-files/directory/'
import os
for fil in os.listdir(path):
summer(fil)
【讨论】:
我正在使用 iCloud Drive,当我输入路径时显示“FileNotFoundError: [Errno 2] No such file or directory: 'iCloud Drive/desktop/IACCproject1'”这是 iCloud 驱动器的问题还是还有什么? iCloud 驱动器位于:/home/yourusername/Library/Mobile Documents/com~apple~CloudDocs/【参考方案4】:您可以使用 for 循环并遍历 cwd 中的每个文件并对所有文件执行相同操作,确保所有文件位于同一目录中
import csv
from collections import defaultdict
import pandas as pd
import os
def valueSum(filename):
columns = defaultdict(list)
with open(filename) as f:
reader = csv.DictReader(f)
for row in reader:
for (k,v) in row.items():
if k not in columns:
columns[k] = list()
columns[k].append(v)
df = pd.read_csv(filename)
b = list(df['Reported Price'])
a = list(df['Actual Price'])
for i in range(0, len(a)):
a[i] = int(float(a[i]))
v = sum(a)
for i in range(0, len(b)):
b[i] = int(float(b[i]))
h = sum(b)
print("the total actual cost(s) for team 11 is:", v)
print("the total reported price for team 11 is:", h)
for filename in os.listdir("."):
if filename.endswith(".csv"): #count only csv files
valueSum(filename)
【讨论】:
我收到了错误。 'ValueError: cannot convert float NaN to integer' 我认为它给出了这个错误,因为某些文件可能没有相同的格式。我也不确定 NaN 是什么。 那是因为 csv 文件中的某些值是 NaN。检查它是否不是 NaN 然后转换为 int 我不知道该怎么做,我可以使用某种功能吗? 你可以用math.isnan()
做到这一点,math.isnan(value)
如果它的 NaN 将返回 True,如果它不是 NaN 则返回 False以上是关于python新手代码问题?的主要内容,如果未能解决你的问题,请参考以下文章