技术标签: C# java 自定义游戏辅助编辑器
该编辑器编写的初衷是为了帮助游戏一些功能的开发比如新手引导,成就等等。现在编写的是一个框架,具体功能需要自行扩展。
目录
一、编辑器结构(原始数据+触发器)
编辑器有四大数据模块组成它们分别是原始数据、触发器数据、枚举数据结构、数据存储数据结构。下面会逐一介绍每个数据,关于它们的数据构成如何扩展等。
原始数据是最基本的数据,它是组成整个编辑器数据的基石,标识出该数据是做什么的。
触发器数据在编辑器和运行时都是需要用的数据,在编辑器中它用来存储编辑好的数据,在运行时中它用来处理游戏传出的数据。可以看出触发器数据在整个编辑器和运行时中有着重要的地位。
枚举数据结构是用于辅助类的数据,该数据用于选择器数据。
数据存储 分为编辑数据存储和导出数据存储,编辑数据用于保存编辑器数据,导出数据用于运行时数据的运用。
原始数据有一个总类OrigDataParent。
OrigDataParent是一个抽象类,包含四个字段,变量name表示数据的名称,它将在选择[事件/环境/动作]中显现该名字。变量id表示该段数据的唯一id,它对应着不同的枚举值,[事件/环境/动作]对应的不同的枚举,这个id代表该唯一的原始数据,在触发器中的origId就是对应着该id,[事件/环境/动作]三个不同的枚举在运行时中有着唯一区别的作用。变量descrip表示数据描述,用来给使用者一个具体的解释。变量type表示所属类型它用于为原始数据分类型,对应着三个不同的枚举分别是OrigEventTypeEnum/OrigConditionTypeEnum/OrigActionTypeEnum。
OrigDataParent继承了接口IOrigData,该接口包含了两个方法Show()和Save (params object[] obj),其中Show用来显示原始数据中的内容供使用者填写/选择数据,后面将会举例说明。Save用来保存使用者编辑的数据。
另外比较重要的一点是为了能够读取数据的方便开发者扩展新的触发器时需要给出指定的命名空间DataStruct。
下面是元数据OrigDataParent与接口IOrigData的代码。
public interface IOrigData
{
/// <summary>
/// 显示Panel数据
/// </summary>
/// <returns></returns>
List<Control> Show();
/// <summary>
/// 保存数据
/// </summary>
/// <param name="obj"></param>
TriggerDataParent Save (params object[] obj) ;
}
namespace DataStruct
{
[Instantiation]
public abstract class OrigDataParent : IOrigData
{
public string name;//数据名称
/// <summary>
/// 唯一id
/// 对应ThreeOrigEnumType中三个枚举中的值
/// </summary>
public int id;
/// <summary>
/// 数据描述
/// </summary>
public string descrip;
/// <summary>
/// //所属类型,默认全部
/// 对应枚举
/// OrigEventTypeEnum/OrigConditionTypeEnum/OrigActionTypeEnum/OrigOtherTypeEnum
/// 的值
/// </summary>
public int type = 0;
public OrigDataParent(string name, int id)
{
this.name = name;
this.id = id;
}
/ <summary>
/ 保存数据的方法
/ </summary>
/ <param name="obj">obj[0]=EditorTriggerDataStruct</param>
//public abstract void Save(params object[] obj);
public abstract TriggerDataParent Save(params object[] obj);
/// <summary>
/// 显示内容的方法
/// </summary>
/// <returns></returns>
public abstract List<Control> Show();
public virtual string Descrip()
{
return name + "——" + descrip;
}
public override string ToString()
{
return name;
}
}
}
原始数据下面分三个类型,事件、环境、动作,这三个类型都有一个父类它们分别是OrigEventDataParent、OrigConditionDataParent、OrigActionDataParent它们都继承父类OrigDataParent。这三个类也均是抽象类,具体内容可见项目代码。
触发器数据有一个总类TriggerDataParent,它是一个抽象类。
TriggerDataParent中有两个字段,变量origId它对应于原始数据唯一的id,标识该触发器要用于做什么。变量fullName表示该触发器的完全限定名,该字段不需要开发者维护,该字段仅用于数据的存储与读取。另外比较重要的一点是为了能够读取数据的方便开发者扩展新的触发器时需要给出指定的命名空间DataStruct。下面是该抽象类的具体内容。
public interface IListVoluation
{
/// <summary>
/// 传入一个List<object> 类型
/// 将其转化为list具体类型
/// </summary>
/// <param name="list"></param>
void listVoluation(List<object> list);
}
namespace DataStruct
{
/// <summary>
/// 触发器数据总类
/// </summary>
[TriggerTypeAttri]
public abstract class TriggerDataParent : IListVoluation
{
/// <summary>
/// 对应原始数据的唯一id
/// </summary>
public float origId;
public string fullName;
public TriggerDataParent(float origId)
{
this.origId = origId;
fullName = GetType().FullName;
}
public TriggerDataParent()
{
fullName = GetType().FullName;
}
public void SetOrigId(int origId)
{
this.origId = origId;
}
/// <summary>
/// 创建额外树节点,
/// 这个节点将作为本身节点的子节点
/// 可以参考TriggerMultipleConditionData的重写方法--creatSelfTreeNode
/// 如无特殊需要不必重写
/// </summary>
/// <returns></returns>
public virtual TreeNode creatSelfTreeNode()
{
return null;
}
/// <summary>
/// 对触发器的额外描述
/// 如无特殊需要不必重写
/// </summary>
/// <returns></returns>
public virtual string Descript()
{
return null;
}
/// <summary>
/// 如果子类中有List成员变量,请务必实现该方法
/// 传入一个List<object> 类型,将其转化为list具体类型
/// </summary>
/// <param name="list">传入的list是对应于所需要的list,用于数据读取</param>
public virtual void listVoluation(List<object> list)
{
}
}
}
触发器结构下面分三个类型,事件、环境、动作,这三个类型都有一个父类它们分别是TriggerDataParent、TriggerConditionDataParent、TriggerActionDataParent它们都继承父类TriggerDataParent。这三个类也均是抽象类,具体内容可见项目代码。
枚举数据是自定义的一个类EnumClassParent,它用来作为选择器数据,所有的选择器数据都要继承该父类,这个类不参与存储,在编辑器开始运行时将会运用反射自动加载所有继承该类的子类。该类有四个字段,它们分别是:listEnum它是一个list列表类型是EnumItem,用来缓存枚举单位;name它表示选择器的名字;enumType枚举类型值,对应于EnumType枚举中的值;字典dicEnums。下面给出该代码:
public class EnumItem
{
public string name;
public int value;
public EnumItem(string name, int value)
{
this.name = name;
this.value = value;
}
}
[Instantiation]
public abstract class EnumClassParent
{
public List<EnumItem> listEnum = new List<EnumItem>();
public string name;
/// <summary>
/// 对应于EnumType的值
/// </summary>
public int enumType;
/// <summary>
/// /key表示EnumItem中的value值
/// </summary>
[JsonIgnore]
public Dictionary<int, EnumItem> dicEnums = new Dictionary<int, EnumItem>();
public EnumClassParent(string name, int enumType)
{
this.name = name;
this.enumType = enumType;
}
protected void creat(string name, int value = -1)
{
if (value == -1)
{
value = listEnum.Count;
}
EnumItem item = new EnumItem(name, value);
listEnum.Add(item);
if (dicEnums.ContainsKey(item.value))
{
dicEnums[item.value] = item;
}
else
{
dicEnums.Add(item.value, item);
}
}
public void setData()
{
if (listEnum.Count > 0)
{
foreach (var item in listEnum)
{
if (dicEnums.ContainsKey(item.value))
{
dicEnums[item.value] = item;
}
else
{
dicEnums.Add(item.value, item);
}
}
}
}
}
/// <summary>
/// 枚举类型标识
/// </summary>
public enum EnumType
{
/// <summary>
/// 对比计算器
/// </summary>
ContrastCalculator,
/// <summary>
/// ui的类型
/// </summary>
UIType,
/// <summary>
/// 触发器枚举
/// </summary>
Trigger,
/// <summary>
/// 创建某个物体的枚举
/// </summary>
CreatItem,
/// <summary>
/// 单位类型
/// </summary>
ItemType,
/// <summary>
/// 玩家GM命令
/// </summary>
PlayerGM,
}
下面给出一个具体的选择器的代码:
namespace DataStruct
{
/// <summary>
/// 对比计算器
/// </summary>
public class EnumContrastCalculator : EnumClassParent
{
public EnumContrastCalculator() : base("对比计算器", (int)EnumType.ContrastCalculator)
{
creat("等于",1000);
creat("不等于",1001);
creat("小于等于",1002);
creat("大于等于",1003);
creat("小于",1004);
creat("大于",1005); }
}
}
改代码在编辑器运行是对应的数据显示:
编辑器数据的存储结构由三个类构成,EditorTriggerDataStruct表示一个完整的触发器,其中包括该触发器内所有的事件环境动作数据,EditorData表示整个类的数据结构,EditorDataSave存储所有的类的数据同时也是保存的json数据。下面的一张图将会解释这三个类的关系。
该数据不需要开发者再次管理,整套管理流程已经书写完毕。
二、运行时结构
对于不同的游戏运行时结构会有所不同,现在给出一个特定的运行时结构。该运行时是在服务器使用。
1、编辑器导出数据的结构
ExportTriggerDataStruct类作为一个触发的结构它包括事件/环境/条件着三类数据,变量triggerStructIndex表示该触发器在该工程中的唯一序列,用于区别于其他的导出触发器数据结构。ExportTriggerDataStruct中有三个方法它们用于处理事件/环境/动作这些数据。下面给出代码:
@DataStructAnnotat
@Scope("prototype")
@Service
public class ExportTriggerDataStruct implements IListVoluation
{
public ArrayList<TriggerEventDataParent> list_event = new ArrayList<TriggerEventDataParent>();
public ArrayList<TriggerConditionDataParent> list_condition = new ArrayList<TriggerConditionDataParent>();
public ArrayList<TriggerActionDataParent> list_action = new ArrayList<TriggerActionDataParent>();
public String fullName;
public float triggerStructIndex;
@Override
public void listVoluation(ArrayList<Object> list)
{
if (list == null || list.size() <= 0)
{
return;
}
for (Object obj : list)
{
addTriggerData((TriggerDataParent) obj);
}
}
private void addTriggerData(TriggerDataParent data)
{
if (data instanceof TriggerEventDataParent)
{
TriggerEventDataParent de = (TriggerEventDataParent) data;
de.triggerIndex = list_event.size();
de.triggerStructIndex = triggerStructIndex;
list_event.add(de);
}
else if (data instanceof TriggerConditionDataParent)
{
TriggerConditionDataParent dc = (TriggerConditionDataParent) data;
list_condition.add(dc);
}
else if (data instanceof TriggerActionDataParent)
{
TriggerActionDataParent da = (TriggerActionDataParent) data;
list_action.add(da);
}
}
/**
* 接受处理事件的结果
*
* @param index
* @param res
*/
public boolean receiveEventResult(int userId, int index, boolean res)
{
if (res)
{
return judgeConditionDataParocessing(userId);
}
return false;
}
/**
* 判断环境数据的处理结果
* @param userId
* @return
*/
public boolean judgeConditionDataParocessing(int userId)
{
if (list_condition != null && list_condition.size() > 0)
{
for (TriggerConditionDataParent con : list_condition)
{
boolean res = con.DataProcessing(userId);
if (!res)
{
Tool.print_debug_level0("条件不满足不执行动作。对应的原始数据id=" + con.origId);
return false;
}
}
}
return actionDataProcessing(userId);
}
/**
* 执行动作
* @param userId
* @return
*/
public boolean actionDataProcessing(int userId)
{
if (list_action != null && list_action.size() > 0)
{
for (TriggerActionDataParent data : list_action)
{
boolean res = data.DataProcessing(userId);
Tool.print_debug_level0("执行动作后的反馈。res=" + res + ",ActionData origId=" + data.origId);
}
}
return true;
}
}
ExportData类中包含整个工程中所有的ExportTriggerDataStruct,我们从json数据中读取的最后会得到一个ExportData类,ExportData类继承了一个IListVoluation接口。listVoluation方法的作用见IListVoluation接口中的方法。代码如下:
@DataStructAnnotat
@Scope("prototype")
@Service
public class ExportData implements IListVoluation
{
public ArrayList<ExportTriggerDataStruct> listChuFaQi;
public String fullName;
@Override
public void listVoluation(ArrayList<Object> list)
{
if (list == null || list.size() <= 0)
{
return;
}
listChuFaQi = new ArrayList<ExportTriggerDataStruct>();
for (Object data : list)
{
if (data instanceof ExportTriggerDataStruct)
{
ExportTriggerDataStruct export = (ExportTriggerDataStruct) data;
listChuFaQi.add(export);
}
}
Tool.print_debug_level0("数据加载完成!!!");
}
}
public interface IListVoluation
{
/**
* 传入一个List<object> 类型 将其转化为list具体类型
* 若子类中有ArrayList或者其他的集合请务必实现该方法
* 否则会导致数据丢失
* @param list
*/
void listVoluation(ArrayList<Object> list);
}
由于在这个应用中我们遇到了类的继承目前为止小W并没有找到合适的此类的json数据解析,所以就自己写了一个json数据解析,小W会再写另一边文章介绍这类json的解析,有兴趣的可以看一下。
2、触发器数据结构的介绍
触发器数据用一个共同的父类TriggerDataParent这个类是一个抽象的于上述的编辑器的TriggerDataParent是一样的,只是方法有所区别,详细的见项目。
事件:TriggerEventDataParent继承父类TriggerDataParent,其中有一个数据处理类用于处理该事件的中传过来的数据,该数据具体怎样处理有开发者自己所需决定。listVoluation方法的作用见IListVoluation接口中的方法。它的代码如下:
public abstract class TriggerEventDataParent extends TriggerDataParent
{
/// <summary>
/// 数据在所在的触发器结构中的唯一次序
/// 该数值在程序启动后自动生成
/// 不需要额外维护
/// </summary>
public int triggerIndex;
/// <summary>
/// 该数据所在触发器结构自己的顺序
/// 该数据在游戏启动时自动赋值
/// 无需额外维护
/// </summary>
public float triggerStructIndex;
@Override
public void listVoluation(ArrayList<Object> list)
{
}
/**
* 每个事件子类均需要实现该方法
*
* @param origId
* 原始数据对应的唯一id
* @param obj
* 需要的参数,需要转化为自己需要的类型
* @return
*/
public abstract boolean dataProcessing(float origId, Object... obj);
}
环境:TriggerConditionDataParent有一个数据处理的方法用于处理该环境中的数据。代码如下:
public abstract class TriggerConditionDataParent extends TriggerDataParent
{
/**
* 实现条件类,所有条件子类均需实现该抽象方法
*
* @return
*/
public abstract boolean dataProcessing(int userId);
}
动作:TriggerActionDataParent有一个数据处理的方法用于处理该环境中的数据。代码如下:
public abstract class TriggerActionDataParent extends TriggerDataParent
{
/**
* 实现动作类,所有动作子类均需实现该抽象方法
*
* @return
*/
public abstract boolean DataProcessing(int userId);
}
3、游戏运行时数据处理
运行时需要用的是关于触发器的类,而关于原始数据的类作为一个枚举值或者常量作为原始数据。
GameRunTimeProcessing中包含一个工程中的数据,这其中有一个获取到事件数据的方法receiveEventTrigger,代码如下:
/**
* 游戏数据处理
*
* @author Will
*
*/
public class GameRunTimeProcessing {
/**
* 所有触发器结构 key:triggerStructIndex
*/
private HashMap<Float, ExportTriggerDataStruct> map_allTriggerStructs = new HashMap<Float, ExportTriggerDataStruct>();
/**
* 所有的事件数据 key:origId
*/
private HashMap<Float, ArrayList<TriggerEventDataParent>> map_allEventDtas = new HashMap<Float, ArrayList<TriggerEventDataParent>>();
public GameRunTimeProcessing() {
}
public GameRunTimeProcessing(Object obj) {
if (obj instanceof ExportData) {
ExportData data = (ExportData) obj;
if (data.listChuFaQi != null && data.listChuFaQi.size() > 0) {
for (ExportTriggerDataStruct export : data.listChuFaQi) {
map_allTriggerStructs.put(export.triggerStructIndex, export);
addAllEventData(export.list_event, export.triggerStructIndex);
}
}
}
}
private void addAllEventData(ArrayList<TriggerEventDataParent> list, float triggerStructIndex) {
if (list == null || list.size() <= 0) {
return;
}
for (TriggerEventDataParent trigger : list) {
trigger.triggerStructIndex = triggerStructIndex;
if (map_allEventDtas.containsKey(trigger.origId)) {
map_allEventDtas.get(trigger.origId).add(trigger);
} else {
ArrayList<TriggerEventDataParent> trigger_list = new ArrayList<TriggerEventDataParent>();
trigger_list.add(trigger);
map_allEventDtas.put(trigger.origId, trigger_list);
}
}
}
/**
* 获取事件触发器
* @param userId 玩家id
* @param origId 原始数据id
* @param objs 事件触发器处理数据所需的参数,它是一个数组
* @return
*/
public boolean receiveEventTrigger(int userId, float origId, Object... objs) {
Tool.print_debug_level0("接受到事件触发器。origId" + origId + ",map_allEventDtas.size()=" + map_allEventDtas.size());
if (map_allEventDtas.containsKey(origId)) {
Tool.print_debug_level0("map_allEventDtas.get(origId).size()=" + map_allEventDtas.get(origId).size());
if (map_allEventDtas.get(origId).size() > 0) {
for (TriggerEventDataParent data : map_allEventDtas.get(origId)) {
boolean res = data.DataProcessing(origId, objs);
ExportTriggerDataStruct trigger_st = map_allTriggerStructs.get(data.triggerStructIndex);
boolean returnRes = trigger_st.receiveEventResult(userId, data.triggerIndex, res);
Tool.print_debug_level0("事件发生之后处理数据的结果=" + returnRes);
return returnRes;
}
} else {
return false;
}
}
return false;
}
}
三、一个完整的实例
1、玩家GM命令为玩家添加装备
描述:在聊天的输入框输入指定的字符串获取装备。
a、原始数据结构
原始数据事件,代码如下:
//命名空间固定为DataStruct
namespace DataStruct
{
/// <summary>
/// 原始事件数据需继承原始数据事件类OrigEventDataParent
/// </summary>
public class OrigEventPlayerGMStr : OrigEventDataParent
{
private string GM_str;//玩家GM命令起始字符串
public OrigEventPlayerGMStr() : base("玩家GM命令事件(指定起始字符串)", (int)OrignalEventDataEnum.playerGM_str)
{
descrip = "通过聊天窗口添加命令,比如(添加装备):add ";
type = (int)OrigEventTypeEnum.玩家;
}
/// <summary>
/// 保存触发器数据
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public override TriggerDataParent Save(params object[] obj)
{
TriggerEventPlayerGMStr data = DataHandleManage.editorHandle.CreatNewTriggerDataClass<TriggerEventPlayerGMStr>(id);
data.SetData(GM_str);
return data;
}
/// <summary>
/// 再panel中显示的数据,下面的图片中将会给出这个方法的用处
/// </summary>
/// <returns></returns>
public override List<Control> Show()
{
List<Control> list = new List<Control>();
Label label = DataHandleManage.orignalHandle.creatLabel(name + "请输入GM命令起始字符(请尽量不要与其它已用字符重复):");
list.Add(label);
TextBox textBox2 = DataHandleManage.orignalHandle.creatTextBox();
textBox2.TextChanged += (object sender, EventArgs e) =>
{
GM_str = textBox2.Text;
};
list.Add(textBox2);
return list;
}
}
}
运行图片如下:
注意上述图片中的内容是如何显示的按钮是如何调用save方法的都不需要开发者去处理,内部已经处理好了。在此玩家GM命令中不需要环境。
原始数据动作,代码如下:
//指定命名空间DataStruct
namespace DataStruct
{
//原始数据动作继承动作的原始数据父类,此类已经在前面介绍过OrigActionDataParent
public class OrigActionPlayerChatCommand : OrigActionDataParent
{
private int player_GM;//玩家GM命令字符串
private Button currentButton;//当前选中的button
public OrigActionPlayerChatCommand() : base("玩家聊天命令", (int)OrignalActionDataEnum.playerChatCommand)
{
descrip = "给玩家添加装备。";
type = (int)OrigActionTypeEnum.玩家;
}
/// <summary>
/// 保存触发器数据
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public override TriggerDataParent Save(params object[] obj)
{
TriggerActionPlayerChatCommand data = DataHandleManage.editorHandle.CreatNewTriggerDataClass<TriggerActionPlayerChatCommand>(id);
data.SetData(player_GM);
return data;
}
/// <summary>
/// 再panel中显示的数据,下面的图片中将会给出这个方法的用处
/// </summary>
/// <returns></returns>
public override List<Control> Show()
{
List<Control> list = new List<Control>();
//这里已经提供创建Label的方法,使用Label时使用该方法
Label label = DataHandleManage.orignalHandle.creatLabel(name + ",点击可选择一个聊天命令类型。");
list.Add(label);
//这里已经提供创建Button的方法,使用Button时使用该方法
Button button = DataHandleManage.orignalHandle.creatButton("点击选择");
button.MouseClick += ButtonClick;
list.Add(button);
return list;
}
//点击Button的事件
private void ButtonClick(object sender, MouseEventArgs e)
{
currentButton = (Button)sender;
FuncDelegate func = new FuncDelegate(selectUIType);
DataHandleManage.openTypeSelectForm(AllDataManage.allEnumClass.dicEnumParent[(int)EnumType.PlayerGM], func);
}
private void selectUIType(params object[] uiType)
{
EnumItem item = (EnumItem)uiType[0];
this.player_GM = item.value;
currentButton.Text = item.name + "--点击选择";
}
}
}
运行图片如下:
b、触发器代码结构
触发器数据事件,代码如下:
//使用指定命名空间DataStruct
namespace DataStruct
{
//该事件触发器需继承触发器事件类 TriggerEventDataParent
public class TriggerEventPlayerGMStr : TriggerEventDataParent
{
public string GM_str;
public void SetData(string GM_str)
{
this.GM_str = GM_str;
}
//描述该触发器内容,若有该触发器自己的自定义的变量则需要重写该方法用于展示该条触发器信息
public override string Descript()
{
string des = "";
OrigEventDataParent orig = AllDataManage.origData.dicEventData[(int)origId];
//string name = AllDataManage.allEnumClass.dicEnumParent[(int)EnumType.PlayerGM].dicEnums[(int)player_GM].name;
des = orig.name + "(自定义的起始命令:" + this.GM_str + ")";
return des;
}
}
}
触发器数据动作,代码如下:
//使用指定的命名空间DataStruct
namespace DataStruct
{
//该动作触发器需继承触发器动作类TriggerActionDataParent
public class TriggerActionPlayerChatCommand : TriggerActionDataParent
{
public float player_GM;
public void SetData(int player_GM)
{
this.player_GM = player_GM;
}
//描述该触发器内容,若有该触发器自己的自定义的变量则需要重写该方法用于展示该条触发器信息
public override string Descript()
{
string des = "";
OrigActionDataParent orig = AllDataManage.origData.dicActionData[(int)origId];
string name = AllDataManage.allEnumClass.dicEnumParent[(int)EnumType.PlayerGM].dicEnums[(int)player_GM].name; ;
des = orig.name + "(" + name + ")";
return des;
}
}
}
运行图片如下:
转载自https://blog.csdn.net/coderTC/article/details/73864097理解GloVe模型概述模型目标:进行词的向量化表示,使得向量之间尽可能多地蕴含语义和语法的信息。输入:语料库输出:词向量方法概述:首先基于语料库构建词的共现矩阵,然后基于共现矩阵和GloVe模型学习词向量。开始统计共现矩阵训练词向量结束统计共现矩阵设共现矩阵为...
CSDN&amp;《程序员》F2F俱乐部周六在柏彦大厦又举办了一次活动,这次是以“性能测试”为主题,邀请我为主持人,因为和几个嘉宾虽然网上见面很多,却一直未曾谋面,为能一睹诸专家“芳容”,我也爽快地答应了。活动举办完回来,我就给李宁“吹嘘”这次活动多么有收获,与专家交流又获得了哪些知识等,使得他也蠢蠢欲动。现场满席,且有很多朋友站着听讲,这也让几位专家和我兴奋异常。为什么一次有关“性能测试”的活动...
题目概述给定一个带头结点的单链表和一个整数K,要求你将链表中的每K个结点做一次逆转。例如给定单链表 1→2→3→4→5→6 和 K=3,你需要将链表改造成 3→2→1→6→5→4;如果 K=4,则应该得到 4→3→2→1→5→6解题思路...
python+sklearn进行交叉验证(使用交叉验证对数据划分,模型评估和参数估计,使用决策树举例)
本文实例讲述了python实现的购物车功能。分享给大家供大家参考,具体如下:这里尝试用python实现简单的购物车程序。。。基本要求:用户输入工资,然后打印购物菜单用户可以不断的购买商品,直到余额不够为止退出时打印用户已购买的商品和剩余金额。。。代码:#!/usr/env python#coding:utf-8import re,mathdef get_customer_salary():whil...
正式开始学习编程,希望可以记录下来自己学习的过程每天学习两到三个小时,每周更三到四篇博客希望可以有所提升,小伙伴们可以互相监督呀
特征工程01 特征归一化问题 为什么需要对数值类型的特征做归一化?对特征进行归一化处理,使各指标处于同一数值量级,使得不同指标之间具有可比性。将所有的特征都统一到一个大致相同的数值区间内。主要有一下两种。(1) 线性函数归一化(Min-Max Scaling)。它对原始数据进行线性变换,使结果映射到[0,1]的范围,实现对原始数据的等比缩放。02 类别型特征问题 在对数据进行预处理时,应该怎样处理类别型特征?序列编号 Ordinal Encoding独热编码 One-hot En
qbo_arduqbobo_arduqbo
通过Carte服务对kettle转换进行稳定性测试,刚开始时是20并发,持续压力测试到20天时出现崩溃,由于崩溃的时间点和引起崩溃原因一时难以定位,重新改变压力测试的策略(测试前开发人员先做些优化,先解除和排除日志中出现的一些异常错误),然后进行100并发持续压力测试(加大并发数可以实现空间换时间,以尽快定位影响稳定性问题的原因),同时开启jvm监控,开启所有服务和数据库监控。测试脚本日夜不间断跑测,直到出现问题,通过监控和系统日志进行综合分析,找出问题。
CocosCreator在1.8版本开始,就支持一键发布微信小程序,下面是详细的发布步骤:1、在微信公众平台下载微信开发者工具; 地址:https://mp.weixin.qq.com/debug/wxagame/dev/devtools/download.html?t=2018115,根据需要选择相应的版本。 2、打开cocoscreator,选择Cocos Creator...
过山车Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 18731 Accepted Submission(s): 8172Problem DescriptionRPG girls今天和大家一起去游乐场玩,终于可
案例1:计算0-100的偶数和(3种循环结构)public static void main(String[] args) { // 业务:(循环) // 1.最大100,最小0,决定了循环的变量和条件 // 2.判断是否是偶数(if判断) // 3.把偶数都加起来存到变量sum中 // 4.输出0-100的偶数和 // 循环: // 1.用三种循环写 // 2.循环条件:i <= 100 // 循环变量:int i = 0; // .