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("谢谢")

参考技术B # -*- coding: utf-8 -*-
"""
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新手代码问题?的主要内容,如果未能解决你的问题,请参考以下文章

python 新手常见问题

Python 新手入门习题及代码

新手村4级萌新--Python基础学习

.py文件运行没反应(新手)

Python:我需要一个代码来使用 HTTPS 自动登录网站 [关闭]

新手入门Python,也会调试代码了,这款 “神器“ 真的超赞!