小波分解与小波包分解代码

Code keeps changing, there’s no doubt about that. We always do our best to set some rock solid code foundations when a new project starts, we even have one or two favorite functions that become the cornerstone of our beautiful program. “This function will be my rod when I walk through the valley of the shadow of death.” But requirements change, and now your function should not just be the rod, but the rod and the staff as well.

代码不断变化,这毫无疑问。 当一个新项目开始时,我们总是尽力为某些基础代码奠定坚实的基础,我们甚至拥有一个或两个最喜欢的函数,这些函数成为了我们漂亮程序的基石。 “当我走过死亡阴影的山谷时,这就是我的职责。” 但是需求发生了变化,现在您的功能不仅应该是杆,还应该是杆人员。

Let’s take a walk.

让我们出去走走。

转1 (Turn 1)

Let’s imagine a MUD written in Node.js. At some point, we will be implementing melee combat in our game. And you write a function you are very much in love with; it’s a function to calculate the damage inflicted by a melee weapon. For the sake of storytelling, we don’t really care much about the contents of the function. We assume you just love it.

让我们想象一下用Node.js编写的MUD 。 在某个时候,我们将在游戏中实施近战。 并且您编写了一个非常喜欢的功能; 它是计算近战武器造成的伤害的函数。 为了讲故事,我们并不十分在意函数的内容。 我们假设您只是喜欢它。

/*** Calculates the damage of a melee attack.** @param {object} weapon - Weapon used in the attack.* @returns {number} Damage inflicted by <code>weapon</code>.*/
function calculateWeaponDamage(weapon) {return weapon.roll();
}

转2 (Turn 2)

After a couple of days, a game mechanics designer asks you to make some changes in the function because the weapon damage calculation should optionally take into account the physical defenses of the player who is being attacked. Turns out this function is being used both to display average damages in the UI, and to actually calculate the damage in-game when used against a real player. So, sometimes there will be a defender, and sometimes not.

几天后,游戏机制设计人员要求您对功能进行一些更改,因为武器损坏计算应选择考虑被攻击玩家的物理防御能力。 事实证明,此功能既可用于在UI中显示平均伤害,也可用于在对付真实玩家时实际计算游戏中的伤害。 因此,有时会有辩护人,有时没有。

Well, fine! I guess we can add a new argument to the function. We can even try to make the function signature backwards compatible by checking whether the new argument is being passed on or not, so that we do not have to go around refactoring all the usages of calculateWeaponDamage.

好吧,很好! 我想我们可以向该函数添加新的参数。 我们甚至可以尝试通过检查是否传递了新参数来使功能签名向后兼容,这样我们就不必重新解析calculateWeaponDamage所有用法。

/*** Calculates the damage of a melee attack.** @param {object} weapon - Weapon used in the attack.* @param {object} [defender] - Player who receives the attack.* @returns {number} Damage inflicted by <code>weapon</code> on <code>defender</code>.*/
function calculateWeaponDamage(weapon, defender) {let tmpDamage = weapon.roll();if (defender) {tmpDamage -= defender.stat('defense');}return tmpDamage;
}

Settled down for now, aren’t we?

现在定居下来,不是吗?

转3 (Turn 3)

Hey! We are giving players with extreme strength some melee damage bonus. Do you think you can take this into account in your beloved calculateWeaponDamage function? All developers using your function will be sending you an instance of the player wielding the weapon, because we need this extra damage to be reflected both in the UI and the actual in-game calculations.

嘿! 我们给具有极限力量的玩家一些近战伤害加成。 您认为可以在您钟爱的calculateWeaponDamage函数中考虑到这一点吗? 所有使用您功能的开发人员都会向您发送持武器玩家的实例,因为我们需要这种额外的损害,才能同时在用户界面和实际游戏计算中得到体现。

— Game mechanics designer

-游戏机制设计师

OK, fine. Now we have three arguments: two mandatory, one optional. But it turns out that other developers don’t have time to do a proper refactoring of the usages of calculateWeaponDamage and, out of desperation, agree to call the function even with an optional argument surrounded by two mandatory ones: calculateDamage(weapon, null, attacker);.

好的。 现在我们有了三个参数:两个强制性,一个可选。 但是事实证明,其他开发人员没有时间适当地重构calculateWeaponDamage的用法,出于绝望,即使使用带有两个必选参数的可选参数也同意调用该函数: calculateDamage(weapon, null, attacker);

/*** Calculates the damage of a melee attack.** @param {object} weapon - Weapon used in the attack.* @param {object} [defender] - Player who receives the attack.* @param {object} attacker - Player who inflicts the attack.* @returns {number} Damage inflicted by <code>weapon</code> of <code>attacker</code> on <code>defender</code>.*/
function calculateWeaponDamage(weapon, defender, attacker) {let tmpDamage = weapon.roll() + attacker.stat('extreme');if (defender) {tmpDamage -= defender.stat('defense');}return tmpDamage;
}

At this point you start to feel a bit itchy.

此时,您开始感到有点发痒。

转4 (Turn 4)

You feel they are misusing calculateWeaponDamage. You are tired of changing the signature of the function and decide to try a new approach: let’s use destructured function parameters. That way, the function receives a single options object argument holding as many mandatory or parameters as they want; if, in the future, new parameters should be added, then the refactoring of its usages will not be as painful as before, and as the owner of the function I don’t have to break my head too much about its signature — it’s just adding another property to the single object argument.

您觉得他们在滥用calculateWeaponDamage 。 您已经对更改函数的签名感到厌倦,并决定尝试一种新方法: 让我们使用分解后的函数参数 。 这样,函数将接收单个options对象参数,该参数包含所需的任意数量的必需或参数。 如果将来要添加新参数,则其用法的重构将不会像以前那样痛苦,并且作为函数的所有者,我不必为它的签名而费心—只是将另一个属性添加到单个对象参数。

/*** Calculates the damage of a melee attack.** @param {object} options - Options of this function.* @param {object} options.attacker - Player who inflicts the attack.* @param {object} options.weapon - Weapon used in the attack.* @param {object} [options.defender] - Player who receives the attack.* @returns {number} Damage inflicted by <code>weapon</code> of <code>attacker</code> on <code>defender</code>.*/
function calculateWeaponDamage({ attacker, weapon, defender }) {let tmpDamage = weapon.roll() + attacker.stat('extreme');if (defender) {tmpDamage -= defender.stat('defense');}return tmpDamage;
}

转5 (Turn 5)

Change of plans, bud!

计划变更,芽!

We need a bunch of extra options in calculateWeaponDamage: weapons might have imbued elemental damage, so we need a flag to determine whether we should take those into account, we also need a flag to actually inflict the damage on defender instead of just calculating it, and we also […]

我们在calculateWeaponDamage需要大量额外的选择:武器可能受到了元素伤害,因此我们需要一个标志来确定是否应将这些因素考虑在内,我们还需要一个标志来对defender造成实际伤害,而不仅仅是计算它,而且我们[…]

— Game mechanics designer

-游戏机制设计师

Anyway. For some reason or another, they’ve thrown a pile of flags at our function and now its signature just became something like this:

无论如何。 由于某种原因,他们在我们的函数上抛出了一堆标志,现在它的签名变得像这样:

/*** Calculates the damage of a melee attack.** @param {object} options - Options of this function.* @param {object} options.attacker - Player who inflicts the attack.* @param {object} options.weapon - Weapon used in the attack.* @param {object} [options.defender] - Player who receives the attack.* @param {boolean} [options.inflictInDefender=false] - Whether to actually inflict the damage on <code>defender</code>.* @param {boolean} [options.ignoreMagicalResistance=false] - If <code>true</code> magical resistances will be ignored in the calculations.* @param {boolean} [options.ignorePhysicalDefence=false] - If <code>true</code> physical defenses will be ignored in the calculations.* @param {boolean} [options.criticalHitsAllowed=true - Whether to allow critical hit values in the calculations.* @returns {number} Damage inflicted by <code>weapon</code> of <code>attacker</code> on <code>defender</code>.*/
function calculateWeaponDamage({ attacker, weapon, defender, inflictInDefender = true, ignoreMagicalResistance = true,ignorePhysicalDefence = true, criticalHitsAllowed = true}) {// We don't really care what happens inside
}

Would you be happy with this function signature?

您对此函数签名满意吗?

回顾性 (Retrospective)

I’ve found myself guilty of overusing destructured function parameters. Sometimes they felt really convenient, other times those function signatures stuck out like a sore thumb.

我发现自己过度使用解构函数参数是有罪的。 有时,他们感到非常方便,而其他时候,这些功能签名却像大拇指一样伸出来。

The series of unfortunate events that led to the latest calculateWeaponDamage version are probably exaggerated, but hopefully you might have recognized some personal experiences or work patterns in them. With the knowledge we have at this point, this is the function signature I would have proposed:

导致最新的calculateWeaponDamage版本的一系列不幸事件可能被夸大了,但是希望您可能已经意识到其中的一些个人经验或工作模式。 有了我们到此为止的知识,这就是我会建议的功能签名:

  • attacker, weapon and defender are the main actors in this function. Semantically, they “weight” more than all the other parameters in the signature. They have the right to be their own arguments in the function.

    attackerweapondefender是此功能的主要参与者。 语义上,它们比签名中的所有其他参数“权重”更多。 他们有权在函数中成为自己的参数。

  • We know now that the function will receive an actual set of options. Let’s have those as a separate, namesake object argument. Traditionally, the “options” argument is the last one, but in our scenario we have an optional argument in between: defender.

    现在我们知道该函数将收到一组实际的选项。 让我们将它们作为一个单独的同名对象参数。 传统上, “选项”参数是最后一个参数 ,但是在我们的场景中,我们之间有一个可选参数: defender

If we would attempt to do some sort of function overloading by allowing our function to be called in both these ways…

如果我们试图通过允许通过这两种方式调用我们的函数来进行某种函数重载……

  • calculateWeaponDamage(attacker, weapon, { ... });

    calculateWeaponDamage(attacker, weapon, { ... });

  • calculateWeaponDamage(attacker, weapon, defender, { ... });

    calculateWeaponDamage(attacker, weapon, defender, { ... });

…you’ll end up having errors when using the first example (without defender) because there would be an attempt to destructure an undefined 4th argument:

…使用第一个示例(不使用defender )时,您最终会出错,因为会尝试破坏未定义的第四个参数:

> calculateWeaponDamage(fingonfil, sword, { criticalHitsAllowed: false });Uncaught TypeError: Cannot read property 'inflictInDefender' of undefined

Maybe our function is just not that suitable to have destructured parameters. Still, we could solve the aforementioned error with a more exotic signature:

也许我们的功能不适合具有分解的参数。 不过,我们可以通过更奇特的签名解决上述错误:

/*** Calculates the damage of a melee attack.** @param {object} weapon - Weapon used in the attack.* @param {object} interactives - Interactive creatures involved in the melee attack.* @param {object} interactives.attacker - Player who inflicts the attack.* @param {object} [interactives.defender] - Player who inflicts the attack.* @param {object} options - Options of this function.* @param {boolean} [options.inflictInDefender=false] - Whether to actually inflict the damage on <code>defender</code>.* @param {boolean} [options.ignoreMagicalResistance=false] - If <code>true</code> magical resistances will be ignored in the calculations.* @param {boolean} [options.ignorePhysicalDefence=false] - If <code>true</code> physical defenses will be ignored in the calculations.* @param {boolean} [options.criticalHitsAllowed=true - Whether to allow critical hit values in the calculations.* @returns {number} Damage inflicted by <code>weapon</code> of <code>attacker</code> on <code>defender</code>.*/
function calculateWeaponDamage(weapon, { attacker, defender },{ inflictInDefender = true, ignoreMagicalResistance = true,ignorePhysicalDefence = true, criticalHitsAllowed = true }) {// Do your magic here
}

This way we “won’t” run into TypeError exceptions when there is no defender passed to the function (narrator: we still will.)

这样,当没有防御者传递给函数时,我们“不会”遇到TypeError异常( 旁白:我们仍然会 。)

Because our function is about calculating the damage inflicted by a weapon, weapon deserves to be the first argument. attacker and defender, as the interactive parties involved in the combat, have the same “semantic weight”. We could group them together as the second destructured argument.

因为我们的功能是关于计算武器造成的伤害,所以weapon应该是第一个论点。 作为参与战斗的互动方, attackerdefender具有相同的“语义权重”。 我们可以将它们组合在一起,作为第二个变形的论点。

Unfortunately, if we go for the simplest possible usage of this new function…

不幸的是,如果我们尽可能简单地使用此新功能……

> calculateWeaponDamage(sword, { attacker: fingonfil });

…we are still getting a TypeError exception.

…我们仍然收到TypeError异常。

> calculateWeaponDamage(sword, { attacker: fingonfil })Uncaught TypeError: Cannot read property 'inflictInDefender' of undefined    at calculateWeaponDamage (repl:2:7)

Since the argument options is truly optional, we can default its value to {}, like this:

由于参数options实际上是可选的,因此我们可以将其默认值设置为{} ,如下所示:

/*** Calculates the damage of a melee attack.** @param {object} weapon - Weapon used in the attack.* @param {object} interactives - Interactive creatures involved in the melee attack.* @param {object} interactives.attacker - Player who inflicts the attack.* @param {object} [interactives.defender] - Player who inflicts the attack.* @param {object} [options] - Options of this function.* @param {boolean} [options.inflictInDefender=false] - Whether to actually inflict the damage on <code>defender</code>.* @param {boolean} [options.ignoreMagicalResistance=false] - If <code>true</code> magical resistances will be ignored in the calculations.* @param {boolean} [options.ignorePhysicalDefence=false] - If <code>true</code> physical defenses will be ignored in the calculations.* @param {boolean} [options.criticalHitsAllowed=true - Whether to allow critical hit values in the calculations.* @returns {number} Damage inflicted by <code>weapon</code> of <code>attacker</code> on <code>defender</code>.*/
function calculateWeaponDamage(weapon, { attacker, defender},{ inflictInDefender = true, ignoreMagicalResistance = true,ignorePhysicalDefence = true, criticalHitsAllowed = true } = {}) {// Do your magic here
}

And this my dear reader would be our last version of the function before we give up and move to TypeScript.

我亲爱的读者将是我们放弃并转移到TypeScript之前该函数的最新版本。

我们注意到了什么? (What have we noticed?)

  • Sometimes we will spend an outrageous amount of time trying to get the right name of a function, or an argument. Or pondering on the position of an argument goes. That’s fine.有时,我们会花费大量时间来尝试获得函数或参数的正确名称。 或思考论点的位置。 没关系。
  • It helps when the arguments of a function have a semantic meaning and can be weighed. Some of them deserve to be in the spotlight, others can stay more in the backstage area.当函数的参数具有语义含义并可以权衡时,它会有所帮助。 他们中的一些人应该受到关注,其他人可以留在后台。
  • Destructured function parameters can help with maintainability but also come with some challenges, like we saw. It’s good to ask oneself: do I really need them here? Is it helping me or making things more complicated?像我们看到的那样,解构的函数参数可以帮助实现可维护性,但同时也会带来一些挑战。 问自己一个很好:我真的在这里需要他们吗? 是帮助我还是使事情变得更复杂?
  • There is a certain convention on what arguments should be in the last position, like callbacks and option objects. If some of those things are present in your function, other developers might expect them to be in that certain position.关于哪些参数应该放在最后位置有一定的约定,例如回调和选项对象。 如果您的函数中存在其中某些内容,则其他开发人员可能希望它们处于该特定位置。

We are documenting our functions with JSDoc, which will also help us see which arguments are optional and which ones have default values. For a more detailed article on bringing your JSDdoc skillsto the next level, check out one of my previous articles:

我们正在使用JSDoc记录我们的函数,这还将帮助我们查看哪些参数是可选的,哪些参数具有默认值。 有关将您的JSDdoc技能提升到更高水平的更详细的文章,请查看我以前的文章之一:

翻译自: https://medium.com/swlh/destructured-function-parameters-and-code-maintainability-c666bbd09af

小波分解与小波包分解代码


http://www.taodudu.cc/news/show-2748881.html

相关文章:

  • 每日英语:China's Red Cross Tries to Rebuild After Self-Inflicted Disaster
  • ubuntu怎么看服务器固态硬盘多大
  • 为服务器选择固态硬盘的一个优点和缺点
  • 服务器固态硬盘优缺点,为什么服务器使用的机械硬盘比固态硬盘多
  • 服务器中的固态硬盘优缺点,「服务器」固态硬盘的优缺点有哪些
  • 服务器如何选择固态硬盘,为什么绝大数服务器还使用机械硬盘,而不选固态硬盘呢?...
  • 数据中心服务器硬盘,PCI-E固态硬盘在数据中心的机会_希捷硬盘_服务器评测与技术-中关村在线...
  • 组装服务器要固态硬盘,服务器选择时,为什么要选择固态硬盘
  • 服务器固态硬盘连接,技术支招:服务器中固态硬盘如何选?
  • 服务器硬盘数据备份到nas,谁说固态硬盘做存储是鸡肋?NAS存储服务器还能这样玩...
  • 服务器系统 固态硬盘速度慢,SSD速度慢的原因和解决办法 电脑装了固态硬盘还慢怎么办...
  • 固态硬盘运行服务器,固态硬盘(SSD)在服务器中的工作原理是什么
  • 服务器固态硬盘raid0,SSD固态硬盘,撸一把RAID0模式大提速
  • 服务器固态硬盘无法识别硬盘,固态硬盘无法识别的原因及解决方法
  • 固态硬盘装到服务器上影响寿命吗,谈谈SSD固态硬盘的寿命问题
  • 服务器固态硬盘接口区别,s s d固态硬盘和服务器配件硬盘的区别
  • 服务器有固态盘系统安装,服务器有装固态硬盘吗
  • 无盘服务器固态硬盘做什么盘,哪个固态硬盘无盘服务器上最好?固态硬盘无盘服务器上详细介绍。...
  • 服务器使用固态硬盘的优缺点
  • 服务器固态硬盘跟机械硬盘之间差别是什么?
  • 浅谈服务器选择固态硬盘的几个优缺点
  • 统一社会信用代码(营业执照)和组织机构代码校验规则
  • 使用Java校验【统一社会信用代码】真假
  • java 社会统一信用代码分解,获取登记管理部门代码、机构类别代码、登记管理机关行政区划码、 主体标识码、校验码
  • JAVA、PHP统一社会信用代码、身份证号算法解析验证
  • JS校验统一社会信用代码的真实性
  • Python实现统一社会信用代码合法性校验
  • JAVA 身份证校验与统一社会信用代码校验
  • Python实现统一社会信用代码校验(GB32100-2015)
  • Python 生成、识别社会统一信用代码

小波分解与小波包分解代码_分解的功能参数和代码可维护性相关推荐

  1. 单片机c语言小波阈值降噪,小波阈值去噪的基本原理_小波去噪阈值如何选取

    小波阈值去噪的基本原理 小波阈值去噪的基本思想是先设置一个临界阈值λ,若小波系数小于λ,认为该系数主要由噪声引起,去除这部分系数;若小波系数大于λ,则认为此系数主要是由信号引起,保留这部分系数,然后对 ...

  2. matlab 小波名称,morlet小波函数matlab

    论-Matlab 7.0复Morlet小波分析操作实例.? 92? 2015年5 月 科技创新 中文科技期刊数据库 ( 文摘版 )自然科学 Matlab 7.0复MorletP]~ 波分析 操作 .. ...

  3. python小波特征提取_Python 小波包变换,小波包能量特征提取 代码

    1. 小波外部包下载 要下载两个包: PyWavelets和Matplotlib(要运行PyWavelets的所有测试,您还需要安装 Matplotlib软件包.) 安装方法: pip install ...

  4. 小波滤波器与其他滤波器的区别_小波变换(六):小波变换在机器学习中的应用(上)...

    本文讲解一篇关于小波变换在机器学习中的应用的博客:<A guide for using the Wavelet Transform in Machine Learning>,极力推荐!!目 ...

  5. matlab 小波滤波器,matlab小波滤波器使用

    研究db小波,用分解和重构滤波器和上下采样函数实现多分辨分析,代码如下: %%% 小波分解与重构 clear;close all; load noissin;Sig=noissin; %% 滤波器分解 ...

  6. matlab 曲线小波去噪,Matlab小波去噪实例.pdf

    第四章 图像增强 4.6 小波去噪举例[4,6] 4.6.1 MATLAB 中用wnoise 函数测试去噪算法 % waveletnoise.m sqrt_snr=3; init=231434; [x ...

  7. 小波、超小波(多尺度几何分析)与压缩感知

    0. 图书 基于MATLAB 6.X的系统分析与设计-小波分析. 胡昌华,李国华,刘涛,等.西安:西安电子科技大学出版社,2004 MATLAB小波分析高级技术. 周伟,桂林,周林,等.西安:西安电子 ...

  8. matlab 小波中心频率,小波频域特性Matlab实现.pdf

    小波频域特性Matlab实现 小波频域特性– Matlab实现 东北大学 信号与信息处理研究所 栾峰 副教授 /luanfeng /luanfeng 编程示例 例 下面给出了一个信号的连续小波变换的例 ...

  9. 小波变换中的多贝西小波(DB小波函数)概述

    内容均来源于维基百科对db小波函数的介绍 多贝西小波(英语:Daubechies Wavelet),是以比利时女性物理暨数学家英格丽·多贝西(Ingrid Daubechies)的名字命名之一种小波函 ...

最新文章

  1. {TypeError}clamp(): argument 'min' must be Number, not Tensor
  2. 安装MYSQL自定义安装路径
  3. ZOJ18th省赛 Lucky 7
  4. 在写移动端时,a标签或者input标签等 在手机上点击背后会有阴影的解决办法
  5. Delphi如何获取时间月份
  6. vue html5模板,vue-h5-template
  7. 文本或代码中 \n 和 \r 的区别
  8. 嵌入式linux写文件内存增加,嵌入式Linux对内存的直接读写
  9. leetcode:Majority Number
  10. 一个前端的入行故事,零基础,2个月自学入门前端,半年从外包进淘宝
  11. c语言程序设计5pdf,C语言程序设计5.pdf
  12. 浙江工业大学计算机学院的博士招生,浙江工业大学计算机科学与技术学院、软件学院...
  13. 设计一个三阶巴特沃斯滤波器_巴特沃斯低通滤波器设计分析.doc
  14. x86汇编指令集大全(带注释)
  15. [算法]详解关键路径算法
  16. R语言计算dataframe中指定数据列的值为缺失值的样本个数(行的个数)
  17. 4.1-4.30推荐文章汇总
  18. (008)前端css,js,Jquery,Servlet入门
  19. R 利用回归分析与时间序列预测北京市PM2.5
  20. AutoSAR系列讲解(入门篇)1.2-AutoSAR概述

热门文章

  1. LM358电流检测电路
  2. 遇险哪里还有空报警?求救app告诉你,有的
  3. linux转置的命令,转置文件(awk)
  4. PIC16F877A单片机 (中断与定时器Timer2)
  5. mac 重置mysql root密码_Mac下忘记Mysql root密码重置
  6. 2016年7月17日学习 scratch 钢琴键
  7. 12月17号英语学习
  8. 桂林理工大学 程序设计实践课程 实习报告
  9. 分享一些正确的放松方式
  10. python通信自动化测试_基于Python的无线通信设备自动化测试软件的研制